All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next 0/9] print refactoring
@ 2018-02-07 17:10 Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 1/9] iproute: refactor printing flags Stephen Hemminger
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger

This patch set breaks up the big print_route function into
smaller pieces for readability and to make later changes
to support JSON and color output easier.

Stephen Hemminger (9):
  iproute: refactor printing flags
  iproute: make printing icmpv6 a function
  iproute: make printing IPv4 cache flags a function
  iproute: refactor cacheinfo printing
  iproute: refactor metrics print
  iproute: refactor printing flow info
  iproute: refactor newdst, gateway and via printing
  iproute: refactor multipath print
  iproute: refactor printing of interface

 ip/iproute.c | 571 +++++++++++++++++++++++++++++++----------------------------
 1 file changed, 297 insertions(+), 274 deletions(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 1/9] iproute: refactor printing flags
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 2/9] iproute: make printing icmpv6 a function Stephen Hemminger
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

Both next hop and route need to decode flags.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 7616c0d95290..024f1cd87cbb 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -347,6 +347,22 @@ static void print_rtax_features(FILE *fp, unsigned int features)
 		fprintf(fp, "0x%x ", of);
 }
 
+static void print_rt_flags(FILE *fp, unsigned int flags)
+{
+	if (flags & RTNH_F_DEAD)
+		fprintf(fp, "dead ");
+	if (flags & RTNH_F_ONLINK)
+		fprintf(fp, "onlink ");
+	if (flags & RTNH_F_PERVASIVE)
+		fprintf(fp, "pervasive ");
+	if (flags & RTNH_F_OFFLOAD)
+		fprintf(fp, "offload ");
+	if (flags & RTNH_F_LINKDOWN)
+		fprintf(fp, "linkdown ");
+	if (flags & RTNH_F_UNRESOLVED)
+		fprintf(fp, "unresolved ");
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -478,20 +494,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	}
 	if (tb[RTA_PRIORITY] && filter.metricmask != -1)
 		fprintf(fp, "metric %u ", rta_getattr_u32(tb[RTA_PRIORITY]));
-	if (r->rtm_flags & RTNH_F_DEAD)
-		fprintf(fp, "dead ");
-	if (r->rtm_flags & RTNH_F_ONLINK)
-		fprintf(fp, "onlink ");
-	if (r->rtm_flags & RTNH_F_PERVASIVE)
-		fprintf(fp, "pervasive ");
-	if (r->rtm_flags & RTNH_F_OFFLOAD)
-		fprintf(fp, "offload ");
-	if (r->rtm_flags & RTM_F_NOTIFY)
-		fprintf(fp, "notify ");
-	if (r->rtm_flags & RTNH_F_LINKDOWN)
-		fprintf(fp, "linkdown ");
-	if (r->rtm_flags & RTNH_F_UNRESOLVED)
-		fprintf(fp, "unresolved ");
+
+	print_rt_flags(fp, r->rtm_flags);
+
 	if (tb[RTA_MARK]) {
 		unsigned int mark = rta_getattr_u32(tb[RTA_MARK]);
 
@@ -728,16 +733,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 					fprintf(fp, "weight %d ",
 						nh->rtnh_hops+1);
 			}
-			if (nh->rtnh_flags & RTNH_F_DEAD)
-				fprintf(fp, "dead ");
-			if (nh->rtnh_flags & RTNH_F_ONLINK)
-				fprintf(fp, "onlink ");
-			if (nh->rtnh_flags & RTNH_F_PERVASIVE)
-				fprintf(fp, "pervasive ");
-			if (nh->rtnh_flags & RTNH_F_OFFLOAD)
-				fprintf(fp, "offload ");
-			if (nh->rtnh_flags & RTNH_F_LINKDOWN)
-				fprintf(fp, "linkdown ");
+
+			print_rt_flags(fp, nh->rtnh_flags);
+
 			len -= NLMSG_ALIGN(nh->rtnh_len);
 			nh = RTNH_NEXT(nh);
 		}
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 2/9] iproute: make printing icmpv6 a function
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 1/9] iproute: refactor printing flags Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 3/9] iproute: make printing IPv4 cache flags " Stephen Hemminger
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

Refactor to reduce size of print_route and improve
readability.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 024f1cd87cbb..da6a4faed836 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -363,6 +363,25 @@ static void print_rt_flags(FILE *fp, unsigned int flags)
 		fprintf(fp, "unresolved ");
 }
 
