Blame SOURCES/0035-Print-IPv6-prefixes-in-CIDR-notation.patch

05e71a
From 5ba6bb92b9ec3545d86d598f07643c399a47c7ad Mon Sep 17 00:00:00 2001
05e71a
From: Phil Sutter <phil@nwl.cc>
05e71a
Date: Tue, 12 Feb 2019 22:51:34 +0100
05e71a
Subject: [PATCH] Print IPv6 prefixes in CIDR notation
05e71a
05e71a
According to RFC4291, IPv6 prefixes are represented in CIDR notation.
05e71a
While the use of a "netmask" notation is not explicitly denied, its
05e71a
existence merely stems from applying IPv4 standards to IPv6. This is not
05e71a
necessarily correct.
05e71a
05e71a
Therefore change printing of IPv6 prefixes to use CIDR notation as long
05e71a
as the address mask's bits are left contiguous.
05e71a
05e71a
Signed-off-by: Phil Sutter <phil@nwl.cc>
05e71a
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
05e71a
Signed-off-by: Phil Sutter <psutter@redhat.com>
05e71a
---
05e71a
 useful_functions.c | 35 ++++++++++++++++++++++++++++++-----
05e71a
 1 file changed, 30 insertions(+), 5 deletions(-)
05e71a
05e71a
diff --git a/useful_functions.c b/useful_functions.c
05e71a
index 8a34f820f230b..bf4393712fa44 100644
05e71a
--- a/useful_functions.c
05e71a
+++ b/useful_functions.c
05e71a
@@ -416,16 +416,41 @@ char *ebt_ip6_to_numeric(const struct in6_addr *addrp)
05e71a
 	return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf));
05e71a
 }
05e71a
 
05e71a
+int ebt_ip6mask_to_cidr(const struct in6_addr *k)
05e71a
+{
05e71a
+	unsigned int bits = 0;
05e71a
+	uint32_t a, b, c, d;
05e71a
+
05e71a
+	a = ntohl(k->s6_addr32[0]);
05e71a
+	b = ntohl(k->s6_addr32[1]);
05e71a
+	c = ntohl(k->s6_addr32[2]);
05e71a
+	d = ntohl(k->s6_addr32[3]);
05e71a
+	while (a & 0x80000000U) {
05e71a
+		++bits;
05e71a
+		a <<= 1;
05e71a
+		a  |= (b >> 31) & 1;
05e71a
+		b <<= 1;
05e71a
+		b  |= (c >> 31) & 1;
05e71a
+		c <<= 1;
05e71a
+		c  |= (d >> 31) & 1;
05e71a
+		d <<= 1;
05e71a
+	}
05e71a
+	if (a != 0 || b != 0 || c != 0 || d != 0)
05e71a
+		return -1;
05e71a
+	return bits;
05e71a
+}
05e71a
+
05e71a
 char *ebt_ip6_mask_to_string(const struct in6_addr *msk)
05e71a
 {
05e71a
-   	/* /0000:0000:0000:0000:0000:000.000.000.000
05e71a
-	 * /0000:0000:0000:0000:0000:0000:0000:0000 */
05e71a
+	int l = ebt_ip6mask_to_cidr(msk);
05e71a
 	static char buf[51+1];
05e71a
-	if (msk->s6_addr32[0] == 0xFFFFFFFFL && msk->s6_addr32[1] == 0xFFFFFFFFL &&
05e71a
-	    msk->s6_addr32[2] == 0xFFFFFFFFL && msk->s6_addr32[3] == 0xFFFFFFFFL)
05e71a
+
05e71a
+	if (l == 127)
05e71a
 		*buf = '\0';
05e71a
-	else
05e71a
+	else if (l == -1)
05e71a
 		sprintf(buf, "/%s", ebt_ip6_to_numeric(msk));
05e71a
+	else
05e71a
+		sprintf(buf, "/%d", l);
05e71a
 	return buf;
05e71a
 }
05e71a
 
05e71a
-- 
05e71a
2.21.0
05e71a