diff options
Diffstat (limited to 'iptables/nft-ipv6.c')
-rw-r--r-- | iptables/nft-ipv6.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index 5489398a..d50b138e 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -20,6 +20,7 @@ #include <xtables.h> +#include <linux/netfilter/nf_tables.h> #include "nft.h" #include "nft-shared.h" @@ -27,26 +28,35 @@ static int nft_ipv6_add(struct nft_rule *r, void *data) { struct iptables_command_state *cs = data; struct xtables_rule_match *matchp; + uint32_t op; - if (cs->fw6.ipv6.iniface[0] != '\0') - add_iniface(r, cs->fw6.ipv6.iniface, cs->fw6.ipv6.invflags); + if (cs->fw6.ipv6.iniface[0] != '\0') { + op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_VIA_IN); + add_iniface(r, cs->fw6.ipv6.iniface, op); + } - if (cs->fw6.ipv6.outiface[0] != '\0') - add_outiface(r, cs->fw6.ipv6.outiface, cs->fw6.ipv6.invflags); + if (cs->fw6.ipv6.outiface[0] != '\0') { + op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_VIA_OUT); + add_outiface(r, cs->fw6.ipv6.outiface, op); + } - if (cs->fw6.ipv6.proto != 0) + if (cs->fw6.ipv6.proto != 0) { + op = nft_invflags2cmp(cs->fw6.ipv6.invflags, XT_INV_PROTO); add_proto(r, offsetof(struct ip6_hdr, ip6_nxt), 1, - cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags); + cs->fw6.ipv6.proto, op); + } if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src)) { + op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_SRCIP); add_addr(r, offsetof(struct ip6_hdr, ip6_src), &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk, - sizeof(struct in6_addr), cs->fw6.ipv6.invflags); + sizeof(struct in6_addr), op); } if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst)) { + op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_DSTIP); add_addr(r, offsetof(struct ip6_hdr, ip6_dst), &cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk, - sizeof(struct in6_addr), cs->fw6.ipv6.invflags); + sizeof(struct in6_addr), op); } add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags); @@ -116,10 +126,12 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct ip6_hdr, ip6_src): get_cmp_data(e, &addr, sizeof(addr), &inv); memcpy(cs->fw6.ipv6.src.s6_addr, &addr, sizeof(addr)); - if (ctx->flags & NFT_XT_CTX_BITWISE) - parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk); - else - memset(&cs->fw.ip.smsk, 0xff, sizeof(struct in6_addr)); + if (ctx->flags & NFT_XT_CTX_BITWISE) { + parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&cs->fw.ip.smsk, 0xff, sizeof(struct in6_addr)); + } if (inv) cs->fw6.ipv6.invflags |= IPT_INV_SRCIP; @@ -127,10 +139,12 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct ip6_hdr, ip6_dst): get_cmp_data(e, &addr, sizeof(addr), &inv); memcpy(cs->fw6.ipv6.dst.s6_addr, &addr, sizeof(addr)); - if (ctx->flags & NFT_XT_CTX_BITWISE) - parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk); - else - memset(&cs->fw.ip.dmsk, 0xff, sizeof(struct in6_addr)); + if (ctx->flags & NFT_XT_CTX_BITWISE) { + parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&cs->fw.ip.dmsk, 0xff, sizeof(struct in6_addr)); + } if (inv) cs->fw6.ipv6.invflags |= IPT_INV_DSTIP; |