summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2022-01-25 17:53:01 +0100
committerFlorian Westphal <fw@strlen.de>2022-01-29 13:39:52 +0100
commit98e69b7e74dc3fc2d7bbd87f8c2cae9559b15df8 (patch)
tree30de71ad55f461b12d6e50acceb3379af1ecf9d4 /iptables/nft.c
parent92808bd52f04154e01a68c47c2834d2252adf60c (diff)
nft: add support for native tcp flag matching
prefer payload + bitwise + cmp to nft_compat match. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables/nft.c')
-rw-r--r--iptables/nft.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index 4b5c4332..3e434549 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1346,6 +1346,26 @@ static int add_nft_udp(struct nftnl_rule *r, struct xt_entry_match *m)
udp->dpts, udp->invflags & XT_UDP_INV_DSTPT);
}
+static int add_nft_tcpflags(struct nftnl_rule *r,
+ uint8_t cmp, uint8_t mask,
+ bool invert)
+{
+ struct nftnl_expr *e;
+
+ e = gen_payload(NFT_PAYLOAD_TRANSPORT_HEADER,
+ 13, 1, NFT_REG_1);
+
+ if (!e)
+ return -ENOMEM;
+
+ nftnl_rule_add_expr(r, e);
+
+ add_bitwise(r, &mask, 1);
+ add_cmp_u8(r, cmp, invert ? NFT_CMP_NEQ : NFT_CMP_EQ);
+
+ return 0;
+}
+
static bool tcp_all_zero(const struct xt_tcp *t)
{
static const struct xt_tcp zero = {
@@ -1358,11 +1378,10 @@ static bool tcp_all_zero(const struct xt_tcp *t)
static int add_nft_tcp(struct nftnl_rule *r, struct xt_entry_match *m)
{
- static const uint8_t supported = XT_TCP_INV_SRCPT | XT_TCP_INV_DSTPT;
+ static const uint8_t supported = XT_TCP_INV_SRCPT | XT_TCP_INV_DSTPT | XT_TCP_INV_FLAGS;
struct xt_tcp *tcp = (void *)m->data;
if (tcp->invflags & ~supported || tcp->option ||
- tcp->flg_mask || tcp->flg_cmp ||
tcp_all_zero(tcp)) {
struct nftnl_expr *expr = nftnl_expr_alloc("match");
int ret;
@@ -1372,6 +1391,14 @@ static int add_nft_tcp(struct nftnl_rule *r, struct xt_entry_match *m)
return ret;
}
+ if (tcp->flg_mask) {
+ int ret = add_nft_tcpflags(r, tcp->flg_cmp, tcp->flg_mask,
+ tcp->invflags & XT_TCP_INV_FLAGS);
+
+ if (ret < 0)
+ return ret;
+ }
+
return add_nft_tcpudp(r, tcp->spts, tcp->invflags & XT_TCP_INV_SRCPT,
tcp->dpts, tcp->invflags & XT_TCP_INV_DSTPT);
}