Signed-off-by: Florian Westphal <fw@xxxxxxxxx> --- iptables/nft.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/iptables/nft.c b/iptables/nft.c index a7f712b1d580..f31c1603eb9e 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, ®); + 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) -- 2.37.3