]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
exthdr: Add support for exthdr specific flags
authorPhil Sutter <phil@nwl.cc>
Fri, 10 Mar 2017 17:13:50 +0000 (18:13 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 10 Mar 2017 18:01:21 +0000 (19:01 +0100)
This allows to have custom flags in exthdr expression, which is
necessary for upcoming existence checks (of both IPv6 extension headers
as well as TCP options).

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/expression.h
include/exthdr.h
include/tcpopt.h
src/exthdr.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/tcpopt.c

index 4f2948cc002be767a4fcdb40addecc94ae837c20..423eae7128f5c82ee30e63338bc6ebfef50467bd 100644 (file)
@@ -282,6 +282,7 @@ struct expr {
                        const struct proto_hdr_template *tmpl;
                        unsigned int                    offset;
                        enum nft_exthdr_op              op;
+                       unsigned int                    flags;
                } exthdr;
                struct {
                        /* EXPR_META */
index cdcc2b9537972e0859b7aaebde86d0d7cde4af71..c7f806ebb2fa299ba8cdeae1e3dc19ab11ae98f6 100644 (file)
@@ -23,7 +23,7 @@ extern struct expr *exthdr_expr_alloc(const struct location *loc,
 
 extern void exthdr_init_raw(struct expr *expr, uint8_t type,
                            unsigned int offset, unsigned int len,
-                           enum nft_exthdr_op op);
+                           enum nft_exthdr_op op, uint32_t flags);
 
 extern bool exthdr_find_template(struct expr *expr, const struct expr *mask,
                                 unsigned int *shift);
index f43a7eb703fedd1191a9df4a3aa4dbac43ab4059..412d02e7ba80fea0326f9601f2a7aae4eb4deea2 100644 (file)
@@ -8,7 +8,8 @@ extern struct expr *tcpopt_expr_alloc(const struct location *loc,
                                      uint8_t type, uint8_t field);
 
 extern void tcpopt_init_raw(struct expr *expr, uint8_t type,
-                           unsigned int offset, unsigned int len);
+                           unsigned int offset, unsigned int len,
+                           uint32_t flags);
 
 extern bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
                                 unsigned int *shift);
index ddda1b870310f6253f9e47feb9724c8586f0fc51..21fe734f8fc153e850225c876397f435ba9f0543 100644 (file)
@@ -46,7 +46,8 @@ static bool exthdr_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
        return e1->exthdr.desc == e2->exthdr.desc &&
               e1->exthdr.tmpl == e2->exthdr.tmpl &&
-              e1->exthdr.op == e2->exthdr.op;
+              e1->exthdr.op == e2->exthdr.op &&
+              e1->exthdr.flags == e2->exthdr.flags;
 }
 
 static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
@@ -55,6 +56,7 @@ static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
        new->exthdr.tmpl = expr->exthdr.tmpl;
        new->exthdr.offset = expr->exthdr.offset;
        new->exthdr.op = expr->exthdr.op;
+       new->exthdr.flags = expr->exthdr.flags;
 }
 
 const struct expr_ops exthdr_expr_ops = {
@@ -97,16 +99,17 @@ static const struct exthdr_desc *exthdr_protocols[IPPROTO_MAX] = {
 
 void exthdr_init_raw(struct expr *expr, uint8_t type,
                     unsigned int offset, unsigned int len,
-                    enum nft_exthdr_op op)
+                    enum nft_exthdr_op op, uint32_t flags)
 {
        const struct proto_hdr_template *tmpl;
        unsigned int i;
 
        assert(expr->ops->type == EXPR_EXTHDR);
        if (op == NFT_EXTHDR_OP_TCPOPT)
-               return tcpopt_init_raw(expr, type, offset, len);
+               return tcpopt_init_raw(expr, type, offset, len, flags);
 
        expr->len = len;
+       expr->exthdr.flags = flags;
        expr->exthdr.offset = offset;
        expr->exthdr.desc = exthdr_protocols[type];
        assert(expr->exthdr.desc != NULL);
@@ -149,7 +152,7 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i
        off += round_up(mask->len, BITS_PER_BYTE) - mask_len;
 
        exthdr_init_raw(expr, expr->exthdr.desc->type,
-                       off, mask_len - mask_offset, NFT_EXTHDR_OP_IPV6);
+                       off, mask_len - mask_offset, NFT_EXTHDR_OP_IPV6, 0);
 
        /* still failed to find a template... Bug. */
        if (expr->exthdr.tmpl == &exthdr_unknown_template)
index 36e8fe3c4337b247bd98699dd255e0d30362094e..9ad1e2c681c6424eac1141040b5e467d06abde61 100644 (file)
@@ -498,9 +498,9 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx,
                                 const struct location *loc,
                                 const struct nftnl_expr *nle)
 {
+       uint32_t offset, len, flags;
        enum nft_registers dreg;
        enum nft_exthdr_op op;
-       uint32_t offset, len;
        uint8_t type;
        struct expr *expr;
 
@@ -508,9 +508,10 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx,
        offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_OFFSET) * BITS_PER_BYTE;
        len    = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_LEN) * BITS_PER_BYTE;
        op     = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_OP);
+       flags  = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_FLAGS);
 
        expr = exthdr_expr_alloc(loc, NULL, 0);
-       exthdr_init_raw(expr, type, offset, len, op);
+       exthdr_init_raw(expr, type, offset, len, op, flags);
 
        dreg = netlink_parse_register(nle, NFTNL_EXPR_EXTHDR_DREG);
        netlink_set_register(ctx, dreg, expr);
index 293150e2d01556067c90e584a12d070e91e5db81..b2f27b7a35855aaac4c6f655574407cc5670b45c 100644 (file)
@@ -178,6 +178,7 @@ static void netlink_gen_exthdr(struct netlink_linearize_ctx *ctx,
        nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_LEN,
                           div_round_up(expr->len, BITS_PER_BYTE));
        nftnl_expr_set_u8(nle, NFTNL_EXPR_EXTHDR_OP, expr->exthdr.op);
+       nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_FLAGS, expr->exthdr.flags);
        nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
index f861214117a184ca029931e0d27b47375b4525ba..d34dfd459f4154a83c0b9a4854219e6c8be01cfb 100644 (file)
@@ -192,7 +192,7 @@ struct expr *tcpopt_expr_alloc(const struct location *loc, uint8_t type,
 }
 
 void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset,
-                    unsigned int len)
+                    unsigned int len, uint32_t flags)
 {
        const struct proto_hdr_template *tmpl;
        unsigned int i, off;
@@ -200,6 +200,7 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset,
        assert(expr->ops->type == EXPR_EXTHDR);
 
        expr->len = len;
+       expr->exthdr.flags = flags;
        expr->exthdr.offset = offset;
 
        assert(type < array_size(tcpopt_protocols));
@@ -229,7 +230,7 @@ bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
                return false;
 
        tcpopt_init_raw(expr, expr->exthdr.desc->type, expr->exthdr.offset,
-                       expr->len);
+                       expr->len, 0);
 
        if (expr->exthdr.tmpl == &tcpopt_unknown_template)
                return false;