All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2 0/3] bridge: filtering by vlan id
@ 2016-04-11 13:18 Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 13:18 UTC (permalink / raw)
  To: netdev; +Cc: stephen, roopa, Nikolay Aleksandrov

Hi,
This set adds support for filtering by a vlan id when showing fdb/mdb/vlan
entries. Currently the filtering is implemented entirely in user-space, but
the plan is to add kernel support as well. The vlan show part is also needed
for the future per-vlan statistics in order to be able to show them only for
a specific vlan. I plan to update the bridge man page soon as it's missing
other options too and it seemed inconsistent to add this given that there're
potential paragraphs missing, thus I'll post a separate patch for that.

Thank you,
 Nik

Nikolay Aleksandrov (3):
  bridge: fdb: add support to filter by vlan id
  bridge: mdb: add support to filter by vlan id
  bridge: vlan: add support to filter by vlan id

 bridge/fdb.c  | 21 ++++++++++++++------
 bridge/mdb.c  | 11 +++++++++--
 bridge/vlan.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 75 insertions(+), 20 deletions(-)

-- 
2.4.3

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

* [PATCH iproute2 1/3] bridge: fdb: add support to filter by vlan id
  2016-04-11 13:18 [PATCH iproute2 0/3] bridge: filtering by vlan id Nikolay Aleksandrov
@ 2016-04-11 13:18 ` Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 2/3] bridge: mdb: " Nikolay Aleksandrov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 13:18 UTC (permalink / raw)
  To: netdev; +Cc: stephen, roopa, Nikolay Aleksandrov

Add the optional keyword "vlan" to bridge fdb show so the user can request
filtering by a specific vlan id. Currently the filtering is implemented
only in user-space. The argument name has been chosen to match the
add/del one - "vlan".

Example:
$ bridge fdb show vlan 400
52:54:00:bf:57:16 dev eth2 vlan 400 master br0 permanent

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 bridge/fdb.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/bridge/fdb.c b/bridge/fdb.c
index df55e86df83f..be849f980a80 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -27,7 +27,7 @@
 #include "rt_names.h"
 #include "utils.h"
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
@@ -35,7 +35,7 @@ static void usage(void)
 			"              [ self ] [ master ] [ use ] [ router ]\n"
 			"              [ local | static | dynamic ] [ dst IPADDR ] [ vlan VID ]\n"
 			"              [ port PORT] [ vni VNI ] [ via DEV ]\n");
-	fprintf(stderr, "       bridge fdb [ show [ br BRDEV ] [ brport DEV ] ]\n");
+	fprintf(stderr, "       bridge fdb [ show [ br BRDEV ] [ brport DEV ] [ vlan VID ] ]\n");
 	exit(-1);
 }
 
@@ -65,6 +65,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	struct ndmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NDA_MAX+1];
+	__u16 vid = 0;
 
 	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
 		fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
@@ -88,6 +89,12 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
 		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
+	if (tb[NDA_VLAN])
+		vid = rta_getattr_u16(tb[NDA_VLAN]);
+
+	if (filter_vlan && filter_vlan != vid)
+		return 0;
+
 	if (n->nlmsg_type == RTM_DELNEIGH)
 		fprintf(fp, "Deleted ");
 
@@ -115,11 +122,8 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 				    RTA_DATA(tb[NDA_DST])));
 	}
 
-	if (tb[NDA_VLAN]) {
-		__u16 vid = rta_getattr_u16(tb[NDA_VLAN]);
-
+	if (vid)
 		fprintf(fp, "vlan %hu ", vid);
-	}
 
 	if (tb[NDA_PORT])
 		fprintf(fp, "port %d ", ntohs(rta_getattr_u16(tb[NDA_PORT])));
@@ -190,6 +194,11 @@ static int fdb_show(int argc, char **argv)
 		} else if (strcmp(*argv, "br") == 0) {
 			NEXT_ARG();
 			br = *argv;
+		} else if (strcmp(*argv, "vlan") == 0) {
+			NEXT_ARG();
+			if (filter_vlan)
+				duparg("vlan", *argv);
+			filter_vlan = atoi(*argv);
 		} else {
 			if (matches(*argv, "help") == 0)
 				usage();
-- 
2.4.3

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

* [PATCH iproute2 2/3] bridge: mdb: add support to filter by vlan id
  2016-04-11 13:18 [PATCH iproute2 0/3] bridge: filtering by vlan id Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
@ 2016-04-11 13:18 ` Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 3/3] bridge: vlan: " Nikolay Aleksandrov
  2016-04-11 15:30 ` [PATCH iproute2 0/3] bridge: filtering " Nikolay Aleksandrov
  3 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 13:18 UTC (permalink / raw)
  To: netdev; +Cc: stephen, roopa, Nikolay Aleksandrov

Add the optional keyword "vid" to bridge mdb show so the user can
request filtering by a specific vlan id. Currently the filtering is
implemented only in user-space. The argument name has been chosen to match
the add/del one - "vid".

Example:
$ bridge mdb show vid 200
dev br0 port eth2 grp 239.0.0.1 permanent vid 200

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 bridge/mdb.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/bridge/mdb.c b/bridge/mdb.c
index 842536ec003c..6c904f8e6ae8 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -24,12 +24,12 @@
 	((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
 #endif
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [permanent | temp] [vid VID]\n");
-	fprintf(stderr, "       bridge mdb {show} [ dev DEV ]\n");
+	fprintf(stderr, "       bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
 	exit(-1);
 }
 
@@ -92,6 +92,8 @@ static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
 	const void *src;
 	int af;
 
+	if (filter_vlan && e->vid != filter_vlan)
+		return;
 	af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
 	src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
 			      (const void *)&e->addr.u.ip6;
@@ -195,6 +197,11 @@ static int mdb_show(int argc, char **argv)
 			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++;
 	}
-- 
2.4.3

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

* [PATCH iproute2 3/3] bridge: vlan: add support to filter by vlan id
  2016-04-11 13:18 [PATCH iproute2 0/3] bridge: filtering by vlan id Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
  2016-04-11 13:18 ` [PATCH iproute2 2/3] bridge: mdb: " Nikolay Aleksandrov
