summaryrefslogtreecommitdiffstats
path: root/src/netlink_linearize.c
diff options
context:
space:
mode:
authorPablo Neira <pablo@netfilter.org>2016-11-24 12:12:33 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-12-04 21:24:48 +0100
commit1d398465831066c5e98fb2a58d7aa0547595de33 (patch)
tree3a0a11b66e7bd45d6d3a3bdab93205f09a156085 /src/netlink_linearize.c
parent8c01e1d6ec92720a7cd5c134a9fcea3953772e92 (diff)
src: trigger layer 4 checksum when pseudoheader fields are modified
This patch sets the NFT_PAYLOAD_L4CSUM_PSEUDOHDR when any of the pseudoheader fields are modified. This implicitly enables stateless NAT, that can be useful under some circuntances. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_linearize.c')
-rw-r--r--src/netlink_linearize.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 6bc0bee8..4a0001a4 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -761,6 +761,18 @@ static void netlink_gen_verdict_stmt(struct netlink_linearize_ctx *ctx,
return netlink_gen_expr(ctx, stmt->expr, NFT_REG_VERDICT);
}
+static bool payload_needs_l4csum_update_pseudohdr(const struct expr *expr,
+ const struct proto_desc *desc)
+{
+ int i;
+
+ for (i = 0; i < PROTO_HDRS_MAX; i++) {
+ if (payload_hdr_field(expr) == desc->pseudohdr[i])
+ return true;
+ }
+ return false;
+}
+
static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
const struct stmt *stmt)
{
@@ -794,6 +806,11 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
NFT_PAYLOAD_CSUM_INET);
nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET,
csum_off / BITS_PER_BYTE);
+
+ if (expr->payload.base == PROTO_BASE_NETWORK_HDR &&
+ payload_needs_l4csum_update_pseudohdr(expr, desc))
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS,
+ NFT_PAYLOAD_L4CSUM_PSEUDOHDR);
}
nftnl_rule_add_expr(ctx->nlr, nle);