]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add specific byteorder to the struct proto_hdr_template
authorAlvaro Neira Ayuso <alvaroneay@gmail.com>
Wed, 17 Sep 2014 07:20:28 +0000 (09:20 +0200)
committerPatrick McHardy <kaber@trash.net>
Wed, 17 Sep 2014 07:20:28 +0000 (09:20 +0200)
If we try to add a rule like:

nft add rule filter input udp length {55-9999}

nftable 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 <alvaroneay@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
include/proto.h
src/exthdr.c
src/payload.c
src/proto.c

index bd3701e31fed07a36bfc4a30b3567334a8350cc6..cc1f51f0bf5e963712b9510fd9d2ccdc97e21987 100644 (file)
@@ -2,6 +2,7 @@
 #define NFTABLES_PROTO_H
 
 #include <nftables.h>
+#include <datatype.h>
 #include <linux/netfilter/nf_tables.h>
 
 /**
@@ -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),                              \
        }
index a619eccea113c604e8b5f8517c5b957ee2b219fa..9ed0b6ac83ab650b47cb314da382d697df5d0ec2 100644 (file)
@@ -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),
        },
index 88baef207e2f1bcb597863431d0689a3215a23e7..1eee4e098052b9cb03d2d35fe6fa17527c506618 100644 (file)
@@ -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;
index 15a456a768bfb59b844ca5e3f1ba93f90917503c..6eb4bb24f3da3d8876799b758a27faf9e135c696 100644 (file)
@@ -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)
 
@@ -785,7 +787,10 @@ const struct datatype ethertype_type = {
 #define ETHHDR_TYPE(__name, __member) \
        ETHHDR_TEMPLATE(__name, &ethertype_type, __member)
 #define ETHHDR_ADDR(__name, __member) \
-       ETHHDR_TEMPLATE(__name, &etheraddr_type, __member)
+       PROTO_HDR_TEMPLATE(__name, &etheraddr_type,             \
+                          BYTEORDER_HOST_ENDIAN,               \
+                          offsetof(struct ether_header, __member) * 8, \
+                          field_sizeof(struct ether_header, __member) * 8)
 
 const struct proto_desc proto_eth = {
        .name           = "ether",