* [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping
@ 2017-10-28 5:13 Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 1/2] iplink: bridge: support bridge port vlan_tunnel attribute Roopa Prabhu
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Roopa Prabhu @ 2017-10-28 5:13 UTC (permalink / raw)
To: stephen; +Cc: netdev, nikolay
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This series adds the required options to iplink and bridge commands
to enable per vlan tunnel info on a bridge port provided by
netlink attributes IFLA_BRPORT_VLAN_TUNNEL (flag) and
IFLA_BRIDGE_VLAN_TUNNEL_INFO
enable vlan-tunnel mapping on a bridge port:
$ip link set dev vxlan0 type bridge_slave vlan_tunnel on
$ip link set dev vxlan0 type bridge_slave vlan_tunnel off
or
$bridge link set dev vxlan0 vlan_tunnel on
$bridge link set dev vxlan0 vlan_tunnel off
add vlan tunnel mapping (expects vlans to have been already
configured on the port):
$bridge vlan add dev vxlan0 vid 2000 tunnel_info id 2000
$bridge vlan add dev vxlan0 vid 1000-1001 tunnel_info id 2000-2001
$bridge vlan tunnelshow
port vlan ids tunnel id
vxlan0 1000-1001 1000-1001
2000 2000
$bridge -j vlan tunnelshow
{
"dummy0": [],
"dummy1": [],
"bridge": [],
"vxlan0": [{
"vlan": 1000,
"vlanEnd": 1001,
"tunid": 1000,
"tunidEnd": 1001
},{
"vlan": 2000,
"tunid": 2000
}
]
}
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Roopa Prabhu (2):
iplink: bridge: support bridge port vlan_tunnel attribute
bridge: vlan: support for per vlan tunnel info
v2 - rebase to latest net-next
bridge/link.c | 12 ++
bridge/vlan.c | 305 ++++++++++++++++++++++++++++++++++++++++++-----
ip/iplink_bridge_slave.c | 9 ++
man/man8/bridge.8 | 12 +-
man/man8/ip-link.8.in | 5 +
5 files changed, 315 insertions(+), 28 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH iproute2 net-next v2 1/2] iplink: bridge: support bridge port vlan_tunnel attribute
2017-10-28 5:13 [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Roopa Prabhu
@ 2017-10-28 5:13 ` Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 2/2] bridge: vlan: support for per vlan tunnel info Roopa Prabhu
2017-10-31 17:06 ` [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Roopa Prabhu @ 2017-10-28 5:13 UTC (permalink / raw)
To: stephen; +Cc: netdev, nikolay
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This config maps to IFLA_BRPORT_VLAN_TUNNEL bridge port netlink
flag attribute. This flag enables vlan to tunnel mapping on a bridge
port. It is off by default.
set vlan_tunnel attribute on bridge port vxlan0:
$ip link set dev vxlan0 type bridge_slave vlan_tunnel on
$ip link set dev vxlan0 type bridge_slave vlan_tunnel off
or via bridge command
$bridge link set dev vxlan0 vlan_tunnel on
$bridge link set dev vxlan0 vlan_tunnel off
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
bridge/link.c | 14 ++++++++++++++
ip/iplink_bridge_slave.c | 9 +++++++++
man/man8/bridge.8 | 6 ++++++
man/man8/ip-link.8.in | 5 +++++
4 files changed, 34 insertions(+)
diff --git a/bridge/link.c b/bridge/link.c
index ae4bb88..65ca47e 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -201,6 +201,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (prtb[IFLA_BRPORT_NEIGH_SUPPRESS])
print_onoff(fp, "neigh_suppress",
rta_getattr_u8(prtb[IFLA_BRPORT_NEIGH_SUPPRESS]));
+ if (prtb[IFLA_BRPORT_VLAN_TUNNEL])
+ print_onoff(fp, "vlan_tunnel",
+ rta_getattr_u8(prtb[IFLA_BRPORT_VLAN_TUNNEL]));
}
} else
print_portstate(fp, rta_getattr_u8(tb[IFLA_PROTINFO]));
@@ -241,6 +244,8 @@ static void usage(void)
fprintf(stderr, " [ learning_sync {on | off} ]\n");
fprintf(stderr, " [ flood {on | off} ]\n");
fprintf(stderr, " [ mcast_flood {on | off} ]\n");
+ fprintf(stderr, " [ neigh_suppress {on | off} ]\n");
+ fprintf(stderr, " [ vlan_tunnel {on | off} ]\n");
fprintf(stderr, " [ hwmode {vepa | veb} ]\n");
fprintf(stderr, " [ self ] [ master ]\n");
fprintf(stderr, " bridge link show [dev DEV]\n");
@@ -280,6 +285,7 @@ static int brlink_modify(int argc, char **argv)
__s8 learning = -1;
__s8 learning_sync = -1;
__s8 flood = -1;
+ __s8 vlan_tunnel = -1;
__s8 mcast_flood = -1;
__s8 hairpin = -1;
__s8 bpdu_guard = -1;
@@ -371,6 +377,11 @@ static int brlink_modify(int argc, char **argv)
if (!on_off("neigh_suppress", &neigh_suppress,
*argv))
return -1;
+ } else if (strcmp(*argv, "vlan_tunnel") == 0) {
+ NEXT_ARG();
+ if (!on_off("vlan_tunnel", &vlan_tunnel,
+ *argv))
+ return -1;
} else {
usage();
}
@@ -426,6 +437,9 @@ static int brlink_modify(int argc, char **argv)
if (neigh_suppress != -1)
addattr8(&req.n, sizeof(req), IFLA_BRPORT_NEIGH_SUPPRESS,
neigh_suppress);
+ if (vlan_tunnel != -1)
+ addattr8(&req.n, sizeof(req), IFLA_BRPORT_VLAN_TUNNEL,
+ vlan_tunnel);
addattr_nest_end(&req.n, nest);
diff --git a/ip/iplink_bridge_slave.c b/ip/iplink_bridge_slave.c
index 0d5a011..be0fb4f 100644
--- a/ip/iplink_bridge_slave.c
+++ b/ip/iplink_bridge_slave.c
@@ -39,6 +39,7 @@ static void print_explain(FILE *f)
" [ mcast_flood {on | off} ]\n"
" [ group_fwd_mask MASK ]\n"
" [ neigh_suppress {on | off} ]\n"
+ " [ vlan_tunnel {on | off} ]\n"
);
}
@@ -283,6 +284,10 @@ static void bridge_slave_print_opt(struct link_util *lu, FILE *f,
print_string(PRINT_ANY, "group_fwd_mask_str",
"group_fwd_mask_str %s ", convbuf);
}
+
+ if (tb[IFLA_BRPORT_VLAN_TUNNEL])
+ _print_onoff(f, "vlan_tunnel", "vlan_tunnel",
+ rta_getattr_u8(tb[IFLA_BRPORT_VLAN_TUNNEL]));
}
static void bridge_slave_parse_on_off(char *arg_name, char *arg_val,
@@ -384,6 +389,10 @@ static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv,
if (get_u16(&mask, *argv, 0))
invarg("invalid group_fwd_mask", *argv);
addattr16(n, 1024, IFLA_BRPORT_GROUP_FWD_MASK, mask);
+ } else if (matches(*argv, "vlan_tunnel") == 0) {
+ NEXT_ARG();
+ bridge_slave_parse_on_off("vlan_tunnel", *argv, n,
+ IFLA_BRPORT_VLAN_TUNNEL);
} else if (matches(*argv, "help") == 0) {
explain();
return -1;
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index fdba0fe..d3c5b1e 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -44,6 +44,8 @@ bridge \- show / manipulate bridge addresses and devices
.BR flood " { " on " | " off " } ] [ "
.BR hwmode " { " vepa " | " veb " } ] [ "
.BR mcast_flood " { " on " | " off " } ] [ "
+.BR neigh_suppress " { " on " | " off " } ] [ "
+.BR vlan_tunnel " { " on " | " off " } ] [ "
.BR self " ] [ " master " ]"
.ti -8
@@ -327,6 +329,10 @@ Controls whether a given port will be flooded with multicast traffic for which t
Controls whether neigh discovery (arp and nd) proxy and suppression is enabled on the port. By default this flag is off.
.TP
+.BR "vlan_tunnel on " or " vlan_tunnel off "
+Controls whether vlan to tunnel mapping is enabled on the port. By default this flag is off.
+
+.TP
.BI self
link setting is configured on specified physical device
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 153665c..71b328c 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1750,6 +1750,8 @@ the following additional arguments are supported:
.BR group_fwd_mask " MASK"
] [
.BR neigh_suppress " { " on " | " off " } ]"
+] [
+.BR vlan_tunnel " { " on " | " off " } ]"
.in +8
.sp
@@ -1830,6 +1832,9 @@ option above.
.BR neigh_suppress " { " on " | " off " }"
- controls whether neigh discovery (arp and nd) proxy and suppression is enabled on the port. By default this flag is off.
+.BR vlan_tunnel " { " on " | " off " }"
+- Controls whether vlan to tunnel mapping is enabled on the port. By default this flag is off.
+
.in -8
.TP
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH iproute2 net-next v2 2/2] bridge: vlan: support for per vlan tunnel info
2017-10-28 5:13 [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 1/2] iplink: bridge: support bridge port vlan_tunnel attribute Roopa Prabhu
@ 2017-10-28 5:13 ` Roopa Prabhu
2017-10-31 17:06 ` [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Roopa Prabhu @ 2017-10-28 5:13 UTC (permalink / raw)
To: stephen; +Cc: netdev, nikolay
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This patch uses kernel bridge vlan attribute
IFLA_BRIDGE_VLAN_TUNNEL_INFO to set/delete/show per vlan tunnel info.
$bridge vlan add dev vxlan0 vid 2000 tunnel_info id 2000
$bridge vlan add dev vxlan0 vid 1000-1001 tunnel_info id 2000-2001
$bridge vlan tunnelshow
port vlan ids tunnel id
vxlan0 1000-1001 1000-1001
2000 2000
$bridge -j vlan tunnelshow
{
"dummy0": [],
"dummy1": [],
"bridge": [],
"vxlan0": [{
"vlan": 1000,
"vlanEnd": 1001,
"tunid": 1000,
"tunidEnd": 1001
},{
"vlan": 2000,
"tunid": 2000
}
]
}
This patch also fixes a json termination bug in print_vlan
when filter vlan is provided by the user.
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
bridge/vlan.c | 328 ++++++++++++++++++++++++++++++++++++++++++++++++------
man/man8/bridge.8 | 14 ++-
2 files changed, 307 insertions(+), 35 deletions(-)
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 4ca91c1..0f78a9e 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -16,18 +16,114 @@
static unsigned int filter_index, filter_vlan;
static int last_ifidx = -1;
+static int show_vlan_tunnel_info = 0;
json_writer_t *jw_global;
static void usage(void)
{
fprintf(stderr,
- "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid ] [ untagged ]\n"
+ "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ tunnel_info id TUNNEL_ID ]\n"
+ " [ pvid ] [ untagged ]\n"
" [ self ] [ master ]\n"
- " bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n");
+ " bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
+ " bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n");
exit(-1);
}
+static int parse_tunnel_info(int *argcp, char ***argvp, __u32 *tun_id_start,
+ __u32 *tun_id_end)
+{
+ char **argv = *argvp;
+ int argc = *argcp;
+ char *t;
+
+ NEXT_ARG();
+ if (!matches(*argv, "id")) {
+ NEXT_ARG();
+ t = strchr(*argv, '-');
+ if (t) {
+ *t = '\0';
+ if (get_u32(tun_id_start, *argv, 0) ||
+ *tun_id_start >= 1u << 24)
+ invarg("invalid tun id", *argv);
+ if (get_u32(tun_id_end, t + 1, 0) ||
+ *tun_id_end >= 1u << 24)
+ invarg("invalid tun id", *argv);
+
+ } else {
+ if (get_u32(tun_id_start, *argv, 0) ||
+ *tun_id_start >= 1u << 24)
+ invarg("invalid tun id", *argv);
+ }
+ } else {
+ invarg("tunnel id expected", *argv);
+ }
+
+ *argcp = argc;
+ *argvp = argv;
+
+ return 0;
+}
+
+static int add_tunnel_info(struct nlmsghdr *n, int reqsize,
+ __u16 vid, __u32 tun_id, __u16 flags)
+{
+ struct rtattr *tinfo;
+
+ tinfo = addattr_nest(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_INFO);
+ addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_ID, tun_id);
+ addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_VID, vid);
+ addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, flags);
+
+ addattr_nest_end(n, tinfo);
+
+ return 0;
+}
+
+static int add_tunnel_info_range(struct nlmsghdr *n, int reqsize,
+ __u16 vid_start, int16_t vid_end,
+ __u32 tun_id_start, __u32 tun_id_end)
+{
+ if (vid_end != -1 && (vid_end - vid_start) > 0) {
+ add_tunnel_info(n, reqsize, vid_start, tun_id_start,
+ BRIDGE_VLAN_INFO_RANGE_BEGIN);
+
+ add_tunnel_info(n, reqsize, vid_end, tun_id_end,
+ BRIDGE_VLAN_INFO_RANGE_END);
+ } else {
+ add_tunnel_info(n, reqsize, vid_start, tun_id_start, 0);
+ }
+
+ return 0;
+}
+
+static int add_vlan_info_range(struct nlmsghdr *n, int reqsize, __u16 vid_start,
+ int16_t vid_end, __u16 flags)
+{
+ struct bridge_vlan_info vinfo = {};
+
+ vinfo.flags = flags;
+ vinfo.vid = vid_start;
+ if (vid_end != -1) {
+ /* send vlan range start */
+ addattr_l(n, reqsize, IFLA_BRIDGE_VLAN_INFO, &vinfo,
+ sizeof(vinfo));
+ vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
+
+ /* Now send the vlan range end */
+ vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
+ vinfo.vid = vid_end;
+ addattr_l(n, reqsize, IFLA_BRIDGE_VLAN_INFO, &vinfo,
+ sizeof(vinfo));
+ } else {
+ addattr_l(n, reqsize, IFLA_BRIDGE_VLAN_INFO, &vinfo,
+ sizeof(vinfo));
+ }
+
+ return 0;
+}
+
static int vlan_modify(int cmd, int argc, char **argv)
{
struct {
@@ -45,7 +141,10 @@ static int vlan_modify(int cmd, int argc, char **argv)
short vid_end = -1;
struct rtattr *afspec;
struct bridge_vlan_info vinfo = {};
+ bool tunnel_info_set = false;
unsigned short flags = 0;
+ __u32 tun_id_start = 0;
+ __u32 tun_id_end = 0;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
@@ -73,6 +172,12 @@ static int vlan_modify(int cmd, int argc, char **argv)
vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
} else if (strcmp(*argv, "untagged") == 0) {
vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
+ } else if (strcmp(*argv, "tunnel_info") == 0) {
+ if (parse_tunnel_info(&argc, &argv,
+ &tun_id_start,
+ &tun_id_end))
+ return -1;
+ tunnel_info_set = true;
} else {
if (matches(*argv, "help") == 0)
NEXT_ARG();
@@ -114,22 +219,12 @@ static int vlan_modify(int cmd, int argc, char **argv)
if (flags)
addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);
- vinfo.vid = vid;
- if (vid_end != -1) {
- /* send vlan range start */
- addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
- sizeof(vinfo));
- vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
-
- /* Now send the vlan range end */
- vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
- vinfo.vid = vid_end;
- addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
- sizeof(vinfo));
- } else {
- addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
- sizeof(vinfo));
- }
+ if (tunnel_info_set)
+ add_tunnel_info_range(&req.n, sizeof(req), vid, vid_end,
+ tun_id_start, tun_id_end);
+ else
+ add_vlan_info_range(&req.n, sizeof(req), vid, vid_end,
+ vinfo.flags);
addattr_nest_end(&req.n, afspec);
@@ -146,14 +241,14 @@ static int vlan_modify(int cmd, int argc, char **argv)
* which are less than filter_vlan)
* return 1 - print the entry and continue
*/
-static int filter_vlan_check(struct bridge_vlan_info *vinfo)
+static int filter_vlan_check(__u16 vid, __u16 flags)
{
/* 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))
+ if (filter_vlan && vid > filter_vlan &&
+ !(flags & BRIDGE_VLAN_INFO_RANGE_END))
return -1;
- if ((vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
- vinfo->vid < filter_vlan)
+ if ((flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
+ vid < filter_vlan)
return 0;
return 1;
@@ -181,6 +276,150 @@ static void start_json_vlan_flags_array(bool *vlan_flags)
*vlan_flags = true;
}
+static void print_vlan_tunnel_info(FILE *fp, struct rtattr *tb, int ifindex)
+{
+ bool jsonw_end_parray = false;
+ struct rtattr *i, *list = tb;
+ int rem = RTA_PAYLOAD(list);
+ __u16 last_vid_start = 0;
+ __u32 last_tunid_start = 0;
+
+ if (!filter_vlan) {
+ print_vlan_port(fp, ifindex);
+ jsonw_end_parray = 1;
+ }
+
+ for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+ struct rtattr *ttb[IFLA_BRIDGE_VLAN_TUNNEL_MAX+1];
+ __u32 tunnel_id = 0;
+ __u16 tunnel_vid = 0;
+ __u16 tunnel_flags = 0;
+ int vcheck_ret;
+
+ if (i->rta_type != IFLA_BRIDGE_VLAN_TUNNEL_INFO)
+ continue;
+
+ parse_rtattr(ttb, IFLA_BRIDGE_VLAN_TUNNEL_MAX,
+ RTA_DATA(i), RTA_PAYLOAD(i));
+
+ if (ttb[IFLA_BRIDGE_VLAN_TUNNEL_VID])
+ tunnel_vid =
+ rta_getattr_u32(ttb[IFLA_BRIDGE_VLAN_TUNNEL_VID]);
+ else
+ continue;
+
+ if (ttb[IFLA_BRIDGE_VLAN_TUNNEL_ID])
+ tunnel_id =
+ rta_getattr_u32(ttb[IFLA_BRIDGE_VLAN_TUNNEL_ID]);
+
+ if (ttb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS])
+ tunnel_flags =
+ rta_getattr_u32(ttb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS]);
+
+ if (!(tunnel_flags & BRIDGE_VLAN_INFO_RANGE_END)) {
+ last_vid_start = tunnel_vid;
+ last_tunid_start = tunnel_id;
+ }
+ vcheck_ret = filter_vlan_check(tunnel_vid, tunnel_flags);
+ if (vcheck_ret == -1)
+ break;
+ else if (vcheck_ret == 0)
+ continue;
+
+ if (tunnel_flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
+ continue;
+
+ if (filter_vlan) {
+ print_vlan_port(fp, ifindex);
+ jsonw_end_parray = 1;
+ }
+
+ if (jw_global) {
+ jsonw_start_object(jw_global);
+ jsonw_uint_field(jw_global, "vlan",
+ last_vid_start);
+ } else {
+ fprintf(fp, "\t %hu", last_vid_start);
+ }
+ if (last_vid_start != tunnel_vid) {
+ if (jw_global)
+ jsonw_uint_field(jw_global, "vlanEnd",
+ tunnel_vid);
+ else
+ fprintf(fp, "-%hu", tunnel_vid);
+ }
+
+ if (jw_global) {
+ jsonw_uint_field(jw_global, "tunid",
+ last_tunid_start);
+ } else {
+ fprintf(fp, "\t %hu", last_tunid_start);
+ }
+ if (last_vid_start != tunnel_vid) {
+ if (jw_global)
+ jsonw_uint_field(jw_global, "tunidEnd",
+ tunnel_id);
+ else
+ fprintf(fp, "-%hu", tunnel_id);
+ }
+
+ if (jw_global)
+ jsonw_end_object(jw_global);
+ else
+ fprintf(fp, "\n");
+ }
+
+ if (jsonw_end_parray) {
+ if (jw_global)
+ jsonw_end_array(jw_global);
+ else
+ fprintf(fp, "\n");
+ }
+}
+
+static int print_vlan_tunnel(const struct sockaddr_nl *who,
+ struct nlmsghdr *n,
+ void *arg)
+{
+ struct ifinfomsg *ifm = NLMSG_DATA(n);
+ struct rtattr *tb[IFLA_MAX+1];
+ int len = n->nlmsg_len;
+ FILE *fp = arg;
+
+ if (n->nlmsg_type != RTM_NEWLINK) {
+ fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
+ n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+ return 0;
+ }
+
+ len -= NLMSG_LENGTH(sizeof(*ifm));
+ if (len < 0) {
+ fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+
+ if (ifm->ifi_family != AF_BRIDGE)
+ return 0;
+
+ if (filter_index && filter_index != ifm->ifi_index)
+ return 0;
+
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len);
+
+ /* if AF_SPEC isn't there, vlan table is not preset for this port */
+ if (!tb[IFLA_AF_SPEC]) {
+ if (!filter_vlan && !jw_global)
+ fprintf(fp, "%s\tNone\n",
+ ll_index_to_name(ifm->ifi_index));
+ return 0;
+ }
+
+ print_vlan_tunnel_info(fp, tb[IFLA_AF_SPEC], ifm->ifi_index);
+
+ fflush(fp);
+ return 0;
+}
+
static int print_vlan(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg)
@@ -219,13 +458,7 @@ static int print_vlan(const struct sockaddr_nl *who,
}
print_vlan_info(fp, tb[IFLA_AF_SPEC], ifm->ifi_index);
- if (!filter_vlan) {
- if (jw_global)
- jsonw_end_array(jw_global);
- else
- fprintf(fp, "\n");
- }
fflush(fp);
return 0;
}
@@ -315,6 +548,7 @@ static int print_vlan_stats(const struct sockaddr_nl *who,
static int vlan_show(int argc, char **argv)
{
char *filter_dev = NULL;
+ int ret = 0;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
@@ -356,10 +590,19 @@ static int vlan_show(int argc, char **argv)
}
jsonw_start_object(jw_global);
} else {
- printf("port\tvlan ids\n");
+ if (show_vlan_tunnel_info)
+ printf("port\tvlan ids\ttunnel id\n");
+ else
+ printf("port\tvlan ids\n");
}
- if (rtnl_dump_filter(&rth, print_vlan, stdout) < 0) {
+ if (show_vlan_tunnel_info)
+ ret = rtnl_dump_filter(&rth, print_vlan_tunnel,
+ stdout);
+ else
+ ret = rtnl_dump_filter(&rth, print_vlan, stdout);
+
+ if (ret < 0) {
fprintf(stderr, "Dump ternminated\n");
exit(1);
}
@@ -408,9 +651,12 @@ void print_vlan_info(FILE *fp, struct rtattr *tb, int ifindex)
int rem = RTA_PAYLOAD(list);
__u16 last_vid_start = 0;
bool vlan_flags = false;
+ bool jsonw_end_parray = false;
- if (!filter_vlan)
+ if (!filter_vlan) {
print_vlan_port(fp, ifindex);
+ jsonw_end_parray = true;
+ }
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
struct bridge_vlan_info *vinfo;
@@ -423,14 +669,16 @@ void print_vlan_info(FILE *fp, struct rtattr *tb, int ifindex)
if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
last_vid_start = vinfo->vid;
- vcheck_ret = filter_vlan_check(vinfo);
+ vcheck_ret = filter_vlan_check(vinfo->vid, vinfo->flags);
if (vcheck_ret == -1)
break;
else if (vcheck_ret == 0)
continue;
- if (filter_vlan)
+ if (filter_vlan) {
print_vlan_port(fp, ifindex);
+ jsonw_end_parray = true;
+ }
if (jw_global) {
jsonw_start_object(jw_global);
jsonw_uint_field(jw_global, "vlan",
@@ -474,6 +722,14 @@ void print_vlan_info(FILE *fp, struct rtattr *tb, int ifindex)
else
fprintf(fp, "\n");
}
+
+ if (jsonw_end_parray) {
+ if (jw_global)
+ jsonw_end_array(jw_global);
+ else
+ fprintf(fp, "\n");
+
+ }
}
int do_vlan(int argc, char **argv)
@@ -489,6 +745,10 @@ int do_vlan(int argc, char **argv)
matches(*argv, "lst") == 0 ||
matches(*argv, "list") == 0)
return vlan_show(argc-1, argv+1);
+ if (matches(*argv, "tunnelshow") == 0) {
+ show_vlan_tunnel_info = 1;
+ return vlan_show(argc-1, argv+1);
+ }
if (matches(*argv, "help") == 0)
usage();
} else {
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index d3c5b1e..d6baa81 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -105,11 +105,13 @@ bridge \- show / manipulate bridge addresses and devices
.IR DEV
.B vid
.IR VID " [ "
+.BR tunnel_info
+.IR TUNNEL_ID " ] [ "
.BR pvid " ] [ " untagged " ] [ "
.BR self " ] [ " master " ] "
.ti -8
-.BR "bridge vlan" " [ " show " ] [ "
+.BR "bridge vlan" " [ " show " | " tunnelshow " ] [ "
.B dev
.IR DEV " ]"
@@ -562,6 +564,12 @@ the interface with which this vlan is associated.
the VLAN ID that identifies the vlan.
.TP
+.BI tunnel_info " TUNNEL_ID"
+the TUNNEL ID that maps to this vlan. The tunnel id is set in dst_metadata for
+every packet that belongs to this vlan (applicable to bridge ports with vlan_tunnel
+flag set).
+
+.TP
.BI pvid
the vlan specified is to be considered a PVID at ingress.
Any untagged frames will be assigned to this VLAN.
@@ -598,6 +606,10 @@ With the
.B -statistics
option, the command displays per-vlan traffic statistics.
+.SS bridge vlan tunnelshow - list vlan tunnel mapping.
+
+This command displays the current vlan tunnel info mapping.
+
.SH bridge monitor - state monitoring
The
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping
2017-10-28 5:13 [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 1/2] iplink: bridge: support bridge port vlan_tunnel attribute Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 2/2] bridge: vlan: support for per vlan tunnel info Roopa Prabhu
@ 2017-10-31 17:06 ` Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Stephen Hemminger @ 2017-10-31 17:06 UTC (permalink / raw)
To: Roopa Prabhu; +Cc: netdev, nikolay
On Fri, 27 Oct 2017 22:13:48 -0700
Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> This series adds the required options to iplink and bridge commands
> to enable per vlan tunnel info on a bridge port provided by
> netlink attributes IFLA_BRPORT_VLAN_TUNNEL (flag) and
> IFLA_BRIDGE_VLAN_TUNNEL_INFO
>
> enable vlan-tunnel mapping on a bridge port:
> $ip link set dev vxlan0 type bridge_slave vlan_tunnel on
> $ip link set dev vxlan0 type bridge_slave vlan_tunnel off
>
> or
>
> $bridge link set dev vxlan0 vlan_tunnel on
> $bridge link set dev vxlan0 vlan_tunnel off
>
> add vlan tunnel mapping (expects vlans to have been already
> configured on the port):
> $bridge vlan add dev vxlan0 vid 2000 tunnel_info id 2000
> $bridge vlan add dev vxlan0 vid 1000-1001 tunnel_info id 2000-2001
>
> $bridge vlan tunnelshow
> port vlan ids tunnel id
> vxlan0 1000-1001 1000-1001
> 2000 2000
>
> $bridge -j vlan tunnelshow
> {
> "dummy0": [],
> "dummy1": [],
> "bridge": [],
> "vxlan0": [{
> "vlan": 1000,
> "vlanEnd": 1001,
> "tunid": 1000,
> "tunidEnd": 1001
> },{
> "vlan": 2000,
> "tunid": 2000
> }
> ]
> }
>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> Roopa Prabhu (2):
> iplink: bridge: support bridge port vlan_tunnel attribute
> bridge: vlan: support for per vlan tunnel info
>
> v2 - rebase to latest net-next
>
> bridge/link.c | 12 ++
> bridge/vlan.c | 305 ++++++++++++++++++++++++++++++++++++++++++-----
> ip/iplink_bridge_slave.c | 9 ++
> man/man8/bridge.8 | 12 +-
> man/man8/ip-link.8.in | 5 +
> 5 files changed, 315 insertions(+), 28 deletions(-)
>
Applied to net-next
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-10-31 17:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-28 5:13 [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 1/2] iplink: bridge: support bridge port vlan_tunnel attribute Roopa Prabhu
2017-10-28 5:13 ` [PATCH iproute2 net-next v2 2/2] bridge: vlan: support for per vlan tunnel info Roopa Prabhu
2017-10-31 17:06 ` [PATCH iproute2 net-next v2 0/2] bridge: support for vlan to tunnel mapping Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).