summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-11-02 10:47:25 +0100
committerFlorian Westphal <fw@strlen.de>2018-11-03 12:09:21 +0100
commitd4bc5a38598b479b124973a821324ce867e87760 (patch)
treecb79ff0f7aea4c910111825c231db126054978e1 /iptables
parent9ff99156b63ee39af3e8fce5ae5b0a2e2e8f0170 (diff)
iptables-nft: fix bogus handling of zero saddr/daddr
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>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft-ipv4.c4
-rw-r--r--iptables/nft-ipv6.c10
2 files changed, 9 insertions, 5 deletions
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 39e61844..6a8a7ced 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 1952164e..7bacee4a 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)