* [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.