@ 2016-04-11 13:18 ` Nikolay Aleksandrov
  2016-04-11 15:30 ` [PATCH iproute2 0/3] bridge: filtering " Nikolay Aleksandrov
  3 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 13:18 UTC (permalink / raw)
  To: netdev; +Cc: stephen, roopa, Nikolay Aleksandrov

Add the optional keyword "vid" to bridge vlan show so the user can
request filtering by a specific vlan id. Currently the filtering is
implemented only in user-space. The argument name has been chosen to
match the add/del one - "vid". This filtering can be used also with the
"-compressvlans" option to see in which range is a vlan (if in any).
Also this will be used to show only specific per-vlan statistics later
when support is added to the kernel for it.

Examples:
$ bridge vlan show vid 450
port	vlan ids
eth1
eth2	 450

br0

$ bridge -c vlan show vid 450
port	vlan ids
eth1
eth2	 400-500

br0

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 bridge/vlan.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 51 insertions(+), 12 deletions(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index ae588323d9b1..8e125c15f84c 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -13,13 +13,13 @@
 #include "br_common.h"
 #include "utils.h"
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
 	fprintf(stderr, "                                                     [ self ] [ master ]\n");
-	fprintf(stderr, "       bridge vlan { show } [ dev DEV ]\n");
+	fprintf(stderr, "       bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
 
@@ -138,6 +138,38 @@ static int vlan_modify(int cmd, int argc, char **argv)
 	return 0;
 }
 
+static void print_vid_range(FILE *f, __u16 v_start, __u16 v_end, __u16 flags)
+{
+	fprintf(f, "\t %hu", v_start);
+	if (v_start != v_end)
+		fprintf(f, "-%hu", v_end);
+	if (flags & BRIDGE_VLAN_INFO_PVID)
+		fprintf(f, " PVID");
+	if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
+		fprintf(f, " Egress Untagged");
+	fprintf(f, "\n");
+}
+
+/* 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
+ * return  0 - skip entry and continue (applies to range start or to entries
+ *             which are less than filter_vlan)
+ * return  1 - print the entry and continue
+ */
+static int filter_vlan_check(struct bridge_vlan_info *vinfo)
+{
+	/* if we're filtering we should stop on the first greater entry */
+	if (filter_vlan && vinfo->vid > filter_vlan &&
+	    !(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
+		return -1;
+	if ((vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
+	    vinfo->vid < filter_vlan)
+		return 0;
+
+	return 1;
+}
+
 static int print_vlan(const struct sockaddr_nl *who,
 		      struct nlmsghdr *n,
 		      void *arg)
@@ -174,26 +206,28 @@ static int print_vlan(const struct sockaddr_nl *who,
 	} else {
 		struct rtattr *i, *list = tb[IFLA_AF_SPEC];
 		int rem = RTA_PAYLOAD(list);
+		__u16 last_vid_start = 0;
 
 		fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
 		for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
 			struct bridge_vlan_info *vinfo;
+			int vcheck_ret;
 
 			if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
 				continue;
 
 			vinfo = RTA_DATA(i);
-			if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)
-				fprintf(fp, "-%hu", vinfo->vid);
-			else
-				fprintf(fp, "\t %hu", vinfo->vid);
-			if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
+
+			if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
+				last_vid_start = vinfo->vid;
+			vcheck_ret = filter_vlan_check(vinfo);
+			if (!vcheck_ret)
 				continue;
-			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
-				fprintf(fp, " PVID");
-			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
-				fprintf(fp, " Egress Untagged");
-			fprintf(fp, "\n");
+			else if (vcheck_ret == 1)
+				print_vid_range(fp, last_vid_start, vinfo->vid,
+						vinfo->flags);
+			else
+				break;
 		}
 	}
 	fprintf(fp, "\n");
@@ -211,6 +245,11 @@ static int vlan_show(int argc, char **argv)
 			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++;
 	}
-- 
2.4.3

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

* Re: [PATCH iproute2 0/3] bridge: filtering by vlan id
  2016-04-11 13:18 [PATCH iproute2 0/3] bridge: filtering by vlan id Nikolay Aleksandrov
                   ` (2 preceding siblings ...)
  2016-04-11 13:18 ` [PATCH iproute2 3/3] bridge: vlan: " Nikolay Aleksandrov
@ 2016-04-11 15:30 ` Nikolay Aleksandrov
  2016-04-11 15:45   ` [PATCH iproute2 v2 " Nikolay Aleksandrov
  3 siblings, 1 reply; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 15:30 UTC (permalink / raw)
  To: netdev; +Cc: stephen, roopa

On 04/11/2016 03:18 PM, Nikolay Aleksandrov wrote:
> Hi,
> This set adds support for filtering by a vlan id when showing fdb/mdb/vlan
> entries. Currently the filtering is implemented entirely in user-space, but
> the plan is to add kernel support as well. The vlan show part is also needed
> for the future per-vlan statistics in order to be able to show them only for
> a specific vlan. I plan to update the bridge man page soon as it's missing
> other options too and it seemed inconsistent to add this given that there're
> potential paragraphs missing, thus I'll post a separate patch for that.
> 
> Thank you,
>  Nik
> 

Self-NAK, after discussing with colleagues, we think it'd be better not to print
the non-matching ports at all (right now they're printed with empty "vlan ids"
column). I'll post a v2 with updated patch 03.

Cheers,
 Nik

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

* [PATCH iproute2 v2 0/3] bridge: filtering by vlan id
  2016-04-11 15:30 ` [PATCH iproute2 0/3] bridge: filtering " Nikolay Aleksandrov
@ 2016-04-11 15:45   ` Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
                       ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 15:45 UTC (permalink / raw)
  To: netdev; +Cc: roopa, stephen, Nikolay Aleksandrov

Hi,
This set adds support for filtering by a vlan id when showing fdb/mdb/vlan
entries. Currently the filtering is implemented entirely in user-space, but
the plan is to add kernel support as well. The vlan show part is also needed
for the future per-vlan statistics in order to be able to show them only for
a specific vlan. I plan to update the bridge man page soon as it's missing
other options too and it seemed inconsistent to add this given that there're
potential paragraphs missing, thus I'll post a separate patch for that.

v2: in patch 03 print only the ports having the vlan instead of empty
"vlan ids" column

Thank you,
 Nik


Nikolay Aleksandrov (3):
  bridge: fdb: add support to filter by vlan id
  bridge: mdb: add support to filter by vlan id
  bridge: vlan: add support to filter by vlan id

 bridge/fdb.c  | 21 +++++++++++++++------
 bridge/mdb.c  | 11 +++++++++--
 bridge/vlan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 74 insertions(+), 18 deletions(-)

-- 
2.4.3

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

* [PATCH iproute2 v2 1/3] bridge: fdb: add support to filter by vlan id
  2016-04-11 15:45   ` [PATCH iproute2 v2 " Nikolay Aleksandrov
@ 2016-04-11 15:45     ` Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 2/3] bridge: mdb: " Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 3/3] bridge: vlan: " Nikolay Aleksandrov
  2 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 15:45 UTC (permalink / raw)
  To: netdev; +Cc: roopa, stephen, Nikolay Aleksandrov

Add the optional keyword "vlan" to bridge fdb show so the user can request
filtering by a specific vlan id. Currently the filtering is implemented
only in user-space. The argument name has been chosen to match the
add/del one - "vlan".

Example:
$ bridge fdb show vlan 400
52:54:00:bf:57:16 dev eth2 vlan 400 master br0 permanent

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
v2: no change

 bridge/fdb.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/bridge/fdb.c b/bridge/fdb.c
index df55e86df83f..be849f980a80 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -27,7 +27,7 @@
 #include "rt_names.h"
 #include "utils.h"
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
@@ -35,7 +35,7 @@ static void usage(void)
 			"              [ self ] [ master ] [ use ] [ router ]\n"
 			"              [ local | static | dynamic ] [ dst IPADDR ] [ vlan VID ]\n"
 			"              [ port PORT] [ vni VNI ] [ via DEV ]\n");
