]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: add support to set meta keys
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 26 Dec 2013 19:23:07 +0000 (20:23 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 28 Dec 2013 22:08:20 +0000 (23:08 +0100)
Arturo Borrero added kernel support to set meta keys in
http://patchwork.ozlabs.org/patch/305281/ and the corresponding
library support in http://patchwork.ozlabs.org/patch/305283/.

This patch enhances nft to use this new kernel feature. The
following example shows how to set the packet mark.

% nft add rule ip filter input meta mark set 22
% nft list table filter
table ip filter {
        chain input {
                 type filter hook input priority 0;
                 meta mark set 0x00000016
        }
}

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/netlink_delinearize.c
src/netlink_linearize.c

index 7e4e38c49c35a08f2eeb5cdb45f012cef52222cf..d1d35f85bb938824ae57c05d523eff48cd988c60 100644 (file)
@@ -325,9 +325,9 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx,
                             expr);
 }
 
-static void netlink_parse_meta(struct netlink_parse_ctx *ctx,
-                              const struct location *loc,
-                              const struct nft_rule_expr *nle)
+static void netlink_parse_meta_dreg(struct netlink_parse_ctx *ctx,
+                                   const struct location *loc,
+                                   const struct nft_rule_expr *nle)
 {
        struct expr *expr;
 
@@ -338,6 +338,33 @@ static void netlink_parse_meta(struct netlink_parse_ctx *ctx,
                             expr);
 }
 
+static void netlink_parse_meta_sreg(struct netlink_parse_ctx *ctx,
+                                   const struct location *loc,
+                                   const struct nft_rule_expr *nle)
+{
+       struct stmt *stmt;
+       struct expr *expr;
+
+       expr = netlink_get_register(ctx, loc,
+                       nft_rule_expr_get_u8(nle, NFT_EXPR_META_SREG));
+       stmt = meta_stmt_alloc(loc,
+                              nft_rule_expr_get_u8(nle, NFT_EXPR_META_KEY),
+                              expr);
+       expr_set_type(expr, stmt->meta.tmpl->dtype, stmt->meta.tmpl->byteorder);
+
+       list_add_tail(&stmt->list, &ctx->rule->stmts);
+}
+
+static void netlink_parse_meta(struct netlink_parse_ctx *ctx,
+                              const struct location *loc,
+                              const struct nft_rule_expr *nle)
+{
+       if (nft_rule_expr_is_set(nle, NFT_EXPR_META_DREG))
+               netlink_parse_meta_dreg(ctx, loc, nle);
+       else
+               netlink_parse_meta_sreg(ctx, loc, nle);
+}
+
 static void netlink_parse_ct(struct netlink_parse_ctx *ctx,
                             const struct location *loc,
                             const struct nft_rule_expr *nle)
@@ -786,6 +813,10 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
                case STMT_EXPRESSION:
                        expr_postprocess(&rctx, stmt, &stmt->expr);
                        break;
+               case STMT_META:
+                       if (stmt->meta.expr != NULL)
+                               expr_postprocess(&rctx, stmt, &stmt->meta.expr);
+                       break;
                case STMT_NAT:
                        if (stmt->nat.addr != NULL)
                                expr_postprocess(&rctx, stmt, &stmt->nat.addr);
index e64e92a8bfd5a2fab932b1085c009d4a87ffdc20..0ac0218d290496694b8afd822c72f10e2fce3fe2 100644 (file)
@@ -518,6 +518,8 @@ static void netlink_gen_meta_stmt(struct netlink_linearize_ctx *ctx,
        release_register(ctx);
 
        nle = alloc_nft_expr("meta");
+       nft_rule_expr_set_u32(nle, NFT_EXPR_META_SREG, sreg);
+       nft_rule_expr_set_u32(nle, NFT_EXPR_META_KEY, stmt->meta.key);
        nft_rule_add_expr(ctx->nlr, nle);
 }