+static void print_rt_pref(FILE *fp, unsigned int pref)
+{
+	fprintf(fp, "pref ");
+
+	switch (pref) {
+	case ICMPV6_ROUTER_PREF_LOW:
+		fprintf(fp, "low");
+		break;
+	case ICMPV6_ROUTER_PREF_MEDIUM:
+		fprintf(fp, "medium");
+		break;
+	case ICMPV6_ROUTER_PREF_HIGH:
+		fprintf(fp, "high");
+		break;
+	default:
+		fprintf(fp, "%u", pref);
+	}
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -740,25 +759,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 			nh = RTNH_NEXT(nh);
 		}
 	}
-	if (tb[RTA_PREF]) {
-		unsigned int pref = rta_getattr_u8(tb[RTA_PREF]);
 
-		fprintf(fp, "pref ");
+	if (tb[RTA_PREF])
+		print_rt_pref(fp, rta_getattr_u8(tb[RTA_PREF]));
 
-		switch (pref) {
-		case ICMPV6_ROUTER_PREF_LOW:
-			fprintf(fp, "low");
-			break;
-		case ICMPV6_ROUTER_PREF_MEDIUM:
-			fprintf(fp, "medium");
-			break;
-		case ICMPV6_ROUTER_PREF_HIGH:
-			fprintf(fp, "high");
-			break;
-		default:
-			fprintf(fp, "%u", pref);
-		}
-	}
 	if (tb[RTA_TTL_PROPAGATE]) {
 		fprintf(fp, "ttl-propagate ");
 		if (rta_getattr_u8(tb[RTA_TTL_PROPAGATE]))
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 3/9] iproute: make printing IPv4 cache flags a function
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 1/9] iproute: refactor printing flags Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 2/9] iproute: make printing icmpv6 a function Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 4/9] iproute: refactor cacheinfo printing Stephen Hemminger
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

More refactoring prior to JSON support.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 65 ++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index da6a4faed836..7317bf116e2c 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -382,6 +382,43 @@ static void print_rt_pref(FILE *fp, unsigned int pref)
 	}
 }
 
