Blame SOURCES/0050-xtables-translate-Fix-translation-of-odd-netmasks.patch

082114
From d8b7a38b12888dcd39c7678b00625369389de9ea Mon Sep 17 00:00:00 2001
082114
From: Phil Sutter <phil@nwl.cc>
082114
Date: Tue, 2 Mar 2021 14:50:07 +0100
082114
Subject: [PATCH] xtables-translate: Fix translation of odd netmasks
082114
082114
Iptables supports netmasks which are not prefixes to match on (or
082114
ignore) arbitrary bits in an address. Yet nftables' prefix notation is
082114
available for real prefixes only, so translation is not as trivial -
082114
print bitmask syntax for those cases.
082114
082114
Signed-off-by: Phil Sutter <phil@nwl.cc>
082114
(cherry picked from commit 46f9d3a9a61ee80fa94b7fa7b3b36045c92606ae)
082114
Signed-off-by: Phil Sutter <psutter@redhat.com>
082114
---
082114
 extensions/generic.txlate   | 48 +++++++++++++++++++++++++++++++++++++
082114
 extensions/libxt_standard.t | 12 ++++++++++
082114
 iptables/nft-ipv4.c         | 42 ++++++++++++++++++++++----------
082114
 iptables/nft-ipv6.c         | 19 ++++++++++++---
082114
 4 files changed, 106 insertions(+), 15 deletions(-)
082114
082114
diff --git a/extensions/generic.txlate b/extensions/generic.txlate
082114
index 0e256c3727559..9ae9a5b54c1b9 100644
082114
--- a/extensions/generic.txlate
082114
+++ b/extensions/generic.txlate
082114
@@ -10,6 +10,54 @@ nft insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter
082114
 iptables-translate -A INPUT -i iif+ ! -d 10.0.0.0/8
082114
 nft add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter
082114
 
082114
+iptables-translate -I INPUT -s 10.11.12.13/255.255.0.0
082114
+nft insert rule ip filter INPUT ip saddr 10.11.0.0/16 counter
082114
+
082114
+iptables-translate -I INPUT -s 10.11.12.13/255.0.255.0
082114
+nft insert rule ip filter INPUT ip saddr & 255.0.255.0 == 10.0.12.0 counter
082114
+
082114
+iptables-translate -I INPUT -s 10.11.12.13/0.255.0.255
082114
+nft insert rule ip filter INPUT ip saddr & 0.255.0.255 == 0.11.0.13 counter
082114
+
082114
+iptables-translate -I INPUT ! -s 10.11.12.13/0.255.0.255
082114
+nft insert rule ip filter INPUT ip saddr & 0.255.0.255 != 0.11.0.13 counter
082114
+
082114
+iptables-translate -I INPUT -s 0.0.0.0/16
082114
+nft insert rule ip filter INPUT ip saddr 0.0.0.0/16 counter
082114
+
082114
+iptables-translate -I INPUT -s 0.0.0.0/0
082114
+nft insert rule ip filter INPUT counter
082114
+
082114
+iptables-translate -I INPUT ! -s 0.0.0.0/0
082114
+nft insert rule ip filter INPUT ip saddr != 0.0.0.0/0 counter
082114
+
082114
+ip6tables-translate -I INPUT -i iifname -s feed::/16
082114
+nft insert rule ip6 filter INPUT iifname "iifname" ip6 saddr feed::/16 counter
082114
+
082114
+ip6tables-translate -A INPUT -i iif+ ! -d feed::/16
082114
+nft add rule ip6 filter INPUT iifname "iif*" ip6 daddr != feed::/16 counter
082114
+
082114
+ip6tables-translate -I INPUT -s feed:babe::1/ffff:ff00::
082114
+nft insert rule ip6 filter INPUT ip6 saddr feed:ba00::/24 counter
082114
+
082114
+ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/ffff:0:ffff:0:ffff:0:ffff:0
082114
+nft insert rule ip6 filter INPUT ip6 saddr & ffff:0:ffff:0:ffff:0:ffff:0 == feed:0:c0ff:0:c0be:0:5678:0 counter
082114
+
082114
+ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff
082114
+nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff == 0:babe:0:ee00:0:1234:0:90ab counter
082114
+
082114
+ip6tables-translate -I INPUT ! -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff
082114
+nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff != 0:babe:0:ee00:0:1234:0:90ab counter
082114
+
082114
+ip6tables-translate -I INPUT -s ::/16
082114
+nft insert rule ip6 filter INPUT ip6 saddr ::/16 counter
082114
+
082114
+ip6tables-translate -I INPUT -s ::/0
082114
+nft insert rule ip6 filter INPUT counter
082114
+
082114
+ip6tables-translate -I INPUT ! -s ::/0
082114
+nft insert rule ip6 filter INPUT ip6 saddr != ::/0 counter
082114
+
082114
 ebtables-translate -I INPUT -i iname --logical-in ilogname -s 0:0:0:0:0:0
082114
 nft insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter
082114
 
082114
diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t
082114
index 4313f7b7bac9d..56d6da2e5884e 100644
082114
--- a/extensions/libxt_standard.t
082114
+++ b/extensions/libxt_standard.t
082114
@@ -9,3 +9,15 @@
082114
 -j ACCEPT;=;OK
082114
 -j RETURN;=;OK
082114
 ! -p 0 -j ACCEPT;=;FAIL