-	fprintf(stderr, "       bridge fdb [ show [ br BRDEV ] [ brport DEV ] ]\n");
+	fprintf(stderr, "       bridge fdb [ show [ br BRDEV ] [ brport DEV ] [ vlan VID ] ]\n");
 	exit(-1);
 }
 
@@ -65,6 +65,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	struct ndmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NDA_MAX+1];
+	__u16 vid = 0;
 
 	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
 		fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
@@ -88,6 +89,12 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
 		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
+	if (tb[NDA_VLAN])
+		vid = rta_getattr_u16(tb[NDA_VLAN]);
+
+	if (filter_vlan && filter_vlan != vid)
+		return 0;
+
 	if (n->nlmsg_type == RTM_DELNEIGH)
 		fprintf(fp, "Deleted ");
 
@@ -115,11 +122,8 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 				    RTA_DATA(tb[NDA_DST])));
 	}
 
-	if (tb[NDA_VLAN]) {
-		__u16 vid = rta_getattr_u16(tb[NDA_VLAN]);
-
+	if (vid)
 		fprintf(fp, "vlan %hu ", vid);
-	}
 
 	if (tb[NDA_PORT])
 		fprintf(fp, "port %d ", ntohs(rta_getattr_u16(tb[NDA_PORT])));
@@ -190,6 +194,11 @@ static int fdb_show(int argc, char **argv)
 		} else if (strcmp(*argv, "br") == 0) {
 			NEXT_ARG();
 			br = *argv;
+		} else if (strcmp(*argv, "vlan") == 0) {
+			NEXT_ARG();
+			if (filter_vlan)
+				duparg("vlan", *argv);
+			filter_vlan = atoi(*argv);
 		} else {
 			if (matches(*argv, "help") == 0)
 				usage();
-- 
2.4.3

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

* [PATCH iproute2 v2 2/3] bridge: mdb: add support to filter by vlan id
  2016-04-11 15:45   ` [PATCH iproute2 v2 " Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
@ 2016-04-11 15:45     ` Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 3/3] bridge: vlan: " Nikolay Aleksandrov
  2 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 15:45 UTC (permalink / raw)
  To: netdev; +Cc: roopa, stephen, Nikolay Aleksandrov

