All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options
@ 2021-08-28 11:07 Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 01/19] ip: bridge: add support for mcast_vlan_snooping Nikolay Aleksandrov
                   ` (18 more replies)
  0 siblings, 19 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Hi all,
This set adds support for vlan multicast options. The feature is
globally controlled by a new bridge option called mcast_vlan_snooping
which is added by patch 01. Then patches 2-5 add support for dumping
global vlan options and filtering on vlan id. Patch 06 adds support for
setting global vlan options and then patches 07-18 add all the new
global vlan options, finally patch 19 adds support for dumping vlan
multicast router ports. These options are identical in meaning, names and
functionality as the bridge-wide ones.

All the new vlan global commands are under the global keyword:
 $ bridge vlan global show [ vid VID dev DEVICE ]
 $ bridge vlan global set vid VID dev DEVICE ...

I've added command examples in each commit message. The patch-set is a
bit bigger but the global options follow the same pattern so I don't see
a point in breaking them. All man page descriptions have been taken from
the same current bridge-wide mcast options. The only additional iproute2
change which is left to do is the per-vlan mcast router control which
I'll send separately. Note to properly use this set you'll need the
updated kernel headers where mcast router was moved from a global option
to per-vlan/per-device one (changed uapi enum which was in net-next).

Example:
 # enable vlan mcast snooping globally
 $ ip link set dev bridge type bridge mcast_vlan_snooping 1
 # enable mcast querier on vlan 100
 $ bridge vlan global set dev bridge vid 100 mcast_querier 1
 # show vlan 100's global options
 $ bridge -s vlan global show vid 100
port              vlan-id
bridge            100
                    mcast_snooping 1 mcast_querier 1 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

A following kernel patch-set will add selftests which use these commands.

v2: all patches use strcmp instead of matches
    patches 02, 03 which prepare print_vlan_rtm for global show are new
    previous patch 02 is split in patches 02, 03 and 04
    patches 07-18 have their help msg alignment adjusted to fit in 100
    characters

Thanks,
 Nik


Nikolay Aleksandrov (19):
  ip: bridge: add support for mcast_vlan_snooping
  bridge: vlan: factor out vlan option printing
  bridge: vlan: skip unknown attributes when printing options
  bridge: vlan: add support to show global vlan options
  bridge: vlan: add support for vlan filtering when dumping options
  bridge: vlan: add support to set global vlan options
  bridge: vlan: add global mcast_snooping option
  bridge: vlan: add global mcast_igmp_version option
  bridge: vlan: add global mcast_mld_version option
  bridge: vlan: add global mcast_last_member_count option
  bridge: vlan: add global mcast_startup_query_count option
  bridge: vlan: add global mcast_last_member_interval option
  bridge: vlan: add global mcast_membership_interval option
  bridge: vlan: add global mcast_querier_interval option
  bridge: vlan: add global mcast_query_interval option
  bridge: vlan: add global mcast_query_response_interval option
  bridge: vlan: add global mcast_startup_query_interval option
  bridge: vlan: add global mcast_querier option
  bridge: vlan: add support for dumping router ports

 bridge/br_common.h    |   4 +-
 bridge/mdb.c          |   6 +-
 bridge/monitor.c      |   2 +-
 bridge/vlan.c         | 547 +++++++++++++++++++++++++++++++++++++-----
 ip/iplink_bridge.c    |  29 +++
 man/man8/bridge.8     | 130 ++++++++++
 man/man8/ip-link.8.in |   8 +
 7 files changed, 660 insertions(+), 66 deletions(-)

-- 
2.31.1


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

* [PATCH iproute2-next v2 01/19] ip: bridge: add support for mcast_vlan_snooping
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 02/19] bridge: vlan: factor out vlan option printing Nikolay Aleksandrov
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add support for mcast_vlan_snooping option which controls per-vlan
multicast snooping, also update the man page.
Syntax: $ ip link set dev bridge type bridge mcast_vlan_snooping 0/1

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: use strcmp instead of matches for option name matching

 ip/iplink_bridge.c    | 29 +++++++++++++++++++++++++++++
 man/man8/ip-link.8.in |  8 ++++++++
 2 files changed, 37 insertions(+)

diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index d12fd0558f7d..c2e63f6e0fcf 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -43,6 +43,7 @@ static void print_explain(FILE *f)
 		"		  [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
 		"		  [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
 		"		  [ mcast_snooping MULTICAST_SNOOPING ]\n"
+		"		  [ mcast_vlan_snooping MULTICAST_VLAN_SNOOPING ]\n"
 		"		  [ mcast_router MULTICAST_ROUTER ]\n"
 		"		  [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n"
 		"		  [ mcast_querier MULTICAST_QUERIER ]\n"
@@ -83,6 +84,7 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
 static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
 			    struct nlmsghdr *n)
 {
+	struct br_boolopt_multi bm = {};
 	__u32 val;
 
 	while (argc > 0) {
@@ -200,6 +202,18 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
 				invarg("invalid mcast_snooping", *argv);
 
 			addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
+		} else if (strcmp(*argv, "mcast_vlan_snooping") == 0) {
+			__u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
+			__u8 mcast_vlan_snooping;
+
+			NEXT_ARG();
+			if (get_u8(&mcast_vlan_snooping, *argv, 0))
+				invarg("invalid mcast_vlan_snooping", *argv);
+			bm.optmask |= 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
+			if (mcast_vlan_snooping)
+				bm.optval |= mcvl_bit;
+			else
+				bm.optval &= ~mcvl_bit;
 		} else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
 			__u8 mcast_qui;
 
@@ -379,6 +393,9 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
 		argc--, argv++;
 	}
 
+	if (bm.optmask)
+		addattr_l(n, 1024, IFLA_BR_MULTI_BOOLOPT,
+			  &bm, sizeof(bm));
 	return 0;
 }
 
@@ -559,6 +576,18 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 			   "mcast_snooping %u ",
 			   rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
 
+	if (tb[IFLA_BR_MULTI_BOOLOPT]) {
+		__u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
+		struct br_boolopt_multi *bm;
+
+		bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]);
+		if (bm->optmask & mcvl_bit)
+			print_uint(PRINT_ANY,
+				   "mcast_vlan_snooping",
+				   "mcast_vlan_snooping %u ",
+				    !!(bm->optval & mcvl_bit));
+	}
+
 	if (tb[IFLA_BR_MCAST_ROUTER])
 		print_uint(PRINT_ANY,
 			   "mcast_router",
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 572bed872eed..2c278d53c050 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1492,6 +1492,8 @@ the following additional arguments are supported:
 ] [
 .BI mcast_snooping " MULTICAST_SNOOPING "
 ] [
+.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
+] [
 .BI mcast_router " MULTICAST_ROUTER "
 ] [
 .BI mcast_query_use_ifaddr " MCAST_QUERY_USE_IFADDR "
@@ -1614,6 +1616,12 @@ per-VLAN per-port stats accounting. Can be changed only when there are no port V
 or off
 .RI ( MULTICAST_SNOOPING " == 0). "
 
+.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
+- turn multicast VLAN snooping on
+.RI ( MULTICAST_VLAN_SNOOPING " > 0) "
+or off
+.RI ( MULTICAST_VLAN_SNOOPING " == 0). "
+
 .BI mcast_router " MULTICAST_ROUTER "
 - set bridge's multicast router if IGMP snooping is enabled.
 .I MULTICAST_ROUTER
-- 
2.31.1


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

* [PATCH iproute2-next v2 02/19] bridge: vlan: factor out vlan option printing
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 01/19] ip: bridge: add support for mcast_vlan_snooping Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 03/19] bridge: vlan: skip unknown attributes when printing options Nikolay Aleksandrov
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Factor out the code which prints current per-vlan options from
print_vlan_rtm without any changes, later we'll filter based on the vlan
attribute and add support for global vlan option printing.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: new patch (split off of previous patch 02)

 bridge/vlan.c | 110 ++++++++++++++++++++++++++------------------------
 1 file changed, 58 insertions(+), 52 deletions(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 9b6511f189ff..b9d928010cb4 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -621,11 +621,67 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 	return 0;
 }
 
+static void print_vlan_opts(struct rtattr *a)
+{
+	struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1];
+	struct bridge_vlan_xstats vstats;
+	struct bridge_vlan_info *vinfo;
+	__u16 vrange = 0;
+	__u8 state = 0;
+
+	parse_rtattr_flags(vtb, BRIDGE_VLANDB_ENTRY_MAX, RTA_DATA(a),
+			   RTA_PAYLOAD(a), NLA_F_NESTED);
+	vinfo = RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_INFO]);
+
+	memset(&vstats, 0, sizeof(vstats));
+	if (vtb[BRIDGE_VLANDB_ENTRY_RANGE])
+		vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_ENTRY_RANGE]);
+	else
+		vrange = vinfo->vid;
+
+	if (vtb[BRIDGE_VLANDB_ENTRY_STATE])
+		state = rta_getattr_u8(vtb[BRIDGE_VLANDB_ENTRY_STATE]);
+
+	if (vtb[BRIDGE_VLANDB_ENTRY_STATS]) {
+		struct rtattr *stb[BRIDGE_VLANDB_STATS_MAX+1];
+		struct rtattr *attr;
+
+		attr = vtb[BRIDGE_VLANDB_ENTRY_STATS];
+		parse_rtattr(stb, BRIDGE_VLANDB_STATS_MAX, RTA_DATA(attr),
+			     RTA_PAYLOAD(attr));
+
+		if (stb[BRIDGE_VLANDB_STATS_RX_BYTES]) {
+			attr = stb[BRIDGE_VLANDB_STATS_RX_BYTES];
+			vstats.rx_bytes = rta_getattr_u64(attr);
+		}
+		if (stb[BRIDGE_VLANDB_STATS_RX_PACKETS]) {
+			attr = stb[BRIDGE_VLANDB_STATS_RX_PACKETS];
+			vstats.rx_packets = rta_getattr_u64(attr);
+		}
+		if (stb[BRIDGE_VLANDB_STATS_TX_PACKETS]) {
+			attr = stb[BRIDGE_VLANDB_STATS_TX_PACKETS];
+			vstats.tx_packets = rta_getattr_u64(attr);
+		}
+		if (stb[BRIDGE_VLANDB_STATS_TX_BYTES]) {
+			attr = stb[BRIDGE_VLANDB_STATS_TX_BYTES];
+			vstats.tx_bytes = rta_getattr_u64(attr);
+		}
+	}
+	print_range("vlan", vinfo->vid, vrange);
+	print_vlan_flags(vinfo->flags);
+	print_nl();
+	print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s    ", "");
+	print_stp_state(state);
+	print_nl();
+	if (show_stats)
+		__print_one_vlan_stats(&vstats);
+}
+
 int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 {
-	struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1], *a;
 	struct br_vlan_msg *bvm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
+	struct rtattr *a;
 	int rem;
 
 	if (n->nlmsg_type != RTM_NEWVLAN && n->nlmsg_type != RTM_DELVLAN &&
@@ -660,49 +716,6 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 
 	rem = len;
 	for (a = BRVLAN_RTA(bvm); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) {
-		struct bridge_vlan_xstats vstats;
-		struct bridge_vlan_info *vinfo;
-		__u32 vrange = 0;
-		__u8 state = 0;
-
-		parse_rtattr_flags(vtb, BRIDGE_VLANDB_ENTRY_MAX, RTA_DATA(a),
-				   RTA_PAYLOAD(a), NLA_F_NESTED);
-		vinfo = RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_INFO]);
-
-		memset(&vstats, 0, sizeof(vstats));
-		if (vtb[BRIDGE_VLANDB_ENTRY_RANGE])
-			vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_ENTRY_RANGE]);
-		else
-			vrange = vinfo->vid;
-
-		if (vtb[BRIDGE_VLANDB_ENTRY_STATE])
-			state = rta_getattr_u8(vtb[BRIDGE_VLANDB_ENTRY_STATE]);
-
-		if (vtb[BRIDGE_VLANDB_ENTRY_STATS]) {
-			struct rtattr *stb[BRIDGE_VLANDB_STATS_MAX+1];
-			struct rtattr *attr;
-
-			attr = vtb[BRIDGE_VLANDB_ENTRY_STATS];
-			parse_rtattr(stb, BRIDGE_VLANDB_STATS_MAX, RTA_DATA(attr),
-				     RTA_PAYLOAD(attr));
-
-			if (stb[BRIDGE_VLANDB_STATS_RX_BYTES]) {
-				attr = stb[BRIDGE_VLANDB_STATS_RX_BYTES];
-				vstats.rx_bytes = rta_getattr_u64(attr);
-			}
-			if (stb[BRIDGE_VLANDB_STATS_RX_PACKETS]) {
-				attr = stb[BRIDGE_VLANDB_STATS_RX_PACKETS];
-				vstats.rx_packets = rta_getattr_u64(attr);
-			}
-			if (stb[BRIDGE_VLANDB_STATS_TX_PACKETS]) {
-				attr = stb[BRIDGE_VLANDB_STATS_TX_PACKETS];
-				vstats.tx_packets = rta_getattr_u64(attr);
-			}
-			if (stb[BRIDGE_VLANDB_STATS_TX_BYTES]) {
-				attr = stb[BRIDGE_VLANDB_STATS_TX_BYTES];
-				vstats.tx_bytes = rta_getattr_u64(attr);
-			}
-		}
 		if (vlan_rtm_cur_ifidx != bvm->ifindex) {
 			open_vlan_port(bvm->ifindex, VLAN_SHOW_VLAN);
 			open_json_object(NULL);
@@ -711,14 +724,7 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 			open_json_object(NULL);
 			print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s  ", "");
 		}
-		print_range("vlan", vinfo->vid, vrange);
-		print_vlan_flags(vinfo->flags);
-		print_nl();
-		print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s    ", "");
-		print_stp_state(state);
-		print_nl();
-		if (show_stats)
-			__print_one_vlan_stats(&vstats);
+		print_vlan_opts(a);
 		close_json_object();
 	}
 
-- 
2.31.1


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

* [PATCH iproute2-next v2 03/19] bridge: vlan: skip unknown attributes when printing options
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 01/19] ip: bridge: add support for mcast_vlan_snooping Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 02/19] bridge: vlan: factor out vlan option printing Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 04/19] bridge: vlan: add support to show global vlan options Nikolay Aleksandrov
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Skip unknown attributes when printing vlan options in print_vlan_rtm.
Make sure print_vlan_opts doesn't accept attributes it doesn't understand.
Currently we print only one type, later global vlan options support will
be added.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: new patch, split off of previous patch 02

 bridge/vlan.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index b9d928010cb4..7e4254283373 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -629,6 +629,9 @@ static void print_vlan_opts(struct rtattr *a)
 	__u16 vrange = 0;
 	__u8 state = 0;
 
+	if ((a->rta_type & NLA_TYPE_MASK) != BRIDGE_VLANDB_ENTRY)
+		return;
+
 	parse_rtattr_flags(vtb, BRIDGE_VLANDB_ENTRY_MAX, RTA_DATA(a),
 			   RTA_PAYLOAD(a), NLA_F_NESTED);
 	vinfo = RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_INFO]);
@@ -716,6 +719,12 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 
 	rem = len;
 	for (a = BRVLAN_RTA(bvm); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) {
+		unsigned short rta_type = a->rta_type & NLA_TYPE_MASK;
+
+		/* skip unknown attributes */
+		if (rta_type > BRIDGE_VLANDB_MAX)
+			continue;
+
 		if (vlan_rtm_cur_ifidx != bvm->ifindex) {
 			open_vlan_port(bvm->ifindex, VLAN_SHOW_VLAN);
 			open_json_object(NULL);
@@ -724,7 +733,11 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 			open_json_object(NULL);
 			print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s  ", "");
 		}
-		print_vlan_opts(a);
+		switch (rta_type) {
+		case BRIDGE_VLANDB_ENTRY:
+			print_vlan_opts(a);
+			break;
+		}
 		close_json_object();
 	}
 
-- 
2.31.1


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

* [PATCH iproute2-next v2 04/19] bridge: vlan: add support to show global vlan options
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (2 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 03/19] bridge: vlan: skip unknown attributes when printing options Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 05/19] bridge: vlan: add support for vlan filtering when dumping options Nikolay Aleksandrov
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add support for new bridge vlan command grouping called global which
operates on global options. The first command it supports is "show".
To do that we update print_vlan_rtm to recognize the global vlan options
attribute and parse it properly.
Man page and help are also updated with the new command.

Syntax is: $ bridge vlan global show [ vid VID ] [ dev DEV ]

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: previously this was patch 02 which is now split in 02-04
    use strcmp instead of matches

 bridge/br_common.h |   3 +-
 bridge/monitor.c   |   2 +-
 bridge/vlan.c      | 110 +++++++++++++++++++++++++++++++++++++++++++--
 man/man8/bridge.8  |  21 +++++++++
 4 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/bridge/br_common.h b/bridge/br_common.h
index b9adafd98dea..09f42c814918 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -12,7 +12,8 @@ int print_mdb_mon(struct nlmsghdr *n, void *arg);
 int print_fdb(struct nlmsghdr *n, void *arg);
 void print_stp_state(__u8 state);
 int parse_stp_state(const char *arg);
-int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor);
+int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor,
+		   bool global_only);
 
 int do_fdb(int argc, char **argv);
 int do_mdb(int argc, char **argv);
diff --git a/bridge/monitor.c b/bridge/monitor.c
index 88f52f52f084..845e221abb49 100644
--- a/bridge/monitor.c
+++ b/bridge/monitor.c
@@ -71,7 +71,7 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl,
 	case RTM_DELVLAN:
 		if (prefix_banner)
 			fprintf(fp, "[VLAN]");
-		return print_vlan_rtm(n, arg, true);
+		return print_vlan_rtm(n, arg, true, false);
 
 	default:
 		return 0;
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 7e4254283373..8a2cc306cb07 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -36,7 +36,8 @@ static void usage(void)
 		"                                                     [ self ] [ master ]\n"
 		"       bridge vlan { set } vid VLAN_ID dev DEV [ state STP_STATE ]\n"
 		"       bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
-		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n");
+		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
+		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
 
@@ -621,6 +622,25 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 	return 0;
 }
 
+static void print_vlan_global_opts(struct rtattr *a)
+{
+	struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1];
+	__u16 vid, vrange = 0;
+
+	if ((a->rta_type & NLA_TYPE_MASK) != BRIDGE_VLANDB_GLOBAL_OPTIONS)
+		return;
+
+	parse_rtattr_flags(vtb, BRIDGE_VLANDB_GOPTS_MAX, RTA_DATA(a),
+			   RTA_PAYLOAD(a), NLA_F_NESTED);
+	vid = rta_getattr_u16(vtb[BRIDGE_VLANDB_GOPTS_ID]);
+	if (vtb[BRIDGE_VLANDB_GOPTS_RANGE])
+		vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_GOPTS_RANGE]);
+	else
+		vrange = vid;
+	print_range("vlan", vid, vrange);
+	print_nl();
+}
+
 static void print_vlan_opts(struct rtattr *a)
 {
 	struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1];
@@ -680,7 +700,7 @@ static void print_vlan_opts(struct rtattr *a)
 		__print_one_vlan_stats(&vstats);
 }
 
-int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
+int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only)
 {
 	struct br_vlan_msg *bvm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
@@ -722,7 +742,8 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 		unsigned short rta_type = a->rta_type & NLA_TYPE_MASK;
 
 		/* skip unknown attributes */
-		if (rta_type > BRIDGE_VLANDB_MAX)
+		if (rta_type > BRIDGE_VLANDB_MAX ||
+		    (global_only && rta_type != BRIDGE_VLANDB_GLOBAL_OPTIONS))
 			continue;
 
 		if (vlan_rtm_cur_ifidx != bvm->ifindex) {
@@ -737,6 +758,9 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 		case BRIDGE_VLANDB_ENTRY:
 			print_vlan_opts(a);
 			break;
+		case BRIDGE_VLANDB_GLOBAL_OPTIONS:
+			print_vlan_global_opts(a);
+			break;
 		}
 		close_json_object();
 	}
@@ -746,7 +770,12 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor)
 
 static int print_vlan_rtm_filter(struct nlmsghdr *n, void *arg)
 {
-	return print_vlan_rtm(n, arg, false);
+	return print_vlan_rtm(n, arg, false, false);
+}
+
+static int print_vlan_rtm_global_filter(struct nlmsghdr *n, void *arg)
+{
+	return print_vlan_rtm(n, arg, false, true);
 }
 
 static int vlan_show(int argc, char **argv, int subject)
@@ -864,6 +893,61 @@ out:
 	return 0;
 }
 
+static int vlan_global_show(int argc, char **argv)
+{
+	__u32 dump_flags = BRIDGE_VLANDB_DUMPF_GLOBAL;
+	int ret = 0, subject = VLAN_SHOW_VLAN;
+	char *filter_dev = NULL;
+
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			if (filter_dev)
+				duparg("dev", *argv);
+			filter_dev = *argv;
+		} else if (strcmp(*argv, "vid") == 0) {
+			NEXT_ARG();
+			if (filter_vlan)
+				duparg("vid", *argv);
+			filter_vlan = atoi(*argv);
+		}
+		argc--; argv++;
+	}
+
+	if (filter_dev) {
+		filter_index = ll_name_to_index(filter_dev);
+		if (!filter_index)
+			return nodev(filter_dev);
+	}
+
+	new_json_obj(json);
+
+	if (rtnl_brvlandump_req(&rth, PF_BRIDGE, dump_flags) < 0) {
+		perror("Cannot send dump request");
+		exit(1);
+	}
+
+	if (!is_json_context()) {
+		printf("%-" __stringify(IFNAMSIZ) "s  %-"
+		       __stringify(VLAN_ID_LEN) "s", "port",
+		       "vlan-id");
+		printf("\n");
+	}
+
+	ret = rtnl_dump_filter(&rth, print_vlan_rtm_global_filter, &subject);
+	if (ret < 0) {
+		fprintf(stderr, "Dump terminated\n");
+		exit(1);
+	}
+
+	if (vlan_rtm_cur_ifidx != -1)
+		close_vlan_port();
+
+	delete_json_obj();
+	fflush(stdout);
+	return 0;
+}
+
 void print_vlan_info(struct rtattr *tb, int ifindex)
 {
 	struct rtattr *i, *list = tb;
@@ -908,6 +992,22 @@ void print_vlan_info(struct rtattr *tb, int ifindex)
 		close_vlan_port();
 }
 
+static int vlan_global(int argc, char **argv)
+{
+	if (argc > 0) {
+		if (strcmp(*argv, "show") == 0 ||
+		    strcmp(*argv, "lst") == 0 ||
+		    strcmp(*argv, "list") == 0)
+			return vlan_global_show(argc-1, argv+1);
+		else
+			usage();
+	} else {
+		return vlan_global_show(0, NULL);
+	}
+
+	return 0;
+}
+
 int do_vlan(int argc, char **argv)
 {
 	ll_init_map(&rth);
@@ -926,6 +1026,8 @@ int do_vlan(int argc, char **argv)
 		}
 		if (matches(*argv, "set") == 0)
 			return vlan_option_set(argc-1, argv+1);
+		if (strcmp(*argv, "global") == 0)
+			return vlan_global(argc-1, argv+1);
 		if (matches(*argv, "help") == 0)
 			usage();
 	} else {
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index eec7df4383bc..9ec4cb1dec67 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -152,6 +152,13 @@ bridge \- show / manipulate bridge addresses and devices
 .B dev
 .IR DEV " ]"
 
+.ti -8
+.BR "bridge vlan global" " [ " show " ] [ "
+.B dev
+.IR DEV " ] [ "
+.B vid
+.IR VID " ]"
+
 .ti -8
 .BR "bridge monitor" " [ " all " | " neigh " | " link " | " mdb " | " vlan " ]"
 
@@ -895,6 +902,20 @@ option, the command displays per-vlan traffic statistics.
 
 This command displays the current vlan tunnel info mapping.
 
+.SS bridge vlan global show - list global vlan options.
+
+This command displays the global VLAN options for each VLAN entry.
+
+.TP
+.BI dev " DEV"
+the interface only whose VLAN global options should be listed. Default is to list
+all bridge interfaces.
+
+.TP
+.BI vid " VID"
+the VLAN ID only whose global options should be listed. Default is to list
+all vlans.
+
 .SH bridge monitor - state monitoring
 
 The
-- 
2.31.1


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

* [PATCH iproute2-next v2 05/19] bridge: vlan: add support for vlan filtering when dumping options
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (3 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 04/19] bridge: vlan: add support to show global vlan options Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 06/19] bridge: vlan: add support to set global vlan options Nikolay Aleksandrov
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

In order to allow vlan filtering when dumping options we need to move
all print operations into the option dumping functions and add the
filtering after we've parsed the nested attributes so we can extract the
start and end vlan ids.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
 bridge/vlan.c | 43 ++++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 424fe8371733..69a1d3c295b6 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -622,7 +622,7 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 	return 0;
 }
 
-static void print_vlan_global_opts(struct rtattr *a)
+static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 {
 	struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1];
 	__u16 vid, vrange = 0;
@@ -637,11 +637,24 @@ static void print_vlan_global_opts(struct rtattr *a)
 		vrange = rta_getattr_u16(vtb[BRIDGE_VLANDB_GOPTS_RANGE]);
 	else
 		vrange = vid;
+
+	if (filter_vlan && (filter_vlan < vid || filter_vlan > vrange))
+		return;
+
+	if (vlan_rtm_cur_ifidx != ifindex) {
+		open_vlan_port(ifindex, VLAN_SHOW_VLAN);
+		open_json_object(NULL);
+		vlan_rtm_cur_ifidx = ifindex;
+	} else {
+		open_json_object(NULL);
+		print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s  ", "");
+	}
 	print_range("vlan", vid, vrange);
 	print_nl();
+	close_json_object();
 }
 
-static void print_vlan_opts(struct rtattr *a)
+static void print_vlan_opts(struct rtattr *a, int ifindex)
 {
 	struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1];
 	struct bridge_vlan_xstats vstats;
@@ -662,6 +675,9 @@ static void print_vlan_opts(struct rtattr *a)
 	else
 		vrange = vinfo->vid;
 
+	if (filter_vlan && (filter_vlan < vinfo->vid || filter_vlan > vrange))
+		return;
+
 	if (vtb[BRIDGE_VLANDB_ENTRY_STATE])
 		state = rta_getattr_u8(vtb[BRIDGE_VLANDB_ENTRY_STATE]);
 
@@ -690,6 +706,15 @@ static void print_vlan_opts(struct rtattr *a)
 			vstats.tx_bytes = rta_getattr_u64(attr);
 		}
 	}
+
+	if (vlan_rtm_cur_ifidx != ifindex) {
+		open_vlan_port(ifindex, VLAN_SHOW_VLAN);
+		open_json_object(NULL);
+		vlan_rtm_cur_ifidx = ifindex;
+	} else {
+		open_json_object(NULL);
+		print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s  ", "");
+	}
 	print_range("vlan", vinfo->vid, vrange);
 	print_vlan_flags(vinfo->flags);
 	print_nl();
@@ -698,6 +723,7 @@ static void print_vlan_opts(struct rtattr *a)
 	print_nl();
 	if (show_stats)
 		__print_one_vlan_stats(&vstats);
+	close_json_object();
 }
 
 int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only)
@@ -746,23 +772,14 @@ int print_vlan_rtm(struct nlmsghdr *n, void *arg, bool monitor, bool global_only
 		    (global_only && rta_type != BRIDGE_VLANDB_GLOBAL_OPTIONS))
 			continue;
 
-		if (vlan_rtm_cur_ifidx != bvm->ifindex) {
-			open_vlan_port(bvm->ifindex, VLAN_SHOW_VLAN);
-			open_json_object(NULL);
-			vlan_rtm_cur_ifidx = bvm->ifindex;
-		} else {
-			open_json_object(NULL);
-			print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s  ", "");
-		}
 		switch (rta_type) {
 		case BRIDGE_VLANDB_ENTRY:
-			print_vlan_opts(a);
+			print_vlan_opts(a, bvm->ifindex);
 			break;
 		case BRIDGE_VLANDB_GLOBAL_OPTIONS:
-			print_vlan_global_opts(a);
+			print_vlan_global_opts(a, bvm->ifindex);
 			break;
 		}
-		close_json_object();
 	}
 
 	return 0;
-- 
2.31.1


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

* [PATCH iproute2-next v2 06/19] bridge: vlan: add support to set global vlan options
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (4 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 05/19] bridge: vlan: add support for vlan filtering when dumping options Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option Nikolay Aleksandrov
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add support to change global vlan options via a new vlan global
set subcommand similar to the current vlan set subcommand. The man page
and help are updated accordingly. The command works only with bridge
devices. It doesn't support any options yet.

Syntax: $ bridge vlan global set vid VID dev DEV

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: use strcmp instead of matches

 bridge/vlan.c     | 80 +++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/bridge.8 | 20 ++++++++++++
 2 files changed, 100 insertions(+)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 77db90d8a617..c9b445bc65aa 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -37,6 +37,7 @@ static void usage(void)
 		"       bridge vlan { set } vid VLAN_ID dev DEV [ state STP_STATE ]\n"
 		"       bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
 		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
+		"       bridge vlan global { set } vid VLAN_ID dev DEV\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -338,6 +339,83 @@ static int vlan_option_set(int argc, char **argv)
 	return 0;
 }
 
+static int vlan_global_option_set(int argc, char **argv)
+{
+	struct {
+		struct nlmsghdr	n;
+		struct br_vlan_msg	bvm;
+		char			buf[1024];
+	} req = {
+		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_vlan_msg)),
+		.n.nlmsg_flags = NLM_F_REQUEST,
+		.n.nlmsg_type = RTM_NEWVLAN,
+		.bvm.family = PF_BRIDGE,
+	};
+	struct rtattr *afspec;
+	short vid_end = -1;
+	char *d = NULL;
+	short vid = -1;
+
+	afspec = addattr_nest(&req.n, sizeof(req),
+			      BRIDGE_VLANDB_GLOBAL_OPTIONS);
+	afspec->rta_type |= NLA_F_NESTED;
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			d = *argv;
+			req.bvm.ifindex = ll_name_to_index(d);
+			if (req.bvm.ifindex == 0) {
+				fprintf(stderr, "Cannot find network device \"%s\"\n",
+					d);
+				return -1;
+			}
+		} else if (strcmp(*argv, "vid") == 0) {
+			char *p;
+
+			NEXT_ARG();
+			p = strchr(*argv, '-');
+			if (p) {
+				*p = '\0';
+				p++;
+				vid = atoi(*argv);
+				vid_end = atoi(p);
+				if (vid >= vid_end || vid_end >= 4096) {
+					fprintf(stderr, "Invalid VLAN range \"%hu-%hu\"\n",
+						vid, vid_end);
+					return -1;
+				}
+			} else {
+				vid = atoi(*argv);
+			}
+			if (vid >= 4096) {
+				fprintf(stderr, "Invalid VLAN ID \"%hu\"\n",
+					vid);
+				return -1;
+			}
+			addattr16(&req.n, sizeof(req), BRIDGE_VLANDB_GOPTS_ID,
+				  vid);
+			if (vid_end != -1)
+				addattr16(&req.n, sizeof(req),
+					  BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
+		} else {
+			if (strcmp(*argv, "help") == 0)
+				NEXT_ARG();
+		}
+		argc--; argv++;
+	}
+	addattr_nest_end(&req.n, afspec);
+
+	if (d == NULL || vid == -1) {
+		fprintf(stderr, "Device and VLAN ID are required arguments.\n");
+		return -1;
+	}
+
+	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+		return -1;
+
+	return 0;
+}
+
 /* In order to use this function for both filtering and non-filtering cases
  * we need to make it a tristate:
  * return -1 - if filtering we've gone over so don't continue
@@ -1016,6 +1094,8 @@ static int vlan_global(int argc, char **argv)
 		    strcmp(*argv, "lst") == 0 ||
 		    strcmp(*argv, "list") == 0)
 			return vlan_global_show(argc-1, argv+1);
+		else if (strcmp(*argv, "set") == 0)
+			return vlan_global_option_set(argc-1, argv+1);
 		else
 			usage();
 	} else {
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 9ec4cb1dec67..796d20b662ab 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -152,6 +152,13 @@ bridge \- show / manipulate bridge addresses and devices
 .B dev
 .IR DEV " ]"
 
+.ti -8
+.BR "bridge vlan global set"
+.B dev
+.I DEV
+.B vid
+.IR VID " [ ]"
+
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
 .B dev
@@ -902,6 +909,19 @@ option, the command displays per-vlan traffic statistics.
 
 This command displays the current vlan tunnel info mapping.
 
+.SS bridge vlan global set - change vlan filter entry's global options
+
+This command changes vlan filter entry's global options.
+
+.TP
+.BI dev " NAME"
+the interface with which this vlan is associated. Only bridge devices are
+supported for global options.
+
+.TP
+.BI vid " VID"
+the VLAN ID that identifies the vlan.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (5 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 06/19] bridge: vlan: add support to set global vlan options Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-09-01  3:36   ` David Ahern
  2021-08-28 11:07 ` [PATCH iproute2-next v2 08/19] bridge: vlan: add global mcast_igmp_version option Nikolay Aleksandrov
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_snooping option which
controls if multicast snooping is enabled or disabled for a single vlan.
Syntax: $ bridge vlan global set dev bridge vid 1 mcast_snooping 1

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 18 +++++++++++++++++-
 man/man8/bridge.8 | 11 ++++++++++-
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 34fba0a5bdfb..b1a8cfc4a362 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -9,6 +9,7 @@
 #include <linux/if_bridge.h>
 #include <linux/if_ether.h>
 #include <string.h>
+#include <errno.h>
 
 #include "json_print.h"
 #include "libnetlink.h"
@@ -38,6 +39,7 @@ static void usage(void)
 		"       bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
 		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
 		"       bridge vlan global { set } vid VLAN_ID dev DEV\n"
+		"                      [ mcast_snooping MULTICAST_SNOOPING ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -355,6 +357,7 @@ static int vlan_global_option_set(int argc, char **argv)
 	short vid_end = -1;
 	char *d = NULL;
 	short vid = -1;
+	__u8 val8;
 
 	afspec = addattr_nest(&req.n, sizeof(req),
 			      BRIDGE_VLANDB_GLOBAL_OPTIONS);
@@ -397,6 +400,12 @@ static int vlan_global_option_set(int argc, char **argv)
 			if (vid_end != -1)
 				addattr16(&req.n, sizeof(req),
 					  BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
+		} else if (strcmp(*argv, "mcast_snooping") == 0) {
+			NEXT_ARG();
+			if (get_u8(&val8, *argv, 0))
+				invarg("invalid mcast_snooping", *argv);
+			addattr8(&req.n, 1024,
+				 BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -702,7 +711,7 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 
 static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 {
-	struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1];
+	struct rtattr *vtb[BRIDGE_VLANDB_GOPTS_MAX + 1], *vattr;
 	__u16 vid, vrange = 0;
 
 	if ((a->rta_type & NLA_TYPE_MASK) != BRIDGE_VLANDB_GLOBAL_OPTIONS)
@@ -729,6 +738,13 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 	}
 	print_range("vlan", vid, vrange);
 	print_nl();
+	print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s    ", "");
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING];
+		print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ",
+			   rta_getattr_u8(vattr));
+	}
+	print_nl();
 	close_json_object();
 }
 
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 796d20b662ab..d894289b2dc2 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -157,7 +157,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B dev
 .I DEV
 .B vid
-.IR VID " [ ]"
+.IR VID " [ "
+.B mcast_snooping
+.IR MULTICAST_SNOOPING " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -922,6 +924,13 @@ supported for global options.
 .BI vid " VID"
 the VLAN ID that identifies the vlan.
 
+.TP
+.BI mcast_snooping " MULTICAST_SNOOPING "
+turn multicast snooping for VLAN entry with VLAN ID on
+.RI ( MULTICAST_SNOOPING " > 0) "
+or off
+.RI ( MULTICAST_SNOOPING " == 0). Default is on. "
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 08/19] bridge: vlan: add global mcast_igmp_version option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (6 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 09/19] bridge: vlan: add global mcast_mld_version option Nikolay Aleksandrov
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_igmp_version option
which controls the IGMP version on the vlan (default 2).
Syntax: $ bridge vlan global set dev bridge vid 1 mcast_igmp_version 3

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 12 ++++++++++++
 man/man8/bridge.8 |  8 +++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index b1a8cfc4a362..5b97f4a167bd 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -40,6 +40,7 @@ static void usage(void)
 		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
 		"       bridge vlan global { set } vid VLAN_ID dev DEV\n"
 		"                      [ mcast_snooping MULTICAST_SNOOPING ]\n"
+		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -406,6 +407,12 @@ static int vlan_global_option_set(int argc, char **argv)
 				invarg("invalid mcast_snooping", *argv);
 			addattr8(&req.n, 1024,
 				 BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
+		} else if (strcmp(*argv, "mcast_igmp_version") == 0) {
+			NEXT_ARG();
+			if (get_u8(&val8, *argv, 0))
+				invarg("invalid mcast_igmp_version", *argv);
+			addattr8(&req.n, 1024,
+				 BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION, val8);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -744,6 +751,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 		print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ",
 			   rta_getattr_u8(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION];
+		print_uint(PRINT_ANY, "mcast_igmp_version",
+			   "mcast_igmp_version %u ", rta_getattr_u8(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index d894289b2dc2..224647b49843 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -159,7 +159,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B vid
 .IR VID " [ "
 .B mcast_snooping
-.IR MULTICAST_SNOOPING " ]"
+.IR MULTICAST_SNOOPING " ] [ "
+.B mcast_igmp_version
+.IR IGMP_VERSION " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -931,6 +933,10 @@ turn multicast snooping for VLAN entry with VLAN ID on
 or off
 .RI ( MULTICAST_SNOOPING " == 0). Default is on. "
 
+.TP
+.BI mcast_igmp_version " IGMP_VERSION "
+set the IGMP version. Default is 2.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 09/19] bridge: vlan: add global mcast_mld_version option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (7 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 08/19] bridge: vlan: add global mcast_igmp_version option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 10/19] bridge: vlan: add global mcast_last_member_count option Nikolay Aleksandrov
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_mld_version option
which controls the MLD version on the vlan (default 1).
Syntax: $ bridge vlan global set dev bridge vid 1 mcast_mld_version 2

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 12 ++++++++++++
 man/man8/bridge.8 |  8 +++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 5b97f4a167bd..aa6fbef27b06 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -41,6 +41,7 @@ static void usage(void)
 		"       bridge vlan global { set } vid VLAN_ID dev DEV\n"
 		"                      [ mcast_snooping MULTICAST_SNOOPING ]\n"
 		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
+		"                      [ mcast_mld_version MLD_VERSION ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -413,6 +414,12 @@ static int vlan_global_option_set(int argc, char **argv)
 				invarg("invalid mcast_igmp_version", *argv);
 			addattr8(&req.n, 1024,
 				 BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION, val8);
+		} else if (strcmp(*argv, "mcast_mld_version") == 0) {
+			NEXT_ARG();
+			if (get_u8(&val8, *argv, 0))
+				invarg("invalid mcast_mld_version", *argv);
+			addattr8(&req.n, 1024,
+				 BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION, val8);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -756,6 +763,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 		print_uint(PRINT_ANY, "mcast_igmp_version",
 			   "mcast_igmp_version %u ", rta_getattr_u8(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION];
+		print_uint(PRINT_ANY, "mcast_mld_version",
+			   "mcast_mld_version %u ", rta_getattr_u8(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 224647b49843..dcbff9367334 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -161,7 +161,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_snooping
 .IR MULTICAST_SNOOPING " ] [ "
 .B mcast_igmp_version
-.IR IGMP_VERSION " ]"
+.IR IGMP_VERSION " ] [ "
+.B mcast_mld_version
+.IR MLD_VERSION " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -937,6 +939,10 @@ or off
 .BI mcast_igmp_version " IGMP_VERSION "
 set the IGMP version. Default is 2.
 
+.TP
+.BI mcast_mld_version " MLD_VERSION "
+set the MLD version. Default is 1.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 10/19] bridge: vlan: add global mcast_last_member_count option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (8 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 09/19] bridge: vlan: add global mcast_mld_version option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 11/19] bridge: vlan: add global mcast_startup_query_count option Nikolay Aleksandrov
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_last_member_count option
which controls the number of queries the bridge will send on the vlan after
a leave is received (default 2).
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_last_member_count 10

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 | 10 +++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index aa6fbef27b06..479574ca38e5 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -42,6 +42,7 @@ static void usage(void)
 		"                      [ mcast_snooping MULTICAST_SNOOPING ]\n"
 		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
 		"                      [ mcast_mld_version MLD_VERSION ]\n"
+		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -359,6 +360,7 @@ static int vlan_global_option_set(int argc, char **argv)
 	short vid_end = -1;
 	char *d = NULL;
 	short vid = -1;
+	__u32 val32;
 	__u8 val8;
 
 	afspec = addattr_nest(&req.n, sizeof(req),
@@ -420,6 +422,13 @@ static int vlan_global_option_set(int argc, char **argv)
 				invarg("invalid mcast_mld_version", *argv);
 			addattr8(&req.n, 1024,
 				 BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION, val8);
+		} else if (strcmp(*argv, "mcast_last_member_count") == 0) {
+			NEXT_ARG();
+			if (get_u32(&val32, *argv, 0))
+				invarg("invalid mcast_last_member_count", *argv);
+			addattr32(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
+				  val32);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -768,6 +777,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 		print_uint(PRINT_ANY, "mcast_mld_version",
 			   "mcast_mld_version %u ", rta_getattr_u8(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT];
+		print_uint(PRINT_ANY, "mcast_last_member_count",
+			   "mcast_last_member_count %u ",
+			   rta_getattr_u32(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index dcbff9367334..cea755184336 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -163,7 +163,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_igmp_version
 .IR IGMP_VERSION " ] [ "
 .B mcast_mld_version
-.IR MLD_VERSION " ]"
+.IR MLD_VERSION " ] [ "
+.B mcast_last_member_count
+.IR LAST_MEMBER_COUNT " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -943,6 +945,12 @@ set the IGMP version. Default is 2.
 .BI mcast_mld_version " MLD_VERSION "
 set the MLD version. Default is 1.
 
+.TP
+.BI mcast_last_member_count " LAST_MEMBER_COUNT "
+set multicast last member count, ie the number of queries the bridge
+will send before stopping forwarding a multicast group after a "leave"
+message has been received. Default is 2.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 11/19] bridge: vlan: add global mcast_startup_query_count option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (9 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 10/19] bridge: vlan: add global mcast_last_member_count option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 12/19] bridge: vlan: add global mcast_last_member_interval option Nikolay Aleksandrov
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_startup_query_count
option which controls the number of queries the bridge will send on the
vlan during startup phase (default 2).
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_startup_query_count 5

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 |  8 +++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 479574ca38e5..2c6ebedd2d5f 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -43,6 +43,7 @@ static void usage(void)
 		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
 		"                      [ mcast_mld_version MLD_VERSION ]\n"
 		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
+		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -429,6 +430,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr32(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
 				  val32);
+		} else if (strcmp(*argv, "mcast_startup_query_count") == 0) {
+			NEXT_ARG();
+			if (get_u32(&val32, *argv, 0))
+				invarg("invalid mcast_startup_query_count",
+				       *argv);
+			addattr32(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
+				  val32);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -783,6 +792,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			   "mcast_last_member_count %u ",
 			   rta_getattr_u32(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT];
+		print_uint(PRINT_ANY, "mcast_startup_query_count",
+			   "mcast_startup_query_count %u ",
+			   rta_getattr_u32(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index cea755184336..7741382321cb 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -165,7 +165,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_mld_version
 .IR MLD_VERSION " ] [ "
 .B mcast_last_member_count
-.IR LAST_MEMBER_COUNT " ]"
+.IR LAST_MEMBER_COUNT " ] [ "
+.B mcast_startup_query_count
+.IR STARTUP_QUERY_COUNT " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -951,6 +953,10 @@ set multicast last member count, ie the number of queries the bridge
 will send before stopping forwarding a multicast group after a "leave"
 message has been received. Default is 2.
 
+.TP
+.BI mcast_startup_query_count " STARTUP_QUERY_COUNT "
+set the number of queries to send during startup phase. Default is 2.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 12/19] bridge: vlan: add global mcast_last_member_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (10 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 11/19] bridge: vlan: add global mcast_startup_query_count option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:07 ` [PATCH iproute2-next v2 13/19] bridge: vlan: add global mcast_membership_interval option Nikolay Aleksandrov
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_last_member_interval
option which controls the interval between queries to find remaining
members of a group after a leave message. To be consistent with the same
bridge-wide option the value is reported with USER_HZ granularity and
the same granularity is expected when setting it.
The default is 100 (1 second).
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_last_member_interval 200

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 16 ++++++++++++++++
 man/man8/bridge.8 |  7 +++++++
 2 files changed, 23 insertions(+)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 2c6ebedd2d5f..2a3dffdbac44 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -43,6 +43,7 @@ static void usage(void)
 		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
 		"                      [ mcast_mld_version MLD_VERSION ]\n"
 		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