+static void print_cache_flags(FILE *fp, __u32 flags)
+{
+	flags &= ~0xFFFF;
+
+	fprintf(fp, "%s    cache ", _SL_);
+
+	if (flags == 0)
+		return;
+
+	putc('<', fp);
+
+#define PRTFL(fl, flname)						\
+	if (flags & RTCF_##fl) {					\
+		flags &= ~RTCF_##fl;					\
+		fprintf(fp, "%s%s", flname, flags ? "," : "> ");	\
+	}
+
+	PRTFL(LOCAL, "local");
+	PRTFL(REJECT, "reject");
+	PRTFL(MULTICAST, "mc");
+	PRTFL(BROADCAST, "brd");
+	PRTFL(DNAT, "dst-nat");
+	PRTFL(SNAT, "src-nat");
+	PRTFL(MASQ, "masq");
+	PRTFL(DIRECTDST, "dst-direct");
+	PRTFL(DIRECTSRC, "src-direct");
+	PRTFL(REDIRECTED, "redirected");
+	PRTFL(DOREDIRECT, "redirect");
+	PRTFL(FAST, "fastroute");
+	PRTFL(NOTIFY, "notify");
+	PRTFL(TPROXY, "proxy");
+#undef PRTFL
+
+	if (flags)
+		fprintf(fp, "%#x> ", flags);
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -544,33 +581,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if (tb[RTA_UID])
 		fprintf(fp, "uid %u ", rta_getattr_u32(tb[RTA_UID]));
 
-	if ((r->rtm_flags&RTM_F_CLONED) && r->rtm_family == AF_INET) {
-		__u32 flags = r->rtm_flags&~0xFFFF;
-		int first = 1;
+	if ((r->rtm_flags & RTM_F_CLONED) && r->rtm_family == AF_INET) {
+		print_cache_flags(fp, r->rtm_flags);
 
-		fprintf(fp, "%s    cache ", _SL_);
-
-#define PRTFL(fl, flname) if (flags&RTCF_##fl) { \
-  flags &= ~RTCF_##fl; \
-  fprintf(fp, "%s" flname "%s", first ? "<" : "", flags ? "," : "> "); \
-  first = 0; }
-		PRTFL(LOCAL, "local");
-		PRTFL(REJECT, "reject");
-		PRTFL(MULTICAST, "mc");
-		PRTFL(BROADCAST, "brd");
-		PRTFL(DNAT, "dst-nat");
-		PRTFL(SNAT, "src-nat");
-		PRTFL(MASQ, "masq");
-		PRTFL(DIRECTDST, "dst-direct");
-		PRTFL(DIRECTSRC, "src-direct");
-		PRTFL(REDIRECTED, "redirected");
-		PRTFL(DOREDIRECT, "redirect");
-		PRTFL(FAST, "fastroute");
-		PRTFL(NOTIFY, "notify");
-		PRTFL(TPROXY, "proxy");
-
-		if (flags)
-			fprintf(fp, "%s%x> ", first ? "<" : "", flags);
 		if (tb[RTA_CACHEINFO]) {
 			struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 4/9] iproute: refactor cacheinfo printing
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (2 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 3/9] iproute: make printing IPv4 cache flags " Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 5/9] iproute: refactor metrics print Stephen Hemminger
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

Make common function for decoding cacheinfo.
This code may print more info than old version in some cases.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 78 +++++++++++++++++++++++++-----------------------------------
 1 file changed, 32 insertions(+), 46 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 7317bf116e2c..a5e4c926e617 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -419,6 +419,31 @@ static void print_cache_flags(FILE *fp, __u32 flags)
 		fprintf(fp, "%#x> ", flags);
 }
 
+static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci)
+{
+	static int hz;
+
+	if (!hz)
+		hz = get_user_hz();
+	if (ci->rta_expires != 0)
+		fprintf(fp, "expires %dsec ", ci->rta_expires/hz);
+	if (ci->rta_error != 0)
+		fprintf(fp, "error %d ", ci->rta_error);
+	if (show_stats) {
+		if (ci->rta_clntref)
+			fprintf(fp, "users %d ", ci->rta_clntref);
+		if (ci->rta_used != 0)
+			fprintf(fp, "used %d ", ci->rta_used);
+		if (ci->rta_lastuse != 0)
+			fprintf(fp, "age %dsec ", ci->rta_lastuse/hz);
+	}
+	if (ci->rta_id)
+		fprintf(fp, "ipid 0x%04x ", ci->rta_id);
+	if (ci->rta_ts || ci->rta_tsage)
+		fprintf(fp, "ts 0x%x tsage %dsec ",
+			ci->rta_ts, ci->rta_tsage);
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -430,7 +455,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	int ret;
 
 	SPRINT_BUF(b1);
-	static int hz;
 
 	if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
 		fprintf(stderr, "Not a route: %08x %08x %08x\n",
@@ -584,56 +608,18 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if ((r->rtm_flags & RTM_F_CLONED) && r->rtm_family == AF_INET) {
 		print_cache_flags(fp, r->rtm_flags);
 
-		if (tb[RTA_CACHEINFO]) {
-			struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
+		if (tb[RTA_CACHEINFO])
+			print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO]));
 
-			if (!hz)
-				hz = get_user_hz();
-			if (ci->rta_expires != 0)
-				fprintf(fp, "expires %dsec ", ci->rta_expires/hz);
-			if (ci->rta_error != 0)
-				fprintf(fp, "error %d ", ci->rta_error);
-			if (show_stats) {
-				if (ci->rta_clntref)
-					fprintf(fp, "users %d ", ci->rta_clntref);
-				if (ci->rta_used != 0)
-					fprintf(fp, "used %d ", ci->rta_used);
-				if (ci->rta_lastuse != 0)
-					fprintf(fp, "age %dsec ", ci->rta_lastuse/hz);
-			}
-			if (ci->rta_id)
-				fprintf(fp, "ipid 0x%04x ", ci->rta_id);
-			if (ci->rta_ts || ci->rta_tsage)
-				fprintf(fp, "ts 0x%x tsage %dsec ",
-					ci->rta_ts, ci->rta_tsage);
-		}
 	} else if (r->rtm_family == AF_INET6) {
-		struct rta_cacheinfo *ci = NULL;
+
+		if (r->rtm_flags & RTM_F_CLONED)
+			fprintf(fp, "%s    cache ", _SL_);
 
 		if (tb[RTA_CACHEINFO])
-			ci = RTA_DATA(tb[RTA_CACHEINFO]);
-		if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
-			if (!hz)
-				hz = get_user_hz();
-			if (r->rtm_flags & RTM_F_CLONED)
-				fprintf(fp, "%s    cache ", _SL_);
-			if (ci->rta_expires)
-				fprintf(fp, "expires %dsec ", ci->rta_expires/hz);
-			if (ci->rta_error != 0)
-				fprintf(fp, "error %d ", ci->rta_error);
-			if (show_stats) {
-				if (ci->rta_clntref)
-					fprintf(fp, "users %d ", ci->rta_clntref);
-				if (ci->rta_used != 0)
-					fprintf(fp, "used %d ", ci->rta_used);
-				if (ci->rta_lastuse != 0)
-					fprintf(fp, "age %dsec ", ci->rta_lastuse/hz);
-			}
-		} else if (ci) {
-			if (ci->rta_error != 0)
-				fprintf(fp, "error %d ", ci->rta_error);
-		}
+			print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO]));
 	}
