]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: raw payload match and mangle on inner header / payload data
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 2 Nov 2021 13:01:58 +0000 (14:01 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Nov 2021 09:53:59 +0000 (10:53 +0100)
This patch adds support to match on inner header / payload data:

 # nft add rule x y @ih,32,32 0x14000000 counter

you can also mangle payload data:

 # nft add rule x y @ih,32,32 set 0x14000000 counter

This update triggers a checksum update at the layer 4 header via
csum_flags, mangling odd bytes is also aligned to 16-bits.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/proto.h
src/evaluate.c
src/netlink_linearize.c
src/parser_bison.y
src/proto.c
src/scanner.l

index 580e409028bc652b89e6b6a2275c343e041fcd86..a04240a5de81db6442590b21aa1ef18e0e0f9917 100644 (file)
@@ -18,6 +18,7 @@ enum proto_bases {
        PROTO_BASE_LL_HDR,
        PROTO_BASE_NETWORK_HDR,
        PROTO_BASE_TRANSPORT_HDR,
+       PROTO_BASE_INNER_HDR,
        __PROTO_BASE_MAX
 };
 #define PROTO_BASE_MAX         (__PROTO_BASE_MAX - 1)
index 6a8c396f33c481c5b9dc8cbb2fc38885454ea337..a268b3cb9ee2d177d2817ad7014ab7c1c014ddc9 100644 (file)
@@ -2446,6 +2446,9 @@ static bool stmt_evaluate_payload_need_csum(const struct expr *payload)
 {
        const struct proto_desc *desc;
 
+       if (payload->payload.base == PROTO_BASE_INNER_HDR)
+               return true;
+
        desc = payload->payload.desc;
 
        return desc && desc->checksum_key;
index 454b9ba3fbc7282db8df5a99469cefa52dfda845..111102fd43346095f86ed3c890ed7a5b8662126c 100644 (file)
@@ -1028,8 +1028,9 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
                nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET,
                                   csum_off / BITS_PER_BYTE);
        }
-       if (expr->payload.base == PROTO_BASE_NETWORK_HDR && desc &&
-           payload_needs_l4csum_update_pseudohdr(expr, desc))
+       if ((expr->payload.base == PROTO_BASE_NETWORK_HDR && desc &&
+            payload_needs_l4csum_update_pseudohdr(expr, desc)) ||
+           expr->payload.base == PROTO_BASE_INNER_HDR)
                nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS,
                                   NFT_PAYLOAD_L4CSUM_PSEUDOHDR);
 
index 65fd35a36cde0ca42eb78f0ac06812817c8c5ba3..eb89a58989e2df8c7ae309ec5d9d5c5579edabae 100644 (file)
@@ -318,6 +318,7 @@ int nft_lex(void *, void *, void *);
 %token LL_HDR                  "ll"
 %token NETWORK_HDR             "nh"
 %token TRANSPORT_HDR           "th"
+%token INNER_HDR               "ih"
 
 %token BRIDGE                  "bridge"
 
@@ -5260,6 +5261,7 @@ payload_raw_expr  :       AT      payload_base_spec       COMMA   NUM     COMMA   NUM
 payload_base_spec      :       LL_HDR          { $$ = PROTO_BASE_LL_HDR; }
                        |       NETWORK_HDR     { $$ = PROTO_BASE_NETWORK_HDR; }
                        |       TRANSPORT_HDR   { $$ = PROTO_BASE_TRANSPORT_HDR; }
+                       |       INNER_HDR       { $$ = PROTO_BASE_INNER_HDR; }
                        ;
 
 eth_hdr_expr           :       ETHER   eth_hdr_field   close_scope_eth
index 2b61e0ba47fd936d547293c661bb920d3cb952ed..fe58c83a92955a23a148cbd8fa2f7db7bcb27b70 100644 (file)
@@ -28,6 +28,7 @@ const char *proto_base_names[] = {
        [PROTO_BASE_LL_HDR]             = "link layer",
        [PROTO_BASE_NETWORK_HDR]        = "network layer",
        [PROTO_BASE_TRANSPORT_HDR]      = "transport layer",
+       [PROTO_BASE_INNER_HDR]          = "payload data",
 };
 
 const char *proto_base_tokens[] = {
@@ -35,6 +36,7 @@ const char *proto_base_tokens[] = {
        [PROTO_BASE_LL_HDR]             = "ll",
        [PROTO_BASE_NETWORK_HDR]        = "nh",
        [PROTO_BASE_TRANSPORT_HDR]      = "th",
+       [PROTO_BASE_INNER_HDR]          = "ih",
 };
 
 const struct proto_hdr_template proto_unknown_template =
index 6cc7778dd85e1fc285558f238d082b60f5e7be32..5d263f9dc8b14ae59472cf09ac5d993b0107e460 100644 (file)
@@ -414,6 +414,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "ll"                   { return LL_HDR; }
 "nh"                   { return NETWORK_HDR; }
 "th"                   { return TRANSPORT_HDR; }
+"ih"                   { return INNER_HDR; }
 
 "bridge"               { return BRIDGE; }