summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2022-09-12 10:58:46 +0200
committerFlorian Westphal <fw@strlen.de>2022-09-13 14:14:40 +0200
commit8acaccf69c22fb195a0b88e28489792304728245 (patch)
tree1d3ae3e461b43c74d97635fef9336fbd4bf386d1 /iptables
parentb4fd0f682b53609c747e6dd69cc5024545d4b90c (diff)
nft: prefer payload to ttl/hl module
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index a7f712b1..f31c1603 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -43,6 +43,8 @@
#include <linux/netfilter/xt_mark.h>
#include <linux/netfilter/xt_pkttype.h>
+#include <linux/netfilter_ipv6/ip6t_hl.h>
+
#include <libmnl/libmnl.h>
#include <libnftnl/gen.h>
#include <libnftnl/table.h>
@@ -1465,6 +1467,41 @@ static int add_nft_pkttype(struct nft_handle *h, struct nftnl_rule *r,
return 0;
}
+static int add_nft_hl(struct nft_handle *h, struct nftnl_rule *r,
+ struct xt_entry_match *m, uint8_t offset)
+{
+ struct ip6t_hl_info *info = (void *)m->data;
+ struct nftnl_expr *expr;
+ uint8_t reg;
+ uint8_t op;
+
+ switch (info->mode) {
+ case IP6T_HL_NE:
+ op = NFT_CMP_NEQ;
+ break;
+ case IP6T_HL_EQ:
+ op = NFT_CMP_EQ;
+ break;
+ case IP6T_HL_LT:
+ op = NFT_CMP_LT;
+ break;
+ case IP6T_HL_GT:
+ op = NFT_CMP_GT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ expr = gen_payload(h, NFT_PAYLOAD_NETWORK_HEADER, offset, 1, &reg);
+ if (!expr)
+ return -ENOMEM;
+
+ nftnl_rule_add_expr(r, expr);
+ add_cmp_u8(r, info->hop_limit, op, reg);
+
+ return 0;
+}
+
int add_match(struct nft_handle *h,
struct nftnl_rule *r, struct xt_entry_match *m)
{
@@ -1483,6 +1520,12 @@ int add_match(struct nft_handle *h,
return add_nft_mark(h, r, m);
else if (!strcmp(m->u.user.name, "pkttype"))
return add_nft_pkttype(h, r, m);
+ else if (!strcmp(m->u.user.name, "hl"))
+ return add_nft_hl(h, r, m,
+ offsetof(struct ip6_hdr, ip6_hlim));
+ else if (!strcmp(m->u.user.name, "ttl"))
+ return add_nft_hl(h, r, m,
+ offsetof(struct iphdr, ttl));
expr = nftnl_expr_alloc("match");
if (expr == NULL)