diff mbox series

[iproute2-next,v2,19/19] bridge: vlan: add support for dumping router ports

Message ID 20210828110805.463429-20-razor@blackwall.org (mailing list archive)
State Accepted
Delegated to: David Ahern
Headers show
Series bridge: vlan: add global multicast options | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Nikolay Aleksandrov Aug. 28, 2021, 11:08 a.m. UTC
From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add dump support for vlan multicast router ports and their details if
requested. If details are requested we print 1 entry per line, otherwise
we print all router ports on a single line similar to how mdb prints
them.

Looks like:
$ bridge vlan global show vid 100
 port              vlan-id
 bridge            100
                     mcast_snooping 1 mcast_querier 0 mcast_igmp_version 2 mcast_mld_version 1 mcast_last_member_count 2 mcast_last_member_interval 100 mcast_startup_query_count 2 mcast_startup_query_interval 3125 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000
                     router ports: ens20 ens16

Looks like (with -s):
 $ bridge -s vlan global show vid 100
 port              vlan-id
 bridge            100
                     mcast_snooping 1 mcast_querier 0 mcast_igmp_version 2 mcast_mld_version 1 mcast_last_member_count 2 mcast_last_member_interval 100 mcast_startup_query_count 2 mcast_startup_query_interval 3125 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000
                     router ports: ens20   187.57 temp
                                   ens16   118.27 temp

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
 bridge/br_common.h |  1 +
 bridge/mdb.c       |  6 +++---
 bridge/vlan.c      | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/bridge/br_common.h b/bridge/br_common.h
index 09f42c814918..610e83f65603 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -14,6 +14,7 @@  void print_stp_state(__u8 state);
 int parse_stp_state(const char *arg);
 int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor,
 		   bool global_only);
+void br_print_router_port_stats(struct rtattr *pattr);
 
 int do_fdb(int argc, char **argv);
 int do_mdb(int argc, char **argv);
diff --git a/bridge/mdb.c b/bridge/mdb.c
index b427d878677f..7b5863d31c46 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -59,7 +59,7 @@  static const char *format_timer(__u32 ticks, int align)
 	return tbuf;
 }
 
-static void __print_router_port_stats(FILE *f, struct rtattr *pattr)
+void br_print_router_port_stats(struct rtattr *pattr)
 {
 	struct rtattr *tb[MDBA_ROUTER_PATTR_MAX + 1];
 
@@ -101,13 +101,13 @@  static void br_print_router_ports(FILE *f, struct rtattr *attr,
 			print_string(PRINT_JSON, "port", NULL, port_ifname);
 
 			if (show_stats)
-				__print_router_port_stats(f, i);
+				br_print_router_port_stats(i);
 			close_json_object();
 		} else if (show_stats) {
 			fprintf(f, "router ports on %s: %s",
 				brifname, port_ifname);
 
-			__print_router_port_stats(f, i);
+			br_print_router_port_stats(i);
 			fprintf(f, "\n");
 		} else {
 			fprintf(f, "%s ", port_ifname);
diff --git a/bridge/vlan.c b/bridge/vlan.c
index afb5186d36de..bf3b440fa1b4 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -803,6 +803,36 @@  static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 	return 0;
 }
 
+static void print_vlan_router_ports(struct rtattr *rattr)
+{
+	int rem = RTA_PAYLOAD(rattr);
+	struct rtattr *i;
+
+	print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s    ", "");
+	open_json_array(PRINT_ANY, is_json_context() ? "router_ports" :
+						       "router ports: ");
+	for (i = RTA_DATA(rattr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+		uint32_t *port_ifindex = RTA_DATA(i);
+		const char *port_ifname = ll_index_to_name(*port_ifindex);
+
+		open_json_object(NULL);
+		if (show_stats && i != RTA_DATA(rattr)) {
+			print_nl();
+			/* start: IFNAMSIZ + 4 + strlen("router ports: ") */
+			print_string(PRINT_FP, NULL,
+				     "%-" __stringify(IFNAMSIZ) "s    "
+				     "              ",
+				     "");
+		}
+		print_string(PRINT_ANY, "port", "%s ", port_ifname);
+		if (show_stats)
+			br_print_router_port_stats(i);
+		close_json_object();
+	}
+	close_json_array(PRINT_JSON, NULL);
+	print_nl();
+}
+
 static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 {
 	struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1], *vattr;
@@ -902,6 +932,10 @@  static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			     rta_getattr_u64(vattr));
 	}
 	print_nl();
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]) {
+		vattr = RTA_DATA(vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]);
+		print_vlan_router_ports(vattr);
+	}
 	close_json_object();
 }