+
 	if (tb[RTA_METRICS]) {
 		int i;
 		unsigned int mxlock = 0;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 5/9] iproute: refactor metrics print
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (3 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 4/9] iproute: refactor cacheinfo printing Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 6/9] iproute: refactor printing flow info Stephen Hemminger
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger

Make a separate function to improve readability and enable
easier JSON conversion.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 ip/iproute.c | 117 +++++++++++++++++++++++++++++++----------------------------
 1 file changed, 61 insertions(+), 56 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index a5e4c926e617..f93229ca6caa 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -444,6 +444,65 @@ static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci)
 			ci->rta_ts, ci->rta_tsage);
 }
 
+static void print_rta_metrics(FILE *fp, const struct rtattr *rta)
+{
+	struct rtattr *mxrta[RTAX_MAX+1];
+	unsigned int mxlock = 0;
+	int i;
+
+	parse_rtattr(mxrta, RTAX_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta));
+
+	if (mxrta[RTAX_LOCK])
+		mxlock = rta_getattr_u32(mxrta[RTAX_LOCK]);
+
+	for (i = 2; i <= RTAX_MAX; i++) {
+		__u32 val = 0U;
+
+		if (mxrta[i] == NULL && !(mxlock & (1 << i)))
+			continue;
+
+		if (mxrta[i] != NULL && i != RTAX_CC_ALGO)
+			val = rta_getattr_u32(mxrta[i]);
+
+		if (i == RTAX_HOPLIMIT && (int)val == -1)
+			continue;
+
+		if (i < sizeof(mx_names)/sizeof(char *) && mx_names[i])
+			fprintf(fp, "%s ", mx_names[i]);
+		else
+			fprintf(fp, "metric %d ", i);
+
+		if (mxlock & (1<<i))
+			fprintf(fp, "lock ");
+
+		switch (i) {
+		case RTAX_FEATURES:
+			print_rtax_features(fp, val);
+			break;
+		default:
+			fprintf(fp, "%u ", val);
+			break;
+
+		case RTAX_RTT:
+		case RTAX_RTTVAR:
+		case RTAX_RTO_MIN:
+			if (i == RTAX_RTT)
+				val /= 8;
+			else if (i == RTAX_RTTVAR)
+				val /= 4;
+
+			if (val >= 1000)
+				fprintf(fp, "%gs ", val/1e3);
+			else
+				fprintf(fp, "%ums ", val);
+			break;
+		case RTAX_CC_ALGO:
+			fprintf(fp, "%s ", rta_getattr_str(mxrta[i]));
+			break;
+		}
+	}
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -620,63 +679,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 			print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO]));
 	}
 