082114
+-s 10.11.12.13/8;-s 10.0.0.0/8;OK
082114
+-s 10.11.12.13/9;-s 10.0.0.0/9;OK
082114
+-s 10.11.12.13/10;-s 10.0.0.0/10;OK
082114
+-s 10.11.12.13/11;-s 10.0.0.0/11;OK
082114
+-s 10.11.12.13/12;-s 10.0.0.0/12;OK
082114
+-s 10.11.12.13/30;-s 10.11.12.12/30;OK
082114
+-s 10.11.12.13/31;-s 10.11.12.12/31;OK
082114
+-s 10.11.12.13/32;-s 10.11.12.13/32;OK
082114
+-s 10.11.12.13/255.0.0.0;-s 10.0.0.0/8;OK
082114
+-s 10.11.12.13/255.128.0.0;-s 10.0.0.0/9;OK
082114
+-s 10.11.12.13/255.0.255.0;-s 10.0.12.0/255.0.255.0;OK
082114
+-s 10.11.12.13/255.0.12.0;-s 10.0.12.0/255.0.12.0;OK
082114
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
082114
index 5bd0710781533..af5db31532540 100644
082114
--- a/iptables/nft-ipv4.c
082114
+++ b/iptables/nft-ipv4.c
082114
@@ -383,6 +383,32 @@ static void nft_ipv4_post_parse(int command,
082114
 			      " source or destination IP addresses");
082114
 }
082114
 
082114
+static void xlate_ipv4_addr(const char *selector, const struct in_addr *addr,
082114
+			    const struct in_addr *mask,
082114
+			    bool inv, struct xt_xlate *xl)
082114
+{
082114
+	const char *op = inv ? "!= " : "";
082114
+	int cidr;
082114
+
082114
+	if (!inv && !addr->s_addr && !mask->s_addr)
082114
+		return;
082114
+
082114
+	cidr = xtables_ipmask_to_cidr(mask);
082114
+	switch (cidr) {
082114
+	case -1:
082114
+		/* inet_ntoa() is not reentrant */
082114
+		xt_xlate_add(xl, "%s & %s ", selector, inet_ntoa(*mask));
082114
+		xt_xlate_add(xl, "%s %s ", inv ? "!=" : "==", inet_ntoa(*addr));
082114
+		break;
082114
+	case 32:
082114
+		xt_xlate_add(xl, "%s %s%s ", selector, op, inet_ntoa(*addr));
082114
+		break;
082114
+	default:
082114
+		xt_xlate_add(xl, "%s %s%s/%d ", selector, op, inet_ntoa(*addr),
082114
+			     cidr);
082114
+	}
082114
+}
082114
+
082114
 static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl)
082114
 {
082114
 	const struct iptables_command_state *cs = data;
082114
@@ -417,18 +443,10 @@ static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl)
082114
 		}
082114
 	}
082114
 
082114
-	if (cs->fw.ip.src.s_addr != 0) {
082114
-		xt_xlate_add(xl, "ip saddr %s%s%s ",
082114
-			   cs->fw.ip.invflags & IPT_INV_SRCIP ? "!= " : "",
082114
-			   inet_ntoa(cs->fw.ip.src),
082114
-			   xtables_ipmask_to_numeric(&cs->fw.ip.smsk));
082114
-	}
082114
-	if (cs->fw.ip.dst.s_addr != 0) {
082114
-		xt_xlate_add(xl, "ip daddr %s%s%s ",
082114
-			   cs->fw.ip.invflags & IPT_INV_DSTIP ? "!= " : "",
082114
-			   inet_ntoa(cs->fw.ip.dst),
082114
-			   xtables_ipmask_to_numeric(&cs->fw.ip.dmsk));
082114
-	}
082114
+	xlate_ipv4_addr("ip saddr", &cs->fw.ip.src, &cs->fw.ip.smsk,
082114
+			cs->fw.ip.invflags & IPT_INV_SRCIP, xl);
082114
+	xlate_ipv4_addr("ip daddr", &cs->fw.ip.dst, &cs->fw.ip.dmsk,
082114
+			cs->fw.ip.invflags & IPT_INV_DSTIP, xl);
082114
 
082114
 	ret = xlate_matches(cs, xl);
082114
 	if (!ret)
082114
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
082114
index 6ece631d85f59..a5481b3f77ac5 100644
082114
--- a/iptables/nft-ipv6.c
082114
+++ b/iptables/nft-ipv6.c
082114
@@ -337,14 +337,27 @@ static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr,
082114
 			    const struct in6_addr *mask,
082114
 			    int invert, struct xt_xlate *xl)
082114
 {
082114
+	const char *op = invert ? "!= " : "";
082114
 	char addr_str[INET6_ADDRSTRLEN];
082114
+	int cidr;
082114
 
082114
-	if (!invert && IN6_IS_ADDR_UNSPECIFIED(addr))
082114
+	if (!invert && IN6_IS_ADDR_UNSPECIFIED(addr) && IN6_IS_ADDR_UNSPECIFIED(mask))
082114
 		return;
082114
 
082114
 	inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN);
082114
-	xt_xlate_add(xl, "%s %s%s%s ", selector, invert ? "!= " : "", addr_str,
082114
-			xtables_ip6mask_to_numeric(mask));
082114
+	cidr = xtables_ip6mask_to_cidr(mask);
082114
+	switch (cidr) {
082114
+	case -1:
082114
+		xt_xlate_add(xl, "%s & %s %s %s ", selector,
082114
+			     xtables_ip6addr_to_numeric(mask),
082114
+			     invert ? "!=" : "==", addr_str);
082114
+		break;
082114
+	case 128:
082114
+		xt_xlate_add(xl, "%s %s%s ", selector, op, addr_str);
082114
+		break;
082114
+	default:
082114
+		xt_xlate_add(xl, "%s %s%s/%d ", selector, op, addr_str, cidr);
082114
+	}
082114
 }
082114
 
082114
 static int nft_ipv6_xlate(const void *data, struct xt_xlate *xl)
082114
-- 
082114
2.31.1
082114