summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-11-02 14:01:58 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2021-11-08 10:53:59 +0100
commitb67abc51ba6f78be79f344dfda9c6d0753d79aea (patch)
tree974a155489e69c0a9a5c9f3ee209ca5bec2d3c99 /src
parentdad3338f1f76a4a5bd782bae9c6b48941dfb1e31 (diff)
src: raw payload match and mangle on inner header / payload data
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>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c3
-rw-r--r--src/netlink_linearize.c5
-rw-r--r--src/parser_bison.y2
-rw-r--r--src/proto.c2
-rw-r--r--src/scanner.l1
5 files changed, 11 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 6a8c396f..a268b3cb 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -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;
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 454b9ba3..111102fd 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -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);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 65fd35a3..eb89a589 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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
diff --git a/src/proto.c b/src/proto.c
index 2b61e0ba..fe58c83a 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -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 =
diff --git a/src/scanner.l b/src/scanner.l
index 6cc7778d..5d263f9d 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -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; }