-	if (tb[RTA_METRICS]) {
-		int i;
-		unsigned int mxlock = 0;
-		struct rtattr *mxrta[RTAX_MAX+1];
-
-		parse_rtattr(mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]),
-			    RTA_PAYLOAD(tb[RTA_METRICS]));
-		if (mxrta[RTAX_LOCK])
-			mxlock = rta_getattr_u32(mxrta[RTAX_LOCK]);
-
-		for (i = 2; i <= RTAX_MAX; i++) {
-			__u32 val = 0U;
-
-			if (mxrta[i] == NULL && !(mxlock & (1 << i)))
-				continue;
-
-			if (mxrta[i] != NULL && i != RTAX_CC_ALGO)
-				val = rta_getattr_u32(mxrta[i]);
-
-			if (i == RTAX_HOPLIMIT && (int)val == -1)
-				continue;
-
-			if (i < sizeof(mx_names)/sizeof(char *) && mx_names[i])
-				fprintf(fp, "%s ", mx_names[i]);
-			else
-				fprintf(fp, "metric %d ", i);
-
-			if (mxlock & (1<<i))
-				fprintf(fp, "lock ");
+	if (tb[RTA_METRICS])
+		print_rta_metrics(fp, tb[RTA_METRICS]);
 
-			switch (i) {
-			case RTAX_FEATURES:
-				print_rtax_features(fp, val);
-				break;
-			default:
-				fprintf(fp, "%u ", val);
-				break;
-
-			case RTAX_RTT:
-			case RTAX_RTTVAR:
-			case RTAX_RTO_MIN:
-				if (i == RTAX_RTT)
-					val /= 8;
-				else if (i == RTAX_RTTVAR)
-					val /= 4;
-
-				if (val >= 1000)
-					fprintf(fp, "%gs ", val/1e3);
-				else
-					fprintf(fp, "%ums ", val);
-				break;
-			case RTAX_CC_ALGO:
-				fprintf(fp, "%s ", rta_getattr_str(mxrta[i]));
-				break;
-			}
-		}
-	}
 	if (tb[RTA_IIF] && filter.iifmask != -1) {
 		fprintf(fp, "iif %s ",
 			ll_index_to_name(rta_getattr_u32(tb[RTA_IIF])));
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 6/9] iproute: refactor printing flow info
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (4 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 5/9] iproute: refactor metrics print Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 7/9] iproute: refactor newdst, gateway and via printing Stephen Hemminger
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger

Use common code for printing flow info.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 ip/iproute.c | 46 ++++++++++++++++++++--------------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index f93229ca6caa..1635a9e29bcf 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -444,6 +444,22 @@ static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci)
 			ci->rta_ts, ci->rta_tsage);
 }
 
+static void print_rta_flow(FILE *fp, const struct rtattr *rta)
+{
+	__u32 to = rta_getattr_u32(rta);
+	__u32 from = to >> 16;
+	SPRINT_BUF(b1);
+
+	to &= 0xFFFF;
+	fprintf(fp, "realm%s ", from ? "s" : "");
+	if (from) {
+		fprintf(fp, "%s/",
+			rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
+	}
+	fprintf(fp, "%s ",
+		rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
+}
+
 static void print_rta_metrics(FILE *fp, const struct rtattr *rta)
 {
 	struct rtattr *mxrta[RTAX_MAX+1];
@@ -647,19 +663,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		}
 	}
 
-	if (tb[RTA_FLOW] && filter.realmmask != ~0U) {
-		__u32 to = rta_getattr_u32(tb[RTA_FLOW]);
-		__u32 from = to>>16;
-
-		to &= 0xFFFF;
-		fprintf(fp, "realm%s ", from ? "s" : "");
-		if (from) {
-			fprintf(fp, "%s/",
-				rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
-		}
-		fprintf(fp, "%s ",
-			rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
-	}
+	if (tb[RTA_FLOW] && filter.realmmask != ~0U)
+		print_rta_flow(fp, tb[RTA_FLOW]);
 
 	if (tb[RTA_UID])
 		fprintf(fp, "uid %u ", rta_getattr_u32(tb[RTA_UID]));
@@ -731,19 +736,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 						family_name(via->rtvia_family),
 						format_host(via->rtvia_family, len, via->rtvia_addr));
 				}
-				if (tb[RTA_FLOW]) {
-					__u32 to = rta_getattr_u32(tb[RTA_FLOW]);
-					__u32 from = to>>16;
-
-					to &= 0xFFFF;
-					fprintf(fp, "realm%s ", from ? "s" : "");
-					if (from) {
-						fprintf(fp, "%s/",
-							rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
-					}
-					fprintf(fp, "%s ",
-						rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
-				}
+				if (tb[RTA_FLOW])
+					print_rta_flow(fp, tb[RTA_FLOW]);
 			}
 			if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
 				fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex));
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 7/9] iproute: refactor newdst, gateway and via printing
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (5 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 6/9] iproute: refactor printing flow info Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 8/9] iproute: refactor multipath print Stephen Hemminger
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

Since these fields are printed in both route and multipath case;
avoid duplicating code.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 73 +++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 40 insertions(+), 33 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 1635a9e29bcf..74216e73648f 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -460,6 +460,32 @@ static void print_rta_flow(FILE *fp, const struct rtattr *rta)
 		rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
 }
 