+		"                      [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
 		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
@@ -361,6 +362,7 @@ static int vlan_global_option_set(int argc, char **argv)
 	short vid_end = -1;
 	char *d = NULL;
 	short vid = -1;
+	__u64 val64;
 	__u32 val32;
 	__u8 val8;
 
@@ -438,6 +440,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr32(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
 				  val32);
+		} else if (strcmp(*argv, "mcast_last_member_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_last_member_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -792,6 +802,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			   "mcast_last_member_count %u ",
 			   rta_getattr_u32(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL];
+		print_lluint(PRINT_ANY, "mcast_last_member_interval",
+			     "mcast_last_member_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
 		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT];
 		print_uint(PRINT_ANY, "mcast_startup_query_count",
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 7741382321cb..0d973a9db0e0 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -166,6 +166,8 @@ bridge \- show / manipulate bridge addresses and devices
 .IR MLD_VERSION " ] [ "
 .B mcast_last_member_count
 .IR LAST_MEMBER_COUNT " ] [ "
+.B mcast_last_member_interval
+.IR LAST_MEMBER_INTERVAL " ] [ "
 .B mcast_startup_query_count
 .IR STARTUP_QUERY_COUNT " ]"
 
@@ -953,6 +955,11 @@ set multicast last member count, ie the number of queries the bridge
 will send before stopping forwarding a multicast group after a "leave"
 message has been received. Default is 2.
 
+.TP
+.BI mcast_last_member_interval " LAST_MEMBER_INTERVAL "
+interval between queries to find remaining members of a group,
+after a "leave" message is received.
+
 .TP
 .BI mcast_startup_query_count " STARTUP_QUERY_COUNT "
 set the number of queries to send during startup phase. Default is 2.
-- 
2.31.1


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

* [PATCH iproute2-next v2 13/19] bridge: vlan: add global mcast_membership_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (11 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 12/19] bridge: vlan: add global mcast_last_member_interval option Nikolay Aleksandrov
@ 2021-08-28 11:07 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 14/19] bridge: vlan: add global mcast_querier_interval option Nikolay Aleksandrov
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:07 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_membership_interval
option which controls the interval after which the bridge will leave a
group if no reports have been received for it. To be consistent with the
same bridge-wide option the value is reported with USER_HZ granularity and
the same granularity is expected when setting it.
The default is 26000 (260 seconds).
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_membership_interval 13000

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 |  9 ++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 2a3dffdbac44..acdbb4a1b562 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -45,6 +45,7 @@ static void usage(void)
 		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
 		"                      [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
 		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
+		"                      [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -448,6 +449,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr64(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
 				  val64);
+		} else if (strcmp(*argv, "mcast_membership_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_membership_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -814,6 +823,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			   "mcast_startup_query_count %u ",
 			   rta_getattr_u32(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL];
+		print_lluint(PRINT_ANY, "mcast_membership_interval",
+			     "mcast_membership_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 0d973a9db0e0..a026ca16f89a 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -169,7 +169,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_last_member_interval
 .IR LAST_MEMBER_INTERVAL " ] [ "
 .B mcast_startup_query_count
-.IR STARTUP_QUERY_COUNT " ]"
+.IR STARTUP_QUERY_COUNT " ] [ "
+.B mcast_membership_interval
+.IR MEMBERSHIP_INTERVAL " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -964,6 +966,11 @@ after a "leave" message is received.
 .BI mcast_startup_query_count " STARTUP_QUERY_COUNT "
 set the number of queries to send during startup phase. Default is 2.
 
+.TP
+.BI mcast_membership_interval " MEMBERSHIP_INTERVAL "
+delay after which the bridge will leave a group,
+if no membership reports for this group are received.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 14/19] bridge: vlan: add global mcast_querier_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (12 preceding siblings ...)
  2021-08-28 11:07 ` [PATCH iproute2-next v2 13/19] bridge: vlan: add global mcast_membership_interval option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 15/19] bridge: vlan: add global mcast_query_interval option Nikolay Aleksandrov
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_querier_interval
option which controls the interval after which if no other router
queries are seen the bridge will start sending its own queries.
To be consistent with the same bridge-wide option the value is reported
with USER_HZ granularity and the same granularity is expected when
setting it.
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_querier_interval 13000

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 | 12 +++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index acdbb4a1b562..5494dd15c76e 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -46,6 +46,7 @@ static void usage(void)
 		"                      [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
 		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
 		"                      [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
+		"                      [ mcast_querier_interval QUERIER_INTERVAL ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -457,6 +458,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr64(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
 				  val64);
+		} else if (strcmp(*argv, "mcast_querier_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_querier_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -829,6 +838,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			     "mcast_membership_interval %llu ",
 			     rta_getattr_u64(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL];
+		print_lluint(PRINT_ANY, "mcast_querier_interval",
+			     "mcast_querier_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index a026ca16f89a..f5c72ec83f93 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -171,7 +171,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_startup_query_count
 .IR STARTUP_QUERY_COUNT " ] [ "
 .B mcast_membership_interval
-.IR MEMBERSHIP_INTERVAL " ]"
+.IR MEMBERSHIP_INTERVAL " ] [ "
+.B mcast_querier_interval
+.IR QUERIER_INTERVAL " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -971,6 +973,14 @@ set the number of queries to send during startup phase. Default is 2.
 delay after which the bridge will leave a group,
 if no membership reports for this group are received.
 
+.TP
+.BI mcast_querier_interval " QUERIER_INTERVAL "
+interval between queries sent by other routers. If no queries are seen
+after this delay has passed, the bridge will start to send its own queries
+(as if
+.BI mcast_querier
+was enabled).
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 15/19] bridge: vlan: add global mcast_query_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (13 preceding siblings ...)
  2021-08-28 11:08 ` [PATCH iproute2-next v2 14/19] bridge: vlan: add global mcast_querier_interval option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 16/19] bridge: vlan: add global mcast_query_response_interval option Nikolay Aleksandrov
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_query_interval
option which controls the interval between queries sent by the bridge
after the end of the startup phase. To be consistent with the same
bridge-wide option the value is reported with USER_HZ granularity and
the same granularity is expected when setting it.
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_query_interval 13000

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 |  9 ++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 5494dd15c76e..d7fb27ea752a 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -47,6 +47,7 @@ static void usage(void)
 		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
 		"                      [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
 		"                      [ mcast_querier_interval QUERIER_INTERVAL ]\n"
+		"                      [ mcast_query_interval QUERY_INTERVAL ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -466,6 +467,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr64(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
 				  val64);
