Message ID | 20121103032436.8744.12352.stgit@localhost6.localdomain6 |
---|---|
State | RFC, archived |
Delegated to: | stephen hemminger |
Headers | show |
On Fri, 02 Nov 2012 20:24:36 -0700 John Fastabend <john.r.fastabend@intel.com> wrote: > Test bridge commands to set veb, vepa modes to iproute2. > > [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge show > eth2: mode VEB bridge_flags: self > eth3: mode VEPA bridge_flags: self > eth10: mode VEB bridge_flags: self > eth12: mode VEB bridge_flags: self > > [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge state mode veb dev eth3 self > bridge_mode_set eth3: type 19 family 7 mode VEB flags 0002 > > [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge show > eth2: mode VEB bridge_flags: self > eth3: mode VEB bridge_flags: self > eth10: mode VEB bridge_flags: self > eth12: mode VEB bridge_flags: self > > Maybe the final patch should separate protocol (STP) configuraiton > from the bridge setup (VEB.VEPA). But this is good for testing in > the meantime. > > v2: remove a lot of the crazy cruft in the last patch > > Signed-off-by: John Fastabend <john.r.fastabend@intel.com> > --- > > bridge/br_common.h | 1 > bridge/bridge.c | 3 - > bridge/fdb.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++ > include/linux/if_link.h | 16 +++ > 4 files changed, 263 insertions(+), 1 deletions(-) > > diff --git a/bridge/br_common.h b/bridge/br_common.h > index 718ecb9..3e5dcab 100644 > --- a/bridge/br_common.h > +++ b/bridge/br_common.h > @@ -5,6 +5,7 @@ extern int print_fdb(const struct sockaddr_nl *who, > struct nlmsghdr *n, void *arg); > > extern int do_fdb(int argc, char **argv); > +extern int do_bridge(int argc, char **argv); > extern int do_monitor(int argc, char **argv); > > extern int preferred_family; > diff --git a/bridge/bridge.c b/bridge/bridge.c > index e2c33b0..b5145c1 100644 > --- a/bridge/bridge.c > +++ b/bridge/bridge.c > @@ -27,7 +27,7 @@ static void usage(void) > { > fprintf(stderr, > "Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n" > -"where OBJECT := { fdb | monitor }\n" > +"where OBJECT := { fdb | monitor | bridge }\n" > " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" ); > exit(-1); > } > @@ -43,6 +43,7 @@ static const struct cmd { > int (*func)(int argc, char **argv); > } cmds[] = { > { "fdb", do_fdb }, > + { "bridge", do_bridge }, > { "monitor", do_monitor }, > { "help", do_help }, > { 0 } > diff --git a/bridge/fdb.c b/bridge/fdb.c > index 4ca4861..e1c138d 100644 > --- a/bridge/fdb.c > +++ b/bridge/fdb.c > @@ -34,6 +34,13 @@ static void usage(void) > exit(-1); > } > > +static void bridge_usage(void) > +{ > + fprintf(stderr, "Usage: br bridge er mode {veb | vepa} dev DEV\n"); > + fprintf(stderr, " br bridge {show} [ dev DEV] \n"); > + exit(-1); > +} > + > static const char *state_n2a(unsigned s) > { > static char buf[32]; > @@ -269,3 +276,240 @@ int do_fdb(int argc, char **argv) > fprintf(stderr, "Command \"%s\" is unknown, try \"bridge fdb help\".\n", *argv); > exit(-1); > } > + > +int print_bridge(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) > +{ > + FILE *fp = arg; > + struct ifinfomsg *ifm = NLMSG_DATA(n); > + int len = n->nlmsg_len; > + struct rtattr * tb[IFLA_MAX+1]; > + > + 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) { > + fprintf(stderr, "hmm: Not PF_BRIDGE is %i\n", ifm->ifi_family); > + } > + > + if (filter_index && filter_index != ifm->ifi_index) > + return 0; > + > + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len); > + > + if (!tb[IFLA_IFNAME]) { > + fprintf(stderr, "%s: missing ifname using ifi_index %u name %s\n", > + __func__, ifm->ifi_index, > + ll_index_to_name(ifm->ifi_index)); > + } > + if (tb[IFLA_AF_SPEC]) { > + struct rtattr *bridge[IFLA_BRIDGE_MAX+1]; > + __u16 mode = 0, flags = 0; > + > + parse_rtattr_nested(bridge, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]); > + if (bridge[IFLA_BRIDGE_MODE]) > + mode =*(__u16*)RTA_DATA(bridge[IFLA_BRIDGE_MODE]); > + if (bridge[IFLA_BRIDGE_FLAGS]) > + flags =*(__u16*)RTA_DATA(bridge[IFLA_BRIDGE_FLAGS]); > + > + fprintf(stderr, "%s: mode %s bridge_flags: %s %s\n", > + ll_index_to_name(ifm->ifi_index), > + mode ? "VEPA" : "VEB", > + flags & BRIDGE_FLAGS_SELF ? "self" : "", > + flags & BRIDGE_FLAGS_MASTER ? "master" : ""); > + } > + > + if (tb[IFLA_PROTINFO]) { > + __u8 state = *(__u8*)RTA_DATA(tb[IFLA_PROTINFO]); > + char *sstate; > + > + switch (state) { > + case 0: > + sstate = "DISABLED"; > + break; > + case 1: > + sstate = "LISTENING"; > + break; > + case 2: > + sstate = "LEARNING"; > + break; > + case 3: > + sstate = "FORWARDING"; > + break; > + case 4: > + sstate = "BLOCKING"; > + break; > + default: > + sstate = "UNKNOWN"; > + break; > + } > + > + > + fprintf(stderr, "%s: %s: ifla_protinfo: %s\n", > + ll_index_to_name(ifm->ifi_index), > + __func__, sstate); > + } > + > + fflush(fp); > + return 0; > +} > + > +static int bridge_show(int argc, char **argv) > +{ > + char *filter_dev = NULL; > + > + > + while (argc > 0) { > + if (strcmp(*argv, "dev") == 0) { > + NEXT_ARG(); > + if (filter_dev) > + duparg("dev", *argv); > + > + filter_dev = *argv; > + } > + argc--; argv++; > + } > + > + if (filter_dev) { > + if ((filter_index = if_nametoindex(filter_dev)) == 0) { > + fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev); > + return -1; > + } > + } > + > + if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { > + perror("Cannot send dump request"); > + exit(1); > + } > + > + if (rtnl_dump_filter(&rth, print_bridge, stdout) < 0) { > + fprintf(stderr, "Dump terminated\n"); > + exit(1); > + } > + > + return 0; > +} > + > +static int bridge_state_set(int argc, char **argv) > +{ > + struct { > + struct nlmsghdr n; > + struct ifinfomsg ifm; > + char buf[1024]; > + } req; > + struct { > + struct nlmsghdr hdr; > + struct nlmsgerr err; > + struct nlmsghdr rhdr; > + struct ifinfomsg ifm; > + char buf[1024]; > + } reply; > + char *d = NULL; > + __u8 state = 0; > + __u16 mode = -1, flags = 0; > + > + memset(&req, 0, sizeof(req)); > + memset(&reply, 0, sizeof(reply)); > + > + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); > + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_ACK; > + req.n.nlmsg_type = RTM_SETLINK; > + req.ifm.ifi_family = PF_BRIDGE; > + > + while (argc > 0) { > + if (strcmp(*argv, "dev") == 0) { > + NEXT_ARG(); > + d = *argv; > + } else if (matches(*argv, "state") == 0) { > + NEXT_ARG(); > + if (matches(*argv, "DISABLED") == 0) > + state = 0; > + else if (matches(*argv, "LISTENING") == 0) > + state = 1; > + else if (matches(*argv, "LEARNING") == 0) > + state = 2; > + else if (matches(*argv, "FORWARDING") == 0) > + state = 3; > + else if (matches(*argv, "BLOCKING") == 0) > + state = 4; > + else > + invarg("Invalid state value\n", *argv); > + > + } else if (matches(*argv, "mode") == 0) { > + NEXT_ARG(); > + if (matches(*argv, "veb") == 0) > + mode = BRIDGE_MODE_VEB; > + else if (matches(*argv, "vepa") == 0) > + mode = BRIDGE_MODE_VEPA; > + else > + invarg("Invalid mode value\n", *argv); > + > + } else if (matches(*argv, "master") == 0) { > + flags |= BRIDGE_FLAGS_MASTER; > + } else if (matches(*argv, "self") == 0) { > + flags |= BRIDGE_FLAGS_SELF; > + } > + > + argc--; argv++; > + } > + > + if (!d) { > + fprintf(stderr, "Device required.\n"); > + exit(-1); > + } > + > + req.ifm.ifi_index = ll_name_to_index(d); > + if (req.ifm.ifi_index == 0) { > + fprintf(stderr, "Cannot find device \"%s\"\n", d); > + return -1; > + } > + > + if (state < 4) > + addattr8(&req.n, sizeof(req.buf), IFLA_PROTINFO, state); > + > + printf("%s %s(%u): type %i family %i state 0x%x ", __func__, d, req.ifm.ifi_index, > + req.n.nlmsg_type, req.ifm.ifi_family, state); > + > + if (mode < 3 || flags) { > + struct rtattr *binfo; > + int err = 0; > + > + binfo = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC); > + if (flags) > + err = addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags); > + if (mode < 3) > + err = addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode); > + if (err < 0) > + fprintf(stderr, "addattr16 failes\n"); > + addattr_nest_end(&req.n, binfo); > + > + printf("mode %s\n", mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB"); > + } > + > + printf("%s: %s(%u): rtnl_talk length %u\n", __func__, d, req.ifm.ifi_index, req.n.nlmsg_len); > + if (rtnl_talk(&rth, &req.n, 0, 0, &reply.hdr) < 0) { > + printf("\nREPLY: error %i\n", reply.err.error); > + print_bridge(NULL, &reply.err.msg, stderr); > + exit(2); > + } > + > + return 0; > +} > + > +int do_bridge(int argc, char **argv) > +{ > + ll_init_map(&rth); > + > + if (argc > 0) { > + if (matches(*argv, "show") == 0) > + return bridge_show(argc-1, argv+1); > + else if (matches(*argv, "state") == 0) > + return bridge_state_set(argc-1, argv+1); > + else if (matches(*argv, "help") == 0) > + bridge_usage(); > + } > + > + exit(0); > +} > diff --git a/include/linux/if_link.h b/include/linux/if_link.h > index 012d95a..1a6c2f1 100644 > --- a/include/linux/if_link.h > +++ b/include/linux/if_link.h > @@ -142,6 +142,7 @@ enum { > #define IFLA_PROMISCUITY IFLA_PROMISCUITY > IFLA_NUM_TX_QUEUES, > IFLA_NUM_RX_QUEUES, > + IFLA_BRIDGE, > __IFLA_MAX > }; > > @@ -375,6 +376,21 @@ enum { > #define PORT_UUID_MAX 16 > #define PORT_SELF_VF -1 > > +/* Bridge Flags */ > +#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */ > +#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */ > + > +#define BRIDGE_MODE_VEB 0 /* Default loopback mode */ > +#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ > + > +/* Bridge management nested attributes */ > +enum { > + IFLA_BRIDGE_FLAGS, > + IFLA_BRIDGE_MODE, > + __IFLA_BRIDGE_MAX, > +}; > +#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) > + > enum { > PORT_REQUEST_PREASSOCIATE = 0, > PORT_REQUEST_PREASSOCIATE_RR, > This looks ok. I will roll it into the resubmit of bridge changes when I get back from Linuxcon. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 11/5/2012 12:50 AM, Stephen Hemminger wrote: > On Fri, 02 Nov 2012 20:24:36 -0700 > John Fastabend <john.r.fastabend@intel.com> wrote: > >> Test bridge commands to set veb, vepa modes to iproute2. [...] >> +}; >> +#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) >> + >> enum { >> PORT_REQUEST_PREASSOCIATE = 0, >> PORT_REQUEST_PREASSOCIATE_RR, >> > > This looks ok. I will roll it into the resubmit of bridge changes > when I get back from Linuxcon. > Sounds good thanks. I'll test what you come up with when I see it. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/bridge/br_common.h b/bridge/br_common.h index 718ecb9..3e5dcab 100644 --- a/bridge/br_common.h +++ b/bridge/br_common.h @@ -5,6 +5,7 @@ extern int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); extern int do_fdb(int argc, char **argv); +extern int do_bridge(int argc, char **argv); extern int do_monitor(int argc, char **argv); extern int preferred_family; diff --git a/bridge/bridge.c b/bridge/bridge.c index e2c33b0..b5145c1 100644 --- a/bridge/bridge.c +++ b/bridge/bridge.c @@ -27,7 +27,7 @@ static void usage(void) { fprintf(stderr, "Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n" -"where OBJECT := { fdb | monitor }\n" +"where OBJECT := { fdb | monitor | bridge }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" ); exit(-1); } @@ -43,6 +43,7 @@ static const struct cmd { int (*func)(int argc, char **argv); } cmds[] = { { "fdb", do_fdb }, + { "bridge", do_bridge }, { "monitor", do_monitor }, { "help", do_help }, { 0 } diff --git a/bridge/fdb.c b/bridge/fdb.c index 4ca4861..e1c138d 100644 --- a/bridge/fdb.c +++ b/bridge/fdb.c @@ -34,6 +34,13 @@ static void usage(void) exit(-1); } +static void bridge_usage(void) +{ + fprintf(stderr, "Usage: br bridge er mode {veb | vepa} dev DEV\n"); + fprintf(stderr, " br bridge {show} [ dev DEV] \n"); + exit(-1); +} + static const char *state_n2a(unsigned s) { static char buf[32]; @@ -269,3 +276,240 @@ int do_fdb(int argc, char **argv) fprintf(stderr, "Command \"%s\" is unknown, try \"bridge fdb help\".\n", *argv); exit(-1); } + +int print_bridge(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) +{ + FILE *fp = arg; + struct ifinfomsg *ifm = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr * tb[IFLA_MAX+1]; + + 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) { + fprintf(stderr, "hmm: Not PF_BRIDGE is %i\n", ifm->ifi_family); + } + + if (filter_index && filter_index != ifm->ifi_index) + return 0; + + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len); + + if (!tb[IFLA_IFNAME]) { + fprintf(stderr, "%s: missing ifname using ifi_index %u name %s\n", + __func__, ifm->ifi_index, + ll_index_to_name(ifm->ifi_index)); + } + if (tb[IFLA_AF_SPEC]) { + struct rtattr *bridge[IFLA_BRIDGE_MAX+1]; + __u16 mode = 0, flags = 0; + + parse_rtattr_nested(bridge, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]); + if (bridge[IFLA_BRIDGE_MODE]) + mode =*(__u16*)RTA_DATA(bridge[IFLA_BRIDGE_MODE]); + if (bridge[IFLA_BRIDGE_FLAGS]) + flags =*(__u16*)RTA_DATA(bridge[IFLA_BRIDGE_FLAGS]); + + fprintf(stderr, "%s: mode %s bridge_flags: %s %s\n", + ll_index_to_name(ifm->ifi_index), + mode ? "VEPA" : "VEB", + flags & BRIDGE_FLAGS_SELF ? "self" : "", + flags & BRIDGE_FLAGS_MASTER ? "master" : ""); + } + + if (tb[IFLA_PROTINFO]) { + __u8 state = *(__u8*)RTA_DATA(tb[IFLA_PROTINFO]); + char *sstate; + + switch (state) { + case 0: + sstate = "DISABLED"; + break; + case 1: + sstate = "LISTENING"; + break; + case 2: + sstate = "LEARNING"; + break; + case 3: + sstate = "FORWARDING"; + break; + case 4: + sstate = "BLOCKING"; + break; + default: + sstate = "UNKNOWN"; + break; + } + + + fprintf(stderr, "%s: %s: ifla_protinfo: %s\n", + ll_index_to_name(ifm->ifi_index), + __func__, sstate); + } + + fflush(fp); + return 0; +} + +static int bridge_show(int argc, char **argv) +{ + char *filter_dev = NULL; + + + while (argc > 0) { + if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + if (filter_dev) + duparg("dev", *argv); + + filter_dev = *argv; + } + argc--; argv++; + } + + if (filter_dev) { + if ((filter_index = if_nametoindex(filter_dev)) == 0) { + fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev); + return -1; + } + } + + if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { + perror("Cannot send dump request"); + exit(1); + } + + if (rtnl_dump_filter(&rth, print_bridge, stdout) < 0) { + fprintf(stderr, "Dump terminated\n"); + exit(1); + } + + return 0; +} + +static int bridge_state_set(int argc, char **argv) +{ + struct { + struct nlmsghdr n; + struct ifinfomsg ifm; + char buf[1024]; + } req; + struct { + struct nlmsghdr hdr; + struct nlmsgerr err; + struct nlmsghdr rhdr; + struct ifinfomsg ifm; + char buf[1024]; + } reply; + char *d = NULL; + __u8 state = 0; + __u16 mode = -1, flags = 0; + + memset(&req, 0, sizeof(req)); + memset(&reply, 0, sizeof(reply)); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_ACK; + req.n.nlmsg_type = RTM_SETLINK; + req.ifm.ifi_family = PF_BRIDGE; + + while (argc > 0) { + if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + d = *argv; + } else if (matches(*argv, "state") == 0) { + NEXT_ARG(); + if (matches(*argv, "DISABLED") == 0) + state = 0; + else if (matches(*argv, "LISTENING") == 0) + state = 1; + else if (matches(*argv, "LEARNING") == 0) + state = 2; + else if (matches(*argv, "FORWARDING") == 0) + state = 3; + else if (matches(*argv, "BLOCKING") == 0) + state = 4; + else + invarg("Invalid state value\n", *argv); + + } else if (matches(*argv, "mode") == 0) { + NEXT_ARG(); + if (matches(*argv, "veb") == 0) + mode = BRIDGE_MODE_VEB; + else if (matches(*argv, "vepa") == 0) + mode = BRIDGE_MODE_VEPA; + else + invarg("Invalid mode value\n", *argv); + + } else if (matches(*argv, "master") == 0) { + flags |= BRIDGE_FLAGS_MASTER; + } else if (matches(*argv, "self") == 0) { + flags |= BRIDGE_FLAGS_SELF; + } + + argc--; argv++; + } + + if (!d) { + fprintf(stderr, "Device required.\n"); + exit(-1); + } + + req.ifm.ifi_index = ll_name_to_index(d); + if (req.ifm.ifi_index == 0) { + fprintf(stderr, "Cannot find device \"%s\"\n", d); + return -1; + } + + if (state < 4) + addattr8(&req.n, sizeof(req.buf), IFLA_PROTINFO, state); + + printf("%s %s(%u): type %i family %i state 0x%x ", __func__, d, req.ifm.ifi_index, + req.n.nlmsg_type, req.ifm.ifi_family, state); + + if (mode < 3 || flags) { + struct rtattr *binfo; + int err = 0; + + binfo = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC); + if (flags) + err = addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags); + if (mode < 3) + err = addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode); + if (err < 0) + fprintf(stderr, "addattr16 failes\n"); + addattr_nest_end(&req.n, binfo); + + printf("mode %s\n", mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB"); + } + + printf("%s: %s(%u): rtnl_talk length %u\n", __func__, d, req.ifm.ifi_index, req.n.nlmsg_len); + if (rtnl_talk(&rth, &req.n, 0, 0, &reply.hdr) < 0) { + printf("\nREPLY: error %i\n", reply.err.error); + print_bridge(NULL, &reply.err.msg, stderr); + exit(2); + } + + return 0; +} + +int do_bridge(int argc, char **argv) +{ + ll_init_map(&rth); + + if (argc > 0) { + if (matches(*argv, "show") == 0) + return bridge_show(argc-1, argv+1); + else if (matches(*argv, "state") == 0) + return bridge_state_set(argc-1, argv+1); + else if (matches(*argv, "help") == 0) + bridge_usage(); + } + + exit(0); +} diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 012d95a..1a6c2f1 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -142,6 +142,7 @@ enum { #define IFLA_PROMISCUITY IFLA_PROMISCUITY IFLA_NUM_TX_QUEUES, IFLA_NUM_RX_QUEUES, + IFLA_BRIDGE, __IFLA_MAX }; @@ -375,6 +376,21 @@ enum { #define PORT_UUID_MAX 16 #define PORT_SELF_VF -1 +/* Bridge Flags */ +#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */ +#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */ + +#define BRIDGE_MODE_VEB 0 /* Default loopback mode */ +#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ + +/* Bridge management nested attributes */ +enum { + IFLA_BRIDGE_FLAGS, + IFLA_BRIDGE_MODE, + __IFLA_BRIDGE_MAX, +}; +#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) + enum { PORT_REQUEST_PREASSOCIATE = 0, PORT_REQUEST_PREASSOCIATE_RR,
Test bridge commands to set veb, vepa modes to iproute2. [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge show eth2: mode VEB bridge_flags: self eth3: mode VEPA bridge_flags: self eth10: mode VEB bridge_flags: self eth12: mode VEB bridge_flags: self [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge state mode veb dev eth3 self bridge_mode_set eth3: type 19 family 7 mode VEB flags 0002 [root@jf-dev1-dcblab iproute2]# ./bridge/bridge bridge show eth2: mode VEB bridge_flags: self eth3: mode VEB bridge_flags: self eth10: mode VEB bridge_flags: self eth12: mode VEB bridge_flags: self Maybe the final patch should separate protocol (STP) configuraiton from the bridge setup (VEB.VEPA). But this is good for testing in the meantime. v2: remove a lot of the crazy cruft in the last patch Signed-off-by: John Fastabend <john.r.fastabend@intel.com> --- bridge/br_common.h | 1 bridge/bridge.c | 3 - bridge/fdb.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/if_link.h | 16 +++ 4 files changed, 263 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html