Add the optional keyword "vid" to bridge mdb show so the user can
request filtering by a specific vlan id. Currently the filtering is
implemented only in user-space. The argument name has been chosen to match
the add/del one - "vid".

Example:
$ bridge mdb show vid 200
dev br0 port eth2 grp 239.0.0.1 permanent vid 200

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
v2: no change

 bridge/mdb.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/bridge/mdb.c b/bridge/mdb.c
index 842536ec003c..6c904f8e6ae8 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -24,12 +24,12 @@
 	((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
 #endif
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [permanent | temp] [vid VID]\n");
-	fprintf(stderr, "       bridge mdb {show} [ dev DEV ]\n");
+	fprintf(stderr, "       bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
 	exit(-1);
 }
 
@@ -92,6 +92,8 @@ static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
 	const void *src;
 	int af;
 
+	if (filter_vlan && e->vid != filter_vlan)
+		return;
 	af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
 	src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
 			      (const void *)&e->addr.u.ip6;
@@ -195,6 +197,11 @@ static int mdb_show(int argc, char **argv)
 			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++;
 	}
-- 
2.4.3

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

* [PATCH iproute2 v2 3/3] bridge: vlan: add support to filter by vlan id
  2016-04-11 15:45   ` [PATCH iproute2 v2 " Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
  2016-04-11 15:45     ` [PATCH iproute2 v2 2/3] bridge: mdb: " Nikolay Aleksandrov
@ 2016-04-11 15:45     ` Nikolay Aleksandrov
  2 siblings, 0 replies; 9+ messages in thread
From: Nikolay Aleksandrov @ 2016-04-11 15:45 UTC (permalink / raw)
  To: netdev; +Cc: roopa, stephen, Nikolay Aleksandrov

Add the optional keyword "vid" to bridge vlan show so the user can
request filtering by a specific vlan id. Currently the filtering is
implemented only in user-space. The argument name has been chosen to
match the add/del one - "vid". This filtering can be used also with the
"-compressvlans" option to see in which range is a vlan (if in any).
Also this will be used to show only specific per-vlan statistics later
when support is added to the kernel for it.

Examples:
$ bridge vlan show vid 450
port	vlan ids
eth2	 450

$ bridge -c vlan show vid 450
port	vlan ids
eth2	 400-500

$ bridge vlan show vid 1
port	vlan ids
eth1	 1 PVID Egress Untagged
eth2	 1 PVID
br0	 1 PVID Egress Untagged

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
v2: don't print ports which are not matching the vlan filter
The vcheck_ret == 1 case implicit use is to avoid a nesting level which
breaks a lot of lines and produces uglier result.

 bridge/vlan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index ae588323d9b1..717025ae6eec 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -13,13 +13,13 @@
 #include "br_common.h"
 #include "utils.h"
 
-static unsigned int filter_index;
+static unsigned int filter_index, filter_vlan;
 
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
 	fprintf(stderr, "                                                     [ self ] [ master ]\n");
-	fprintf(stderr, "       bridge vlan { show } [ dev DEV ]\n");
+	fprintf(stderr, "       bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n");
 	exit(-1);
 }
 
@@ -138,6 +138,26 @@ static int vlan_modify(int cmd, int argc, char **argv)
 	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
+ * return  0 - skip entry and continue (applies to range start or to entries
+ *             which are less than filter_vlan)
+ * return  1 - print the entry and continue
+ */
+static int filter_vlan_check(struct bridge_vlan_info *vinfo)
+{
+	/* if we're filtering we should stop on the first greater entry */
+	if (filter_vlan && vinfo->vid > filter_vlan &&
+	    !(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
+		return -1;
+	if ((vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
+	    vinfo->vid < filter_vlan)
+		return 0;
+
+	return 1;
+}
+
 static int print_vlan(const struct sockaddr_nl *who,
 		      struct nlmsghdr *n,
 		      void *arg)
@@ -169,26 +189,40 @@ static int print_vlan(const struct sockaddr_nl *who,
 
 	/* if AF_SPEC isn't there, vlan table is not preset for this port */
 	if (!tb[IFLA_AF_SPEC]) {
-		fprintf(fp, "%s\tNone\n", ll_index_to_name(ifm->ifi_index));
+		if (!filter_vlan)
+			fprintf(fp, "%s\tNone\n",
+				ll_index_to_name(ifm->ifi_index));
 		return 0;
 	} else {
 		struct rtattr *i, *list = tb[IFLA_AF_SPEC];
 		int rem = RTA_PAYLOAD(list);
+		__u16 last_vid_start = 0;
 
-		fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
+		if (!filter_vlan)
+			fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
 		for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
 			struct bridge_vlan_info *vinfo;
+			int vcheck_ret;
 
 			if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
 				continue;
 
 			vinfo = RTA_DATA(i);
-			if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)
-				fprintf(fp, "-%hu", vinfo->vid);
-			else
-				fprintf(fp, "\t %hu", vinfo->vid);
-			if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
+
+			if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
+				last_vid_start = vinfo->vid;
+			vcheck_ret = filter_vlan_check(vinfo);
+			if (vcheck_ret == -1)
+				break;
+			else if (vcheck_ret == 0)
 				continue;
+
+			if (filter_vlan)
+				fprintf(fp, "%s",
+					ll_index_to_name(ifm->ifi_index));
+			fprintf(fp, "\t %hu", last_vid_start);
+			if (last_vid_start != vinfo->vid)
+				fprintf(fp, "-%hu", vinfo->vid);
 			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
 				fprintf(fp, " PVID");
 			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
@@ -196,7 +230,8 @@ static int print_vlan(const struct sockaddr_nl *who,
 			fprintf(fp, "\n");
 		}
 	}
-	fprintf(fp, "\n");
+	if (!filter_vlan)
+		fprintf(fp, "\n");
 	fflush(fp);
 	return 0;
 }
@@ -211,6 +246,11 @@ static int vlan_show(int argc, char **argv)
 			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++;
 	}
-- 
2.4.3

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

end of thread, other threads:[~2016-04-11 15:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-11 13:18 [PATCH iproute2 0/3] bridge: filtering by vlan id Nikolay Aleksandrov
2016-04-11 13:18 ` [PATCH iproute2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
2016-04-11 13:18 ` [PATCH iproute2 2/3] bridge: mdb: " Nikolay Aleksandrov
2016-04-11 13:18 ` [PATCH iproute2 3/3] bridge: vlan: " Nikolay Aleksandrov
2016-04-11 15:30 ` [PATCH iproute2 0/3] bridge: filtering " Nikolay Aleksandrov
2016-04-11 15:45   ` [PATCH iproute2 v2 " Nikolay Aleksandrov
2016-04-11 15:45     ` [PATCH iproute2 v2 1/3] bridge: fdb: add support to filter " Nikolay Aleksandrov
2016-04-11 15:45     ` [PATCH iproute2 v2 2/3] bridge: mdb: " Nikolay Aleksandrov
2016-04-11 15:45     ` [PATCH iproute2 v2 3/3] bridge: vlan: " 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.