+		} else if (strcmp(*argv, "mcast_query_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_query_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -844,6 +853,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			     "mcast_querier_interval %llu ",
 			     rta_getattr_u64(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL];
+		print_lluint(PRINT_ANY, "mcast_query_interval",
+			     "mcast_query_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index f5c72ec83f93..cb1170f8d5c9 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -173,7 +173,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_membership_interval
 .IR MEMBERSHIP_INTERVAL " ] [ "
 .B mcast_querier_interval
-.IR QUERIER_INTERVAL " ]"
+.IR QUERIER_INTERVAL " ] [ "
+.B mcast_query_interval
+.IR QUERY_INTERVAL " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -981,6 +983,11 @@ after this delay has passed, the bridge will start to send its own queries
 .BI mcast_querier
 was enabled).
 
+.TP
+.BI mcast_query_interval " QUERY_INTERVAL "
+interval between queries sent by the bridge after the end of the
+startup phase.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 16/19] bridge: vlan: add global mcast_query_response_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (14 preceding siblings ...)
  2021-08-28 11:08 ` [PATCH iproute2-next v2 15/19] bridge: vlan: add global mcast_query_interval option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 17/19] bridge: vlan: add global mcast_startup_query_interval option Nikolay Aleksandrov
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_query_response_interval
option which sets the Max Response Time/Maximum Response Delay for IGMP/MLD
queries sent by the bridge. To be consistent with the same bridge-wide
option the value is reported with USER_HZ granularity and the same
granularity is expected when setting it.
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_query_response_interval 13000

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 |  9 ++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index d7fb27ea752a..7f6845158bf0 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -48,6 +48,7 @@ static void usage(void)
 		"                      [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
 		"                      [ mcast_querier_interval QUERIER_INTERVAL ]\n"
 		"                      [ mcast_query_interval QUERY_INTERVAL ]\n"
+		"                      [ mcast_query_response_interval QUERY_RESPONSE_INTERVAL ]\n"
 		"       bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
@@ -475,6 +476,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr64(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
 				  val64);
+		} else if (strcmp(*argv, "mcast_query_response_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_query_response_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -859,6 +868,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			     "mcast_query_interval %llu ",
 			     rta_getattr_u64(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL];
+		print_lluint(PRINT_ANY, "mcast_query_response_interval",
+			     "mcast_query_response_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	print_nl();
 	close_json_object();
 }
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index cb1170f8d5c9..e9cd5f9f4fe6 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -175,7 +175,9 @@ bridge \- show / manipulate bridge addresses and devices
 .B mcast_querier_interval
 .IR QUERIER_INTERVAL " ] [ "
 .B mcast_query_interval
-.IR QUERY_INTERVAL " ]"
+.IR QUERY_INTERVAL " ] [ "
+.B mcast_query_response_interval
+.IR QUERY_RESPONSE_INTERVAL " ]"
 
 .ti -8
 .BR "bridge vlan global" " [ " show " ] [ "
@@ -988,6 +990,11 @@ was enabled).
 interval between queries sent by the bridge after the end of the
 startup phase.
 
+.TP
+.BI mcast_query_response_interval " QUERY_RESPONSE_INTERVAL "
+set the Max Response Time/Maximum Response Delay for IGMP/MLD
+queries sent by the bridge.
+
 .SS bridge vlan global show - list global vlan options.
 
 This command displays the global VLAN options for each VLAN entry.
-- 
2.31.1


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

* [PATCH iproute2-next v2 17/19] bridge: vlan: add global mcast_startup_query_interval option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (15 preceding siblings ...)
  2021-08-28 11:08 ` [PATCH iproute2-next v2 16/19] bridge: vlan: add global mcast_query_response_interval option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 18/19] bridge: vlan: add global mcast_querier option Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 19/19] bridge: vlan: add support for dumping router ports Nikolay Aleksandrov
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_startup_query_interval
option which controls the interval between queries in the startup phase.
To be consistent with the same bridge-wide option the value is reported
with USER_HZ granularity and the same granularity is expected when setting
it.
Syntax:
 $ bridge vlan global set dev bridge vid 1 mcast_startup_query_interval 15000

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 15 +++++++++++++++
 man/man8/bridge.8 |  6 ++++++
 2 files changed, 21 insertions(+)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index 7f6845158bf0..e8043f8574fd 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -45,6 +45,7 @@ static void usage(void)
 		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
 		"                      [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
 		"                      [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
