From patchwork Tue Sep 9 16:01:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alvaro Neira X-Patchwork-Id: 387388 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D3DA3140188 for ; Wed, 10 Sep 2014 02:01:29 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757202AbaIIQB2 (ORCPT ); Tue, 9 Sep 2014 12:01:28 -0400 Received: from mail-we0-f181.google.com ([74.125.82.181]:49157 "EHLO mail-we0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753914AbaIIQB0 (ORCPT ); Tue, 9 Sep 2014 12:01:26 -0400 Received: by mail-we0-f181.google.com with SMTP id w62so913250wes.26 for ; Tue, 09 Sep 2014 09:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=iOZpRNemfb38fh++m/nYnn0ciDkGYqU2nVh7JMZ2HPk=; b=vYeXSIbrpqqlw46OOJ4SNoY29rtukq1NFQOBAs3e2gjDfsmjvH/4LUL8Ced1q9YaDE n1VJrkDwLKuxCx9bD97e483uSzk0VjuVotos+7EvmIEH+XyRagslqnqBva/F925QDRJ1 1PGbR9+fHIcGLNyxoyyhj6jwpHjvFgowjmXYCUX7aGK2M/8mUWaGDbcGqKoxmzkfmFtN A89iqTPyJpLt9Q4pXhJX/6vMNDed6syycpSFDYWnALqJa9el3bb9nkvarN+zokXLlkw5 lUPZoZ6I0T5qjCi9cGH8f+iAThnsiGnHNl6ujfiYroFGmd+x8KXeSYZQPfa/s9mj+K+q m1Zw== X-Received: by 10.194.179.73 with SMTP id de9mr43875420wjc.87.1410278485280; Tue, 09 Sep 2014 09:01:25 -0700 (PDT) Received: from localhost.localdomain ([77.231.225.2]) by mx.google.com with ESMTPSA id wr10sm15396706wjc.10.2014.09.09.09.01.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Sep 2014 09:01:24 -0700 (PDT) From: Alvaro Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: kaber@trash.net Subject: [nft PATCH] src: add specific byteorder to the struct proto_hdr_template Date: Tue, 9 Sep 2014 18:01:19 +0200 Message-Id: <1410278479-25864-1-git-send-email-alvaroneay@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org If we try to add a rule like: nft add rule filter input udp length {55-9999} nft shows: BUG: invalid byte order conversion 0 => 2 nft: src/evaluate.c:153: byteorder_conversion_op: Assertion `0' failed. Some of the existing payload fields rely on BYTEORDER_INVALID. Therefore, if we try to convert it in evaluation step, we hit this bug. This patch allows to add a specific byteorder to the struct proto_hdr_template. If we create a expression with a invalid byteorder, we will use the byteorder added to the proto_hdr_template structure. Signed-off-by: Alvaro Neira Ayuso --- [Tested with the rules] * nft add rule ip filter input ip length 10-55 counter * nft add rule ip filter input ip length 55-1000 counter * nft add rule ip filter input udp length {0-100} udp dport 9999 counter * nft add rule ip filter input udp length {100-9999} udp dport 9999 counter * Tested with Ana Rey's tests. include/proto.h | 5 ++++- src/exthdr.c | 6 +++++- src/payload.c | 2 +- src/proto.c | 6 ++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/proto.h b/include/proto.h index bd3701e..cc1f51f 100644 --- a/include/proto.h +++ b/include/proto.h @@ -2,6 +2,7 @@ #define NFTABLES_PROTO_H #include +#include #include /** @@ -38,13 +39,15 @@ struct proto_hdr_template { const struct datatype *dtype; uint16_t offset; uint16_t len; + enum byteorder byteorder; enum nft_meta_keys meta_key; }; -#define PROTO_HDR_TEMPLATE(__token, __dtype, __offset, __len) \ +#define PROTO_HDR_TEMPLATE(__token, __dtype, __byteorder, __offset, __len)\ { \ .token = (__token), \ .dtype = (__dtype), \ + .byteorder = (__byteorder), \ .offset = (__offset), \ .len = (__len), \ } diff --git a/src/exthdr.c b/src/exthdr.c index a619ecc..9ed0b6a 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -48,7 +48,7 @@ static const struct expr_ops exthdr_expr_ops = { }; static const struct proto_hdr_template exthdr_unknown_template = - PROTO_HDR_TEMPLATE("unknown", &invalid_type, 0, 0); + PROTO_HDR_TEMPLATE("unknown", &invalid_type, BYTEORDER_INVALID, 0, 0); struct expr *exthdr_expr_alloc(const struct location *loc, const struct exthdr_desc *desc, @@ -102,6 +102,7 @@ void exthdr_init_raw(struct expr *expr, uint8_t type, #define HDR_TEMPLATE(__name, __dtype, __type, __member) \ PROTO_HDR_TEMPLATE(__name, __dtype, \ + BYTEORDER_BIG_ENDIAN, \ offsetof(__type, __member) * 8, \ field_sizeof(__type, __member) * 8) @@ -179,10 +180,13 @@ const struct exthdr_desc exthdr_frag = { [FRAGHDR_NEXTHDR] = FRAG_FIELD("nexthdr", ip6f_nxt, &inet_protocol_type), [FRAGHDR_RESERVED] = FRAG_FIELD("reserved", ip6f_reserved, &integer_type), [FRAGHDR_FRAG_OFF] = PROTO_HDR_TEMPLATE("frag-off", &integer_type, + BYTEORDER_BIG_ENDIAN, 16, 13), [FRAGHDR_RESERVED2] = PROTO_HDR_TEMPLATE("reserved2", &integer_type, + BYTEORDER_BIG_ENDIAN, 29, 2), [FRAGHDR_MFRAGS] = PROTO_HDR_TEMPLATE("more-fragments", &integer_type, + BYTEORDER_BIG_ENDIAN, 31, 1), [FRAGHDR_ID] = FRAG_FIELD("id", ip6f_ident, &integer_type), }, diff --git a/src/payload.c b/src/payload.c index 7297520..a3bbe51 100644 --- a/src/payload.c +++ b/src/payload.c @@ -117,7 +117,7 @@ struct expr *payload_expr_alloc(const struct location *loc, } expr = expr_alloc(loc, &payload_expr_ops, tmpl->dtype, - tmpl->dtype->byteorder, tmpl->len); + tmpl->byteorder, tmpl->len); expr->flags |= flags; expr->payload.desc = desc; diff --git a/src/proto.c b/src/proto.c index 15a456a..4f22d40 100644 --- a/src/proto.c +++ b/src/proto.c @@ -38,7 +38,7 @@ const char *proto_base_tokens[] = { }; const struct proto_hdr_template proto_unknown_template = - PROTO_HDR_TEMPLATE("unknown", &invalid_type, 0, 0); + PROTO_HDR_TEMPLATE("unknown", &invalid_type, BYTEORDER_INVALID, 0, 0); const struct proto_desc proto_unknown = { .name = "unknown", @@ -186,13 +186,15 @@ void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base, #define HDR_TEMPLATE(__name, __dtype, __type, __member) \ PROTO_HDR_TEMPLATE(__name, __dtype, \ + BYTEORDER_BIG_ENDIAN, \ offsetof(__type, __member) * 8, \ field_sizeof(__type, __member) * 8) #define HDR_FIELD(__name, __struct, __member) \ HDR_TEMPLATE(__name, &integer_type, __struct, __member) #define HDR_BITFIELD(__name, __dtype, __offset, __len) \ - PROTO_HDR_TEMPLATE(__name, __dtype, __offset, __len) + PROTO_HDR_TEMPLATE(__name, __dtype, BYTEORDER_BIG_ENDIAN, \ + __offset, __len) #define HDR_TYPE(__name, __dtype, __struct, __member) \ HDR_TEMPLATE(__name, __dtype, __struct, __member)