summaryrefslogtreecommitdiffstats
path: root/iptables/nft-ipv4.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-05-05 10:38:38 +0200
committerFlorian Westphal <fw@strlen.de>2018-05-05 20:02:59 +0200
commitde874054ec26a78ce83ccf13c449a4d3c4a5778e (patch)
treeb1ebd85faa9429715f995a1abcc383d4f6ed3154 /iptables/nft-ipv4.c
parentc7b2fd6f8ee50c0f3be02102fe47b50c65e9e57a (diff)
xtables-compat: fix ipv4 frag (-f)
iptables-translate -A I -f nft add rule ip filter I ip frag-off != 0 counter iptables however checks: frag_off = ntohs(iph->frag_off) & IP_OFFSET; if (NF_INVF(ipinfo, IPT_INV_FRAG, (ipinfo->flags & IPT_F_FRAG) && !frag_off)) return false; So we need to mask off non-offset bits. Second issue is that we negated the meaning in ipt-restore. -f should match if (frag_off & IP_OFFSET) NE 0 ! -f matches non-fragmented packets, i.e. frag_off & IP_OFFSET == 0. So we cannot use nft_invflags2cmp(), as that will use NEQ for negation, but we need EQ instead here. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables/nft-ipv4.c')
-rw-r--r--iptables/nft-ipv4.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 8193ac3c..bddd784c 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -65,10 +65,13 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
add_payload(r, offsetof(struct iphdr, frag_off), 2,
NFT_PAYLOAD_NETWORK_HEADER);
/* get the 13 bits that contain the fragment offset */
- add_bitwise_u16(r, 0x1fff, !0x1fff);
+ add_bitwise_u16(r, 0x1fff, 0);
/* if offset is non-zero, this is a fragment */
- op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_FRAG);
+ op = NFT_CMP_NEQ;
+ if (cs->fw.ip.invflags & IPT_INV_FRAG)
+ op = NFT_CMP_EQ;
+
add_cmp_u16(r, 0, op);
}
@@ -453,7 +456,7 @@ static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl)
cs->fw.ip.invflags & IPT_INV_VIA_OUT);
if (cs->fw.ip.flags & IPT_F_FRAG) {
- xt_xlate_add(xl, "ip frag-off %s%x ",
+ xt_xlate_add(xl, "ip frag-off & 0x1fff %s%x ",
cs->fw.ip.invflags & IPT_INV_FRAG? "" : "!= ", 0);
}