+static void print_rta_newdst(FILE *fp, const struct rtmsg *r,
+			     const struct rtattr *rta)
+{
+	const char *newdst = format_host_rta(r->rtm_family, rta);
+
+	fprintf(fp, "as to %s ", newdst);
+}
+
+static void print_rta_gateway(FILE *fp, const struct rtmsg *r,
+			      const struct rtattr *rta)
+{
+	const char *gateway = format_host_rta(r->rtm_family, rta);
+
+	fprintf(fp, "via %s ", gateway);
+}
+
+static void print_rta_via(FILE *fp, const struct rtattr *rta)
+{
+	const struct rtvia *via = RTA_DATA(rta);
+	size_t len = RTA_PAYLOAD(rta);
+
+	fprintf(fp, "via %s %s ",
+		family_name(via->rtvia_family),
+		format_host(via->rtvia_family, len, via->rtvia_addr));
+}
+
 static void print_rta_metrics(FILE *fp, const struct rtattr *rta)
 {
 	struct rtattr *mxrta[RTAX_MAX+1];
@@ -604,10 +630,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	} else if (r->rtm_src_len) {
 		fprintf(fp, "from 0/%u ", r->rtm_src_len);
 	}
-	if (tb[RTA_NEWDST]) {
-		fprintf(fp, "as to %s ",
-		        format_host_rta(r->rtm_family, tb[RTA_NEWDST]));
-	}
+
+	if (tb[RTA_NEWDST])
+		print_rta_newdst(fp, r, tb[RTA_NEWDST]);
 
 	if (tb[RTA_ENCAP])
 		lwt_print_encap(fp, tb[RTA_ENCAP_TYPE], tb[RTA_ENCAP]);
@@ -617,18 +642,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
 	}
 
-	if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
-		fprintf(fp, "via %s ",
-		        format_host_rta(r->rtm_family, tb[RTA_GATEWAY]));
-	}
-	if (tb[RTA_VIA]) {
-		size_t len = RTA_PAYLOAD(tb[RTA_VIA]) - 2;
-		struct rtvia *via = RTA_DATA(tb[RTA_VIA]);
+	if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len)
+		print_rta_gateway(fp, r, tb[RTA_GATEWAY]);
+
+	if (tb[RTA_VIA])
+		print_rta_via(fp, tb[RTA_VIA]);
 
-		fprintf(fp, "via %s %s ",
-			family_name(via->rtvia_family),
-			format_host(via->rtvia_family, len, via->rtvia_addr));
-	}
 	if (tb[RTA_OIF] && filter.oifmask != -1)
 		fprintf(fp, "dev %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_OIF])));
 
@@ -718,24 +737,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 					lwt_print_encap(fp,
 							tb[RTA_ENCAP_TYPE],
 							tb[RTA_ENCAP]);
-				if (tb[RTA_NEWDST]) {
-					fprintf(fp, "as to %s ",
-						format_host_rta(r->rtm_family,
-								tb[RTA_NEWDST]));
-				}
-				if (tb[RTA_GATEWAY]) {
-					fprintf(fp, "via %s ",
-						format_host_rta(r->rtm_family,
-								tb[RTA_GATEWAY]));
-				}
-				if (tb[RTA_VIA]) {
-					size_t len = RTA_PAYLOAD(tb[RTA_VIA]) - 2;
-					struct rtvia *via = RTA_DATA(tb[RTA_VIA]);
-
-					fprintf(fp, "via %s %s ",
-						family_name(via->rtvia_family),
-						format_host(via->rtvia_family, len, via->rtvia_addr));
-				}
+				if (tb[RTA_NEWDST])
+					print_rta_newdst(fp, r, tb[RTA_NEWDST]);
+				if (tb[RTA_GATEWAY])
+					print_rta_gateway(fp, r, tb[RTA_GATEWAY]);
+				if (tb[RTA_VIA])
+					print_rta_via(fp, tb[RTA_VIA]);
 				if (tb[RTA_FLOW])
 					print_rta_flow(fp, tb[RTA_FLOW]);
 			}
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 8/9] iproute: refactor multipath print
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (6 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 7/9] iproute: refactor newdst, gateway and via printing Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-07 17:10 ` [PATCH iproute2-next 9/9] iproute: refactor printing of interface Stephen Hemminger
  2018-02-08  0:14 ` [PATCH iproute2-next 0/9] print refactoring David Ahern
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

