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@xxxxxxxxx> --- extensions/libip6t_ipv6header.t | 4 ++++ extensions/libxt_standard.t | 4 ++++ iptables/nft-ipv4.c | 4 ++-- iptables/nft-ipv6.c | 10 +++++++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/extensions/libip6t_ipv6header.t b/extensions/libip6t_ipv6header.t index 67fa47998ee0..22805c819370 100644 --- a/extensions/libip6t_ipv6header.t +++ b/extensions/libip6t_ipv6header.t @@ -1,4 +1,8 @@ :INPUT,FORWARD,OUTPUT +-s ::/128;=;OK +! -d ::;! -d ::/128;OK +! -s ::;! -s ::/128;OK +-s ::/64;=;OK -m ipv6header --header hop-by-hop;=;OK -m ipv6header --header hop-by-hop --soft;=;OK -m ipv6header --header ipv6-nonxt;=;OK diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t index 923569c33d57..bfdedb7aa906 100644 --- a/extensions/libxt_standard.t +++ b/extensions/libxt_standard.t @@ -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 diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index 39e618448955..6a8a7cedf6e3 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -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, diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index 1952164e199b..7bacee4ab3a2 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -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) -- 2.18.1