diff options
author | Florian Westphal <fw@strlen.de> | 2022-09-12 10:58:44 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2022-09-13 14:14:38 +0200 |
commit | b4fd0f682b53609c747e6dd69cc5024545d4b90c (patch) | |
tree | 22ffb65b47917d61393b42d6171dbb96b0ae22ce /iptables/nft-shared.c | |
parent | 0da2d1a35bd70d37f72d594927c0649d1dea4f7c (diff) |
nft: support ttl/hoplimit dissection
xlate raw "nft ... ttl eq 1" and so on to the ttl/hl matches.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables/nft-shared.c')
-rw-r--r-- | iptables/nft-shared.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 79c93fe8..71e2f18d 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -27,6 +27,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/rule.h> #include <libnftnl/expr.h> @@ -1449,3 +1451,69 @@ void nft_check_xt_legacy(int family, bool is_ipt_save) prefix, prefix, is_ipt_save ? "-save" : ""); fclose(fp); } + +int nft_parse_hl(struct nft_xt_ctx *ctx, + struct nftnl_expr *e, + struct iptables_command_state *cs) +{ + struct xtables_match *match; + struct ip6t_hl_info *info; + uint8_t hl, mode; + int op; + + hl = nftnl_expr_get_u8(e, NFTNL_EXPR_CMP_DATA); + op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP); + + switch (op) { + case NFT_CMP_NEQ: + mode = IP6T_HL_NE; + break; + case NFT_CMP_EQ: + mode = IP6T_HL_EQ; + break; + case NFT_CMP_LT: + mode = IP6T_HL_LT; + break; + case NFT_CMP_GT: + mode = IP6T_HL_GT; + break; + case NFT_CMP_LTE: + mode = IP6T_HL_LT; + if (hl == 255) + return -1; + hl++; + break; + case NFT_CMP_GTE: + mode = IP6T_HL_GT; + if (hl == 0) + return -1; + hl--; + break; + default: + return -1; + } + + /* ipt_ttl_info and ip6t_hl_info have same layout, + * IPT_TTL_x and IP6T_HL_x are aliases as well, so + * just use HL for both ipv4 and ipv6. + */ + switch (ctx->h->family) { + case NFPROTO_IPV4: + match = nft_create_match(ctx, ctx->cs, "ttl"); + break; + case NFPROTO_IPV6: + match = nft_create_match(ctx, ctx->cs, "hl"); + break; + default: + return -1; + } + + if (!match) + return -1; + + info = (void*)match->m->data; + info->hop_limit = hl; + info->mode = mode; + + return 0; +} |