All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anton Danilov <littlesmilingcloud@gmail.com>
To: Stephen Hemminger <stephen@networkplumber.org>
Cc: netdev@vger.kernel.org, Anton Danilov <littlesmilingcloud@gmail.com>
Subject: [PATCH] [RFC iproute2-next] tc: f_u32: Fix the ipv6 pretty printing.
Date: Tue,  8 Jun 2021 18:17:37 +0300	[thread overview]
Message-ID: <20210608151739.3220-1-littlesmilingcloud@gmail.com> (raw)

Unexpectedly the print_ipv6 function is the copy-paste version of the print_ipv4 function. Fixed.

Before patch:

$ sudo tc -p -s f ls dev dummy0
filter parent 1: protocol ipv6 pref 30 u32 chain 0
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800: ht divisor 1
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )
  match IP src 64.0.0.0/32 (success 0 )
  match IP dst 0.0.0.0/32 (success 0 )
  match sport 0, match dport 0 (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )  (success 0 )  (success 0 )  (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )
  match IP src 0.204.0.221/32 (success 0 )
  match IP dst 0.0.0.0/1 (success 0 )  (success 0 )  (success 0 )  (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::803 order 2051 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::804 order 2052 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::805 order 2053 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
  match IP ihl 1 (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::806 order 2054 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::807 order 2055 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0) (success 0 )

After patch:

$ sudo tc -p -s f ls dev dummy0
filter parent 1: protocol ipv6 pref 30 u32 chain 0
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800: ht divisor 1
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 src 2a02:26e0:4000::/128
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 dst 2a02:26e0:4000::/128
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 src aa:bb:cc:dd::/65
 match ipv6 dst aa:bb:cc:dd::/66
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::803 order 2051 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 class 0xff 0xff (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::804 order 2052 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 class 0x10 0xff (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::805 order 2053 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 class 0x10 0xf0 (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::806 order 2054 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 flowlabel 0xbcde 0xffff (success 0 )
filter parent 1: protocol ipv6 pref 30 u32 chain 0 fh 800::807 order 2055 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
 match ipv6 class 0x12 0xff
 match ipv6 flowlabel 0xbcde 0xffff (success 0 )

Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
 tc/f_u32.c | 152 +++++++++++++++++++++++++++++------------------------
 1 file changed, 82 insertions(+), 70 deletions(-)

diff --git a/tc/f_u32.c b/tc/f_u32.c
index 3fd3eb17..d7beb586 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -820,28 +820,28 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
 	return 0;
 }
 
-static void print_ipv4(FILE *f, const struct tc_u32_key *key)
+static int print_ipv4(FILE *f, const struct tc_u32_key *key)
 {
 	char abuf[256];
 
+	if (key == NULL)
+		return 0;
+
 	switch (key->off) {
 	case 0:
 		switch (ntohl(key->mask)) {
 		case 0x0f000000:
-			fprintf(f, "\n  match IP ihl %u",
+			return fprintf(f, "\n  match IP ihl %u",
 				ntohl(key->val) >> 24);
-			return;
 		case 0x00ff0000:
-			fprintf(f, "\n  match IP dsfield %#x",
+			return fprintf(f, "\n  match IP dsfield %#x",
 				ntohl(key->val) >> 16);
-			return;
 		}
 		break;
 	case 8:
 		if (ntohl(key->mask) == 0x00ff0000) {
-			fprintf(f, "\n  match IP protocol %d",
+			return fprintf(f, "\n  match IP protocol %d",
 				ntohl(key->val) >> 16);
-			return;
 		}
 		break;
 	case 12:
@@ -849,12 +849,11 @@ static void print_ipv4(FILE *f, const struct tc_u32_key *key)
 			int bits = mask2bits(key->mask);
 
 			if (bits >= 0) {
-				fprintf(f, "\n  %s %s/%d",
+				return fprintf(f, "\n  %s %s/%d",
 					key->off == 12 ? "match IP src" : "match IP dst",
 					inet_ntop(AF_INET, &key->val,
 						  abuf, sizeof(abuf)),
 					bits);
-				return;
 			}
 		}
 		break;
@@ -862,87 +861,100 @@ static void print_ipv4(FILE *f, const struct tc_u32_key *key)
 	case 20:
 		switch (ntohl(key->mask)) {
 		case 0x0000ffff:
-			fprintf(f, "\n  match dport %u",
+			return fprintf(f, "\n  match dport %u",
 				ntohl(key->val) & 0xffff);
-			return;
 		case 0xffff0000:
-			fprintf(f, "\n  match sport %u",
+			return fprintf(f, "\n  match sport %u",
 				ntohl(key->val) >> 16);
-			return;
 		case 0xffffffff:
-			fprintf(f, "\n  match dport %u, match sport %u",
+			return fprintf(f, "\n  match dport %u, match sport %u",
 				ntohl(key->val) & 0xffff,
 				ntohl(key->val) >> 16);
 
-			return;
 		}
 		/* XXX: Default print_raw */
 	}
+
+	return 0;
 }
 
-static void print_ipv6(FILE *f, const struct tc_u32_key *key)
+static int print_ipv6(FILE *f, const struct tc_u32_key *key)
 {
 	char abuf[256];
 
+	static __u32 ipv6_src_addr[4];
+	static int ipv6_src_plen;
+	static __u32 ipv6_dst_addr[4];
+	static int ipv6_dst_plen;
+
+	int ret = 0;
+
+	if ((key == NULL || key->off >= 24) && ipv6_src_plen > 0) {
+		ret = fprintf(f, "\n match ipv6 src %s/%d",
+			inet_ntop(AF_INET6, ipv6_src_addr, abuf, sizeof(abuf)), ipv6_src_plen);
+		memset(ipv6_src_addr, 0, 16);
+		ipv6_src_plen = 0;
+	}
+
+	if (key == NULL && ipv6_dst_plen > 0) {
+		ret += fprintf(f, "\n match ipv6 dst %s/%d",
+			inet_ntop(AF_INET6, ipv6_dst_addr, abuf, sizeof(abuf)), ipv6_dst_plen);
+		memset(ipv6_dst_addr, 0, 16);
+		ipv6_dst_plen = 0;
+	}
+
+	if (key == NULL)
+		return ret;
+
 	switch (key->off) {
 	case 0:
-		switch (ntohl(key->mask)) {
-		case 0x0f000000:
-			fprintf(f, "\n  match IP ihl %u",
-				ntohl(key->val) >> 24);
-			return;
-		case 0x00ff0000:
-			fprintf(f, "\n  match IP dsfield %#x",
-				ntohl(key->val) >> 16);
-			return;
+		if (ntohl(key->mask) & 0x0ff00000) {
+			ret = fprintf(f, "\n match ipv6 class %#x %#x",
+				(ntohl(key->val) & 0x0ff00000) >> 20,
+				(ntohl(key->mask) & 0x0ff00000) >> 20);
+		}
+		if (ntohl(key->mask) & 0x000fffff) {
+			ret += fprintf(f, "\n match ipv6 flowlabel %#x %#x",
+				ntohl(key->val) & 0x000fffff,
+				ntohl(key->mask) & 0x000fffff);
 		}
+		return ret;
 		break;
-	case 8:
-		if (ntohl(key->mask) == 0x00ff0000) {
-			fprintf(f, "\n  match IP protocol %d",
-				ntohl(key->val) >> 16);
-			return;
+	case 4:
+		if (ntohl(key->mask) == 0x0000ff00) {
+			return fprintf(f, "\n  match ipv6 protocol %d",
+				ntohl(key->val) >> 8);
 		}
 		break;
+	case 8:
 	case 12:
-	case 16: {
-			int bits = mask2bits(key->mask);
-
-			if (bits >= 0) {
-				fprintf(f, "\n  %s %s/%d",
-					key->off == 12 ? "match IP src" : "match IP dst",
-					inet_ntop(AF_INET, &key->val,
-						  abuf, sizeof(abuf)),
-					bits);
-				return;
-			}
+	case 16:
+	case 20: {
+			ipv6_src_plen += mask2bits(key->mask);
+			ipv6_src_addr[(key->off - 8) / 4] = key->val;
 		}
 		break;
-
-	case 20:
-		switch (ntohl(key->mask)) {
-		case 0x0000ffff:
-			fprintf(f, "\n  match sport %u",
-				ntohl(key->val) & 0xffff);
-			return;
-		case 0xffff0000:
-			fprintf(f, "\n  match dport %u",
-				ntohl(key->val) >> 16);
-			return;
-		case 0xffffffff:
-			fprintf(f, "\n  match sport %u, match dport %u",
-				ntohl(key->val) & 0xffff,
-				ntohl(key->val) >> 16);
-
-			return;
+	case 24:
+	case 28:
+	case 32:
+	case 36: {
+			ipv6_dst_plen += mask2bits(key->mask);
+			ipv6_dst_addr[(key->off - 24) / 4] = key->val;
 		}
+		break;
+
 		/* XXX: Default print_raw */
 	}
+
+	return 0;
 }
 
-static void print_raw(FILE *f, const struct tc_u32_key *key)
+static int print_raw(FILE *f, const struct tc_u32_key *key)
 {
-	fprintf(f, "\n  match %08x/%08x at %s%d",
+	if (key == NULL)
+		return 0;
+
+	return fprintf(f, "\n  match %08x/%08x at %s%d",
 		(unsigned int)ntohl(key->val),
 		(unsigned int)ntohl(key->mask),
 		key->offmask ? "nexthdr+" : "",
@@ -952,14 +964,14 @@ static void print_raw(FILE *f, const struct tc_u32_key *key)
 static const struct {
 	__u16 proto;
 	__u16 pad;
-	void (*pprinter)(FILE *f, const struct tc_u32_key *key);
+	int (*pprinter)(FILE *f, const struct tc_u32_key *key);
 } u32_pprinters[] = {
 	{0,	   0, print_raw},
 	{ETH_P_IP, 0, print_ipv4},
 	{ETH_P_IPV6, 0, print_ipv6},
 };
 
-static void show_keys(FILE *f, const struct tc_u32_key *key)
+static int show_keys(FILE *f, const struct tc_u32_key *key)
 {
 	int i = 0;
 
@@ -969,8 +981,7 @@ static void show_keys(FILE *f, const struct tc_u32_key *key)
 	for (i = 0; i < ARRAY_SIZE(u32_pprinters); i++) {
 		if (u32_pprinters[i].proto == ntohs(f_proto)) {
 show_k:
-			u32_pprinters[i].pprinter(f, key);
-			return;
+			return u32_pprinters[i].pprinter(f, key);
 		}
 	}
 
@@ -1289,12 +1300,13 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
 	if (sel) {
 		if (sel->nkeys) {
 			int i;
-
-			for (i = 0; i < sel->nkeys; i++) {
-				show_keys(f, sel->keys + i);
-				if (show_stats && NULL != pf)
-					fprintf(f, " (success %llu ) ",
-						(unsigned long long) pf->kcnts[i]);
+			// The ipv6 pretty printing requires an additional call at the end.
+			// Call the show_keys with the NULL value after call with last key.
+			for (i = 0; i <= sel->nkeys; i++) {
+				if (show_keys(f, i < sel->nkeys ? sel->keys + i : NULL))
+					if (i < sel->nkeys && show_stats && NULL != pf)
+						fprintf(f, " (success %llu ) ",
+							(unsigned long long) pf->kcnts[i]);
 			}
 		}
 
-- 
2.20.1


             reply	other threads:[~2021-06-08 15:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-08 15:17 Anton Danilov [this message]
2021-06-08 15:17 ` [PATCH] [RFC iproute2-next] tc: f_u32: fix the pretty print of ipv4 filters Anton Danilov
2021-06-08 15:17 ` [PATCH] [RFC iproute2-next] tc: f_u32: Rename commands and functions ip6 to ipv6 to unify naming Anton Danilov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210608151739.3220-1-littlesmilingcloud@gmail.com \
    --to=littlesmilingcloud@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.