Make printing of multipath attributes a function to improve
readability.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 116 ++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 63 insertions(+), 53 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 74216e73648f..c9139bf66bd2 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -545,6 +545,67 @@ static void print_rta_metrics(FILE *fp, const struct rtattr *rta)
 	}
 }
 
+static void print_rta_multipath(FILE *fp, const struct rtmsg *r,
+				struct rtattr *rta)
+{
+	const struct rtnexthop *nh = RTA_DATA(rta);
+	int len = RTA_PAYLOAD(rta);
+	int first = 1;
+
+	while (len > sizeof(*nh)) {
+		struct rtattr *tb[RTA_MAX + 1];
+
+		if (nh->rtnh_len > len)
+			break;
+
+		if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
+			if (first) {
+				fprintf(fp, "Oifs: ");
+				first = 0;
+			} else {
+				fprintf(fp, " ");
+			}
+		} else
+			fprintf(fp, "%s\tnexthop ", _SL_);
+
+		if (nh->rtnh_len > sizeof(*nh)) {
+			parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh),
+				     nh->rtnh_len - sizeof(*nh));
+
+			if (tb[RTA_ENCAP])
+				lwt_print_encap(fp,
+						tb[RTA_ENCAP_TYPE],
+						tb[RTA_ENCAP]);
+			if (tb[RTA_NEWDST])
+				print_rta_newdst(fp, r, tb[RTA_NEWDST]);
+			if (tb[RTA_GATEWAY])
+				print_rta_gateway(fp, r, tb[RTA_GATEWAY]);
+			if (tb[RTA_VIA])
+				print_rta_via(fp, tb[RTA_VIA]);
+			if (tb[RTA_FLOW])
+				print_rta_flow(fp, tb[RTA_FLOW]);
+		}
+
+		if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
+			fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex));
+			if (nh->rtnh_hops != 1)
+				fprintf(fp, "(ttl>%d)", nh->rtnh_hops);
+			fprintf(fp, " ");
+		} else {
+			fprintf(fp, "dev %s ",
+				ll_index_to_name(nh->rtnh_ifindex));
+			if (r->rtm_family != AF_MPLS)
+				fprintf(fp, "weight %d ",
+					nh->rtnh_hops+1);
+		}
+
+		print_rt_flags(fp, nh->rtnh_flags);
+
+		len -= NLMSG_ALIGN(nh->rtnh_len);
+		nh = RTNH_NEXT(nh);
+	}
+}
+
 int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
@@ -710,60 +771,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		fprintf(fp, "iif %s ",
 			ll_index_to_name(rta_getattr_u32(tb[RTA_IIF])));
 	}
-	if (tb[RTA_MULTIPATH]) {
-		struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]);
-		int first = 1;
-
-		len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
-
-		for (;;) {
-			if (len < sizeof(*nh))
-				break;
-			if (nh->rtnh_len > len)
-				break;
-			if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
-				if (first) {
-					fprintf(fp, "Oifs: ");
-					first = 0;
-				} else {
-					fprintf(fp, " ");
-				}
-			} else
-				fprintf(fp, "%s\tnexthop ", _SL_);
-			if (nh->rtnh_len > sizeof(*nh)) {
-				parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh), nh->rtnh_len - sizeof(*nh));
-
-				if (tb[RTA_ENCAP])
-					lwt_print_encap(fp,
-							tb[RTA_ENCAP_TYPE],
-							tb[RTA_ENCAP]);
-				if (tb[RTA_NEWDST])
-					print_rta_newdst(fp, r, tb[RTA_NEWDST]);
-				if (tb[RTA_GATEWAY])
-					print_rta_gateway(fp, r, tb[RTA_GATEWAY]);
-				if (tb[RTA_VIA])
-					print_rta_via(fp, tb[RTA_VIA]);
-				if (tb[RTA_FLOW])
-					print_rta_flow(fp, tb[RTA_FLOW]);
-			}
-			if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
-				fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex));
-				if (nh->rtnh_hops != 1)
-					fprintf(fp, "(ttl>%d)", nh->rtnh_hops);
-				fprintf(fp, " ");
-			} else {
-				fprintf(fp, "dev %s ", ll_index_to_name(nh->rtnh_ifindex));
-				if (r->rtm_family != AF_MPLS)
-					fprintf(fp, "weight %d ",
-						nh->rtnh_hops+1);
-			}
-
-			print_rt_flags(fp, nh->rtnh_flags);
 
