[PATCH iptables-nft 5/7] nft: prefer native expressions instead of tcp match

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of using nft_compat+xtables tcp match, prefer to
emit payload+cmp or payload+range expression.

Unlike udp, tcp has flag bits that can be matched too but
we have to fall back to the xt expression for now.
We also don't support tcp option match, but thats a rarely
used feature anyway.

Delinearization support for ports was added in previous patches.

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 iptables/nft.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/iptables/nft.c b/iptables/nft.c
index 9f181de53678..4b5c4332c7c1 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1346,6 +1346,36 @@ static int add_nft_udp(struct nftnl_rule *r, struct xt_entry_match *m)
 			      udp->dpts, udp->invflags & XT_UDP_INV_DSTPT);
 }
 
+static bool tcp_all_zero(const struct xt_tcp *t)
+{
+	static const struct xt_tcp zero = {
+		.spts[1] = 0xffff,
+		.dpts[1] = 0xffff,
+	};
+
+	return memcmp(t, &zero, sizeof(*t)) == 0;
+}
+
+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;
+	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;
+
+		ret = __add_match(expr, m);
+		nftnl_rule_add_expr(r, expr);
+		return ret;
+	}
+
+	return add_nft_tcpudp(r, tcp->spts, tcp->invflags & XT_TCP_INV_SRCPT,
+			      tcp->dpts, tcp->invflags & XT_TCP_INV_DSTPT);
+}
+
 int add_match(struct nft_handle *h,
 	      struct nftnl_rule *r, struct xt_entry_match *m)
 {
@@ -1358,6 +1388,8 @@ int add_match(struct nft_handle *h,
 		return add_nft_among(h, r, m);
 	else if (!strcmp(m->u.user.name, "udp"))
 		return add_nft_udp(r, m);
+	else if (!strcmp(m->u.user.name, "tcp"))
+		return add_nft_tcp(r, m);
 
 	expr = nftnl_expr_alloc("match");
 	if (expr == NULL)
-- 
2.34.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux