Blame SOURCES/0085-bridge-mdb-add-support-for-extended-router-port-info.patch

4aca6e
From 90e24d0fe6dc4f5f4b5e6d75322e604c63f1cb14 Mon Sep 17 00:00:00 2001
4aca6e
From: Phil Sutter <psutter@redhat.com>
4aca6e
Date: Tue, 28 Feb 2017 16:12:38 +0100
4aca6e
Subject: [PATCH] bridge: mdb: add support for extended router port information
4aca6e
4aca6e
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1417289
4aca6e
Upstream Status: iproute2.git commit ba0372670d1fa
4aca6e
4aca6e
commit ba0372670d1fad0ae6cdbf970000ac7f4f72030f
4aca6e
Author: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
4aca6e
Date:   Mon Mar 14 11:04:46 2016 +0100
4aca6e
4aca6e
    bridge: mdb: add support for extended router port information
4aca6e
4aca6e
    Recently a new temp router port mode was added and with it the dumped
4aca6e
    information was extended similar to how mdb entries were done. This
4aca6e
    patch adds support to dump the new information by using the "-s" switch.
4aca6e
    Example:
4aca6e
    $ bridge -d -s mdb show
4aca6e
    dev br0 port eth1 grp ff02::1:ffbf:5716 temp 234.39
4aca6e
    dev br0 port eth1 grp 239.0.0.2 temp  97.17
4aca6e
    dev br0 port eth1 grp 239.0.0.3 temp 105.36
4aca6e
    router ports on br0: eth1    0.00 permanent
4aca6e
    router ports on br0: eth2  254.87 temp
4aca6e
4aca6e
    It also updates the bridge man page.
4aca6e
4aca6e
    Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
4aca6e
---
4aca6e
 bridge/br_common.h |  3 +++
4aca6e
 bridge/mdb.c       | 53 ++++++++++++++++++++++++++++++++++++++++++++---------
4aca6e
 man/man8/bridge.8  |  6 +++++-
4aca6e
 3 files changed, 52 insertions(+), 10 deletions(-)
4aca6e
4aca6e
diff --git a/bridge/br_common.h b/bridge/br_common.h
4aca6e
index 41eb0dc..5ea45c9 100644
4aca6e
--- a/bridge/br_common.h
4aca6e
+++ b/bridge/br_common.h
4aca6e
@@ -1,6 +1,9 @@
4aca6e
 #define MDB_RTA(r) \
4aca6e
 		((struct rtattr *)(((char *)(r)) + RTA_ALIGN(sizeof(struct br_mdb_entry))))
4aca6e
 
4aca6e
+#define MDB_RTR_RTA(r) \
4aca6e
+		((struct rtattr *)(((char *)(r)) + RTA_ALIGN(sizeof(__u32))))
4aca6e
+
4aca6e
 extern int print_linkinfo(const struct sockaddr_nl *who,
4aca6e
 			  struct nlmsghdr *n,
4aca6e
 			  void *arg);
4aca6e
diff --git a/bridge/mdb.c b/bridge/mdb.c
4aca6e
index 600596c..97da4dc 100644
4aca6e
--- a/bridge/mdb.c
4aca6e
+++ b/bridge/mdb.c
4aca6e
@@ -33,19 +33,56 @@ static void usage(void)
4aca6e
 	exit(-1);
4aca6e
 }
4aca6e
 
4aca6e
-static void br_print_router_ports(FILE *f, struct rtattr *attr)
4aca6e
+static bool is_temp_mcast_rtr(__u8 type)
4aca6e
+{
4aca6e
+	return type == MDB_RTR_TYPE_TEMP_QUERY || type == MDB_RTR_TYPE_TEMP;
4aca6e
+}
4aca6e
+
4aca6e
+static void __print_router_port_stats(FILE *f, struct rtattr *pattr)
4aca6e
+{
4aca6e
+	struct rtattr *tb[MDBA_ROUTER_PATTR_MAX + 1];
4aca6e
+	struct timeval tv;
4aca6e
+	__u8 type;
4aca6e
+
4aca6e
+	parse_rtattr(tb, MDBA_ROUTER_PATTR_MAX, MDB_RTR_RTA(RTA_DATA(pattr)),
4aca6e
+		     RTA_PAYLOAD(pattr) - RTA_ALIGN(sizeof(uint32_t)));
4aca6e
+	if (tb[MDBA_ROUTER_PATTR_TIMER]) {
4aca6e
+		__jiffies_to_tv(&tv,
4aca6e
+				rta_getattr_u32(tb[MDBA_ROUTER_PATTR_TIMER]));
4aca6e
+		fprintf(f, " %4i.%.2i",
4aca6e
+			(int)tv.tv_sec, (int)tv.tv_usec/10000);
4aca6e
+	}
4aca6e
+	if (tb[MDBA_ROUTER_PATTR_TYPE]) {
4aca6e
+		type = rta_getattr_u8(tb[MDBA_ROUTER_PATTR_TYPE]);
4aca6e
+		fprintf(f, " %s",
4aca6e
+			is_temp_mcast_rtr(type) ? "temp" : "permanent");
4aca6e
+	}
4aca6e
+}
4aca6e
+
4aca6e
+static void br_print_router_ports(FILE *f, struct rtattr *attr, __u32 brifidx)
4aca6e
 {
4aca6e
 	uint32_t *port_ifindex;
4aca6e
 	struct rtattr *i;
4aca6e
 	int rem;
4aca6e
 
4aca6e
+	if (!show_stats)
4aca6e
+		fprintf(f, "router ports on %s: ", ll_index_to_name(brifidx));
4aca6e
+
4aca6e
 	rem = RTA_PAYLOAD(attr);
4aca6e
 	for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
4aca6e
 		port_ifindex = RTA_DATA(i);
4aca6e
-		fprintf(f, "%s ", ll_index_to_name(*port_ifindex));
4aca6e
+		if (show_stats) {
4aca6e
+			fprintf(f, "router ports on %s: %s",
4aca6e
+				ll_index_to_name(brifidx),
4aca6e
+				ll_index_to_name(*port_ifindex));
4aca6e
+			__print_router_port_stats(f, i);
4aca6e
+			fprintf(f, "\n");
4aca6e
+		} else {
4aca6e
+			fprintf(f, "%s ", ll_index_to_name(*port_ifindex));
4aca6e
+		}
4aca6e
 	}
4aca6e
-
4aca6e
-	fprintf(f, "\n");
4aca6e
+	if (!show_stats)
4aca6e
+		fprintf(f, "\n");
4aca6e
 }
4aca6e
 
4aca6e
 static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
4aca6e
@@ -127,11 +164,9 @@ int print_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
4aca6e
 
4aca6e
 	if (tb[MDBA_ROUTER]) {
4aca6e
 		if (n->nlmsg_type == RTM_GETMDB) {
4aca6e
-			if (show_details) {
4aca6e
-				fprintf(fp, "router ports on %s: ",
4aca6e
-					ll_index_to_name(r->ifindex));
4aca6e
-				br_print_router_ports(fp, tb[MDBA_ROUTER]);
4aca6e
-			}
4aca6e
+			if (show_details)
4aca6e
+				br_print_router_ports(fp, tb[MDBA_ROUTER],
4aca6e
+						      r->ifindex);
4aca6e
 		} else {
4aca6e
 			uint32_t *port_ifindex;
4aca6e
 
4aca6e
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
4aca6e
index 08f327b..4d5d743 100644
4aca6e
--- a/man/man8/bridge.8
4aca6e
+++ b/man/man8/bridge.8
4aca6e
@@ -119,6 +119,10 @@ is given multiple times, the amount of information increases.
4aca6e
 As a rule, the information is statistics or some time values.
4aca6e
 
4aca6e
 .TP
4aca6e
+.BR "\-d" , " \-details"
4aca6e
+print detailed information about MDB router ports.
4aca6e
+
4aca6e
+.TP
4aca6e
 .BR "\-n" , " \-net" , " \-netns " <NETNS>
4aca6e
 switches
4aca6e
 .B bridge
4aca6e
@@ -506,7 +510,7 @@ a connected router.
4aca6e
 .PP
4aca6e
 With the
4aca6e
 .B -statistics
4aca6e
-option, the command displays timer values for mdb entries.
4aca6e
+option, the command displays timer values for mdb and router port entries.
4aca6e
 
4aca6e
 .SH bridge vlan - VLAN filter list
4aca6e
 
4aca6e
-- 
4aca6e
1.8.3.1
4aca6e