-			len -= NLMSG_ALIGN(nh->rtnh_len);
-			nh = RTNH_NEXT(nh);
-		}
-	}
+	if (tb[RTA_MULTIPATH])
+		print_rta_multipath(fp, r, tb[RTA_MULTIPATH]);
 
 	if (tb[RTA_PREF])
 		print_rt_pref(fp, rta_getattr_u8(tb[RTA_PREF]));
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next 9/9] iproute: refactor printing of interface
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (7 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 8/9] iproute: refactor multipath print Stephen Hemminger
@ 2018-02-07 17:10 ` Stephen Hemminger
  2018-02-08  0:14 ` [PATCH iproute2-next 0/9] print refactoring David Ahern
  9 siblings, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2018-02-07 17:10 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, Stephen Hemminger, Stephen Hemminger

For JSON and colorization, make common code a function.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iproute.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index c9139bf66bd2..91d2b1a61993 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -382,6 +382,14 @@ static void print_rt_pref(FILE *fp, unsigned int pref)
 	}
 }
 
+static void print_rta_if(FILE *fp, const struct rtattr *rta,
+			 const char *prefix)
+{
+	const char *ifname = ll_index_to_name(rta_getattr_u32(rta));
+
+	fprintf(fp, "%s %s ", prefix, ifname);
+}
+
 static void print_cache_flags(FILE *fp, __u32 flags)
 {
 	flags &= ~0xFFFF;
@@ -710,7 +718,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		print_rta_via(fp, tb[RTA_VIA]);
 
 	if (tb[RTA_OIF] && filter.oifmask != -1)
-		fprintf(fp, "dev %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_OIF])));
+		print_rta_if(fp,  tb[RTA_OIF], "dev");
 
 	if (table && (table != RT_TABLE_MAIN || show_details > 0) && !filter.tb)
 		fprintf(fp, "table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
@@ -767,10 +775,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if (tb[RTA_METRICS])
 		print_rta_metrics(fp, tb[RTA_METRICS]);
 
-	if (tb[RTA_IIF] && filter.iifmask != -1) {
-		fprintf(fp, "iif %s ",
-			ll_index_to_name(rta_getattr_u32(tb[RTA_IIF])));
-	}
+	if (tb[RTA_IIF] && filter.iifmask != -1)
+		print_rta_if(fp, tb[RTA_IIF], "iif");
 
 	if (tb[RTA_MULTIPATH])
 		print_rta_multipath(fp, r, tb[RTA_MULTIPATH]);
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next 0/9] print refactoring
  2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
                   ` (8 preceding siblings ...)
  2018-02-07 17:10 ` [PATCH iproute2-next 9/9] iproute: refactor printing of interface Stephen Hemminger
@ 2018-02-08  0:14 ` David Ahern
  9 siblings, 0 replies; 11+ messages in thread
From: David Ahern @ 2018-02-08  0:14 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Stephen Hemminger

On 2/7/18 10:10 AM, Stephen Hemminger wrote:
> This patch set breaks up the big print_route function into
> smaller pieces for readability and to make later changes
> to support JSON and color output easier.
> 
> Stephen Hemminger (9):
>   iproute: refactor printing flags
>   iproute: make printing icmpv6 a function
>   iproute: make printing IPv4 cache flags a function
>   iproute: refactor cacheinfo printing
>   iproute: refactor metrics print
>   iproute: refactor printing flow info
>   iproute: refactor newdst, gateway and via printing
>   iproute: refactor multipath print
>   iproute: refactor printing of interface
> 
>  ip/iproute.c | 571 +++++++++++++++++++++++++++++++----------------------------
>  1 file changed, 297 insertions(+), 274 deletions(-)
> 


series applied to iproute2-next.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-02-08  0:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-07 17:10 [PATCH iproute2-next 0/9] print refactoring Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 1/9] iproute: refactor printing flags Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 2/9] iproute: make printing icmpv6 a function Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 3/9] iproute: make printing IPv4 cache flags " Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 4/9] iproute: refactor cacheinfo printing Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 5/9] iproute: refactor metrics print Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 6/9] iproute: refactor printing flow info Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 7/9] iproute: refactor newdst, gateway and via printing Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 8/9] iproute: refactor multipath print Stephen Hemminger
2018-02-07 17:10 ` [PATCH iproute2-next 9/9] iproute: refactor printing of interface Stephen Hemminger
2018-02-08  0:14 ` [PATCH iproute2-next 0/9] print refactoring David Ahern

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.