+		"                      [ mcast_startup_query_interval STARTUP_QUERY_INTERVAL ]\n"
 		"                      [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
 		"                      [ mcast_querier_interval QUERIER_INTERVAL ]\n"
 		"                      [ mcast_query_interval QUERY_INTERVAL ]\n"
@@ -484,6 +485,14 @@ static int vlan_global_option_set(int argc, char **argv)
 			addattr64(&req.n, 1024,
 				  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
 				  val64);
+		} else if (strcmp(*argv, "mcast_startup_query_interval") == 0) {
+			NEXT_ARG();
+			if (get_u64(&val64, *argv, 0))
+				invarg("invalid mcast_startup_query_interval",
+				       *argv);
+			addattr64(&req.n, 1024,
+				  BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
+				  val64);
 		} else {
 			if (matches(*argv, "help") == 0)
 				NEXT_ARG();
@@ -850,6 +859,12 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 			   "mcast_startup_query_count %u ",
 			   rta_getattr_u32(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL];
+		print_lluint(PRINT_ANY, "mcast_startup_query_interval",
+			     "mcast_startup_query_interval %llu ",
+			     rta_getattr_u64(vattr));
+	}
 	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
 		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL];
 		print_lluint(PRINT_ANY, "mcast_membership_interval",
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index e9cd5f9f4fe6..eeceb309d219 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -170,6 +170,8 @@ bridge \- show / manipulate bridge addresses and devices
 .IR LAST_MEMBER_INTERVAL " ] [ "
 .B mcast_startup_query_count
 .IR STARTUP_QUERY_COUNT " ] [ "
+.B mcast_startup_query_interval
+.IR STARTUP_QUERY_INTERVAL " ] [ "
 .B mcast_membership_interval
 .IR MEMBERSHIP_INTERVAL " ] [ "
 .B mcast_querier_interval
@@ -972,6 +974,10 @@ after a "leave" message is received.
 .BI mcast_startup_query_count " STARTUP_QUERY_COUNT "
 set the number of queries to send during startup phase. Default is 2.
 
+.TP
+.BI mcast_startup_query_interval " STARTUP_QUERY_INTERVAL "
+interval between queries in the startup phase.
+
 .TP
 .BI mcast_membership_interval " MEMBERSHIP_INTERVAL "
 delay after which the bridge will leave a group,
-- 
2.31.1


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

* [PATCH iproute2-next v2 18/19] bridge: vlan: add global mcast_querier option
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (16 preceding siblings ...)
  2021-08-28 11:08 ` [PATCH iproute2-next v2 17/19] bridge: vlan: add global mcast_startup_query_interval option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  2021-08-28 11:08 ` [PATCH iproute2-next v2 19/19] bridge: vlan: add support for dumping router ports Nikolay Aleksandrov
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add control and dump support for the global mcast_querier option which
controls if the bridge will act as a multicast querier for that vlan.
Syntax: $ bridge vlan global set dev bridge vid 1 mcast_querier 1

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
v2: adjust help msg alignment to fit in 100 columns

 bridge/vlan.c     | 12 ++++++++++++
 man/man8/bridge.8 | 10 ++++++++++
 2 files changed, 22 insertions(+)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index e8043f8574fd..afb5186d36de 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -40,6 +40,7 @@ static void usage(void)
 		"       bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
 		"       bridge vlan global { set } vid VLAN_ID dev DEV\n"
 		"                      [ mcast_snooping MULTICAST_SNOOPING ]\n"
+		"                      [ mcast_querier MULTICAST_QUERIER ]\n"
 		"                      [ mcast_igmp_version IGMP_VERSION ]\n"
 		"                      [ mcast_mld_version MLD_VERSION ]\n"
 		"                      [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
@@ -418,6 +419,12 @@ static int vlan_global_option_set(int argc, char **argv)
 				invarg("invalid mcast_snooping", *argv);
 			addattr8(&req.n, 1024,
 				 BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
+		} else if (strcmp(*argv, "mcast_querier") == 0) {
+			NEXT_ARG();
+			if (get_u8(&val8, *argv, 0))
+				invarg("invalid mcast_querier", *argv);
+			addattr8(&req.n, 1024,
+				 BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, val8);
 		} else if (strcmp(*argv, "mcast_igmp_version") == 0) {
 			NEXT_ARG();
 			if (get_u8(&val8, *argv, 0))
@@ -831,6 +838,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
 		print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ",
 			   rta_getattr_u8(vattr));
 	}
