]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables-nft: fix bogus handling of zero saddr/daddr
authorFlorian Westphal <fw@strlen.de>
Fri, 2 Nov 2018 09:47:25 +0000 (10:47 +0100)
committerFlorian Westphal <fw@strlen.de>
Sat, 3 Nov 2018 11:09:21 +0000 (12:09 +0100)
rule for 0.0.0.0/8 is added as 0.0.0.0/0, because we did not check
mask (or negation, for that matter).

Fix this and add test cases too.

This also revealed an ip6tables-nft-save bug, it would print
' !-d', not '! -d'.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1287
Signed-off-by: Florian Westphal <fw@strlen.de>
extensions/libip6t_standard.t [new file with mode: 0644]
extensions/libxt_standard.t
iptables/nft-ipv4.c
iptables/nft-ipv6.c

diff --git a/extensions/libip6t_standard.t b/extensions/libip6t_standard.t
new file mode 100644 (file)
index 0000000..a528af1
--- /dev/null
@@ -0,0 +1,5 @@
+:INPUT,FORWARD,OUTPUT
+-s ::/128;=;OK
+! -d ::;! -d ::/128;OK
+! -s ::;! -s ::/128;OK
+-s ::/64;=;OK
index 923569c33d577be505b4620dd19bb2d4b5d3273c..bfdedb7aa906dfe8abd0ee506d958b56876c16a9 100644 (file)
@@ -1,4 +1,8 @@
 :INPUT,FORWARD,OUTPUT
+-s 127.0.0.1/32 -d 0.0.0.0/8 -j DROP;=;OK
+! -s 0.0.0.0 -j ACCEPT;! -s 0.0.0.0/32 -j ACCEPT;OK
+! -d 0.0.0.0/32 -j ACCEPT;=;OK
+-s 0.0.0.0/24 -j RETURN;=;OK
 -j DROP;=;OK
 -j ACCEPT;=;OK
 -j RETURN;=;OK
index 39e6184489554c4fdbf9117a22780e4fc42d5384..6a8a7cedf6e349fbe84e0f30ff9dcf40223436ff 100644 (file)
@@ -48,13 +48,13 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
                add_l4proto(r, cs->fw.ip.proto, op);
        }
 
-       if (cs->fw.ip.src.s_addr != 0) {
+       if (cs->fw.ip.src.s_addr || cs->fw.ip.smsk.s_addr || cs->fw.ip.invflags & IPT_INV_SRCIP) {
                op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_SRCIP);
                add_addr(r, offsetof(struct iphdr, saddr),
                         &cs->fw.ip.src.s_addr, &cs->fw.ip.smsk.s_addr,
                         sizeof(struct in_addr), op);
        }
-       if (cs->fw.ip.dst.s_addr != 0) {
+       if (cs->fw.ip.dst.s_addr || cs->fw.ip.dmsk.s_addr || cs->fw.ip.invflags & IPT_INV_DSTIP) {
                op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_DSTIP);
                add_addr(r, offsetof(struct iphdr, daddr),
                         &cs->fw.ip.dst.s_addr, &cs->fw.ip.dmsk.s_addr,
index 1952164e199b91ebabe72b3f75cbbeb06dc3cad7..7bacee4ab3a219465e7bc2146733d0fa50c2377e 100644 (file)
@@ -47,13 +47,17 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
                add_l4proto(r, cs->fw6.ipv6.proto, op);
        }
 
-       if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src)) {
+       if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src) ||
+           !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.smsk) ||
+           (cs->fw6.ipv6.invflags & IPT_INV_SRCIP)) {
                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), op);
        }
-       if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst)) {
+       if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst) ||
+           !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dmsk) ||
+           (cs->fw6.ipv6.invflags & IPT_INV_DSTIP)) {
                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,
@@ -235,7 +239,7 @@ static void save_ipv6_addr(char letter, const struct in6_addr *addr,
                return;
 
        printf("%s-%c %s",
-               invert ? " !" : "", letter,
+               invert ? "" : "", letter,
                inet_ntop(AF_INET6, addr, addr_str, sizeof(addr_str)));
 
        if (l == -1)