+	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
+		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER];
+		print_uint(PRINT_ANY, "mcast_querier", "mcast_querier %u ",
+			   rta_getattr_u8(vattr));
+	}
 	if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
 		vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION];
 		print_uint(PRINT_ANY, "mcast_igmp_version",
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index eeceb309d219..76d2fa09d5bc 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -160,6 +160,8 @@ bridge \- show / manipulate bridge addresses and devices
 .IR VID " [ "
 .B mcast_snooping
 .IR MULTICAST_SNOOPING " ] [ "
+.B mcast_querier
+.IR MULTICAST_QUERIER " ] [ "
 .B mcast_igmp_version
 .IR IGMP_VERSION " ] [ "
 .B mcast_mld_version
@@ -951,6 +953,14 @@ turn multicast snooping for VLAN entry with VLAN ID on
 or off
 .RI ( MULTICAST_SNOOPING " == 0). Default is on. "
 
+.TP
+.BI mcast_querier " MULTICAST_QUERIER "
+enable
+.RI ( MULTICAST_QUERIER " > 0) "
+or disable
+.RI ( MULTICAST_QUERIER " == 0) "
+IGMP/MLD querier, ie sending of multicast queries by the bridge. Default is disabled.
+
 .TP
 .BI mcast_igmp_version " IGMP_VERSION "
 set the IGMP version. Default is 2.
-- 
2.31.1


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

* [PATCH iproute2-next v2 19/19] bridge: vlan: add support for dumping router ports
  2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
                   ` (17 preceding siblings ...)
  2021-08-28 11:08 ` [PATCH iproute2-next v2 18/19] bridge: vlan: add global mcast_querier option Nikolay Aleksandrov
@ 2021-08-28 11:08 ` Nikolay Aleksandrov
  18 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-08-28 11:08 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsahern, stephen, Joachim Wiberg, Nikolay Aleksandrov

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 --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();
 }
 
-- 
2.31.1


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

* Re: [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option
  2021-08-28 11:07 ` [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option Nikolay Aleksandrov
@ 2021-09-01  3:36   ` David Ahern
  2021-09-01  8:07     ` Nikolay Aleksandrov
  0 siblings, 1 reply; 22+ messages in thread
From: David Ahern @ 2021-09-01  3:36 UTC (permalink / raw)
  To: Nikolay Aleksandrov, netdev
  Cc: roopa, stephen, Joachim Wiberg, Nikolay Aleksandrov

On 8/28/21 4:07 AM, Nikolay Aleksandrov wrote:
> @@ -397,6 +400,12 @@ static int vlan_global_option_set(int argc, char **argv)
>  			if (vid_end != -1)
>  				addattr16(&req.n, sizeof(req),
>  					  BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
> +		} else if (strcmp(*argv, "mcast_snooping") == 0) {
> +			NEXT_ARG();
> +			if (get_u8(&val8, *argv, 0))
> +				invarg("invalid mcast_snooping", *argv);
> +			addattr8(&req.n, 1024,
> +				 BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
>  		} else {
>  			if (matches(*argv, "help") == 0)
>  				NEXT_ARG();

How did you redo this patch set where 06 uses strcmp for the help line
and yet patches 7-17 all have matches?

Fixed those up given where we are with 5.14 cycle and applied to
iproute2-next.

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

* Re: [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option
  2021-09-01  3:36   ` David Ahern
@ 2021-09-01  8:07     ` Nikolay Aleksandrov
  0 siblings, 0 replies; 22+ messages in thread
From: Nikolay Aleksandrov @ 2021-09-01  8:07 UTC (permalink / raw)
  To: David Ahern, Nikolay Aleksandrov, netdev; +Cc: roopa, stephen, Joachim Wiberg

On 01/09/2021 06:36, David Ahern wrote:
> On 8/28/21 4:07 AM, Nikolay Aleksandrov wrote:
>> @@ -397,6 +400,12 @@ static int vlan_global_option_set(int argc, char **argv)
>>  			if (vid_end != -1)
>>  				addattr16(&req.n, sizeof(req),
>>  					  BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
>> +		} else if (strcmp(*argv, "mcast_snooping") == 0) {
>> +			NEXT_ARG();
>> +			if (get_u8(&val8, *argv, 0))
>> +				invarg("invalid mcast_snooping", *argv);
>> +			addattr8(&req.n, 1024,
>> +				 BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, val8);
>>  		} else {
>>  			if (matches(*argv, "help") == 0)
>>  				NEXT_ARG();
> 
> How did you redo this patch set where 06 uses strcmp for the help line
> and yet patches 7-17 all have matches?
> 
> Fixed those up given where we are with 5.14 cycle and applied to
> iproute2-next.
> 

Oh wtf, looks like rebasing gone wrong, I'll have to fix up my scripts.
Apologies about that and thanks for taking care of the matches -> strcmp.

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

end of thread, other threads:[~2021-09-01  8:07 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-28 11:07 [PATCH iproute2-next v2 00/19] bridge: vlan: add global multicast options Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 01/19] ip: bridge: add support for mcast_vlan_snooping Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 02/19] bridge: vlan: factor out vlan option printing Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 03/19] bridge: vlan: skip unknown attributes when printing options Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 04/19] bridge: vlan: add support to show global vlan options Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 05/19] bridge: vlan: add support for vlan filtering when dumping options Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 06/19] bridge: vlan: add support to set global vlan options Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 07/19] bridge: vlan: add global mcast_snooping option Nikolay Aleksandrov
2021-09-01  3:36   ` David Ahern
2021-09-01  8:07     ` Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 08/19] bridge: vlan: add global mcast_igmp_version option Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 09/19] bridge: vlan: add global mcast_mld_version option Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 10/19] bridge: vlan: add global mcast_last_member_count option Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 11/19] bridge: vlan: add global mcast_startup_query_count option Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 12/19] bridge: vlan: add global mcast_last_member_interval option Nikolay Aleksandrov
2021-08-28 11:07 ` [PATCH iproute2-next v2 13/19] bridge: vlan: add global mcast_membership_interval option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 14/19] bridge: vlan: add global mcast_querier_interval option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 15/19] bridge: vlan: add global mcast_query_interval option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 16/19] bridge: vlan: add global mcast_query_response_interval option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 17/19] bridge: vlan: add global mcast_startup_query_interval option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 18/19] bridge: vlan: add global mcast_querier option Nikolay Aleksandrov
2021-08-28 11:08 ` [PATCH iproute2-next v2 19/19] bridge: vlan: add support for dumping router ports Nikolay Aleksandrov

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.