diff options
author | hrs <hrs@FreeBSD.org> | 2014-10-01 21:37:32 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2014-10-01 21:37:32 +0000 |
commit | 667a2b736994fabf5ccb434e354a82390b85607e (patch) | |
tree | eac48fef50344f3ef26c23cfa7d7fd20d5e8afa6 /sbin/ifconfig/iflagg.c | |
parent | e6ca9a3b21e901c5d307611c1dde00e02f6549e1 (diff) | |
download | FreeBSD-src-667a2b736994fabf5ccb434e354a82390b85607e.zip FreeBSD-src-667a2b736994fabf5ccb434e354a82390b85607e.tar.gz |
Virtualize lagg(4) cloner. This change fixes a panic when tearing down
if_lagg(4) interfaces which were cloned in a vnet jail.
Sysctl nodes which are dynamically generated for each cloned interface
(net.link.lagg.N.*) have been removed, and use_flowid and flowid_shift
ifconfig(8) parameters have been added instead. Flags and per-interface
statistics counters are displayed in "ifconfig -v".
CR: D842
Diffstat (limited to 'sbin/ifconfig/iflagg.c')
-rw-r--r-- | sbin/ifconfig/iflagg.c | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/sbin/ifconfig/iflagg.c b/sbin/ifconfig/iflagg.c index 29b8574..edb6121 100644 --- a/sbin/ifconfig/iflagg.c +++ b/sbin/ifconfig/iflagg.c @@ -68,7 +68,7 @@ setlaggproto(const char *val, int d, int s, const struct afswtch *afp) bzero(&ra, sizeof(ra)); ra.ra_proto = LAGG_PROTO_MAX; - for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) { + for (i = 0; i < nitems(lpr); i++) { if (strcmp(val, lpr[i].lpr_name) == 0) { ra.ra_proto = lpr[i].lpr_proto; break; @@ -83,6 +83,48 @@ setlaggproto(const char *val, int d, int s, const struct afswtch *afp) } static void +setlaggflowidshift(const char *val, int d, int s, const struct afswtch *afp) +{ + struct lagg_reqall ra; + + bzero(&ra, sizeof(ra)); + ra.ra_opts = LAGG_OPT_FLOWIDSHIFT; + strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname)); + ra.ra_flowid_shift = (int)strtol(val, NULL, 10); + if (ra.ra_flowid_shift & ~LAGG_OPT_FLOWIDSHIFT_MASK) + errx(1, "Invalid flowid_shift option: %s", val); + + if (ioctl(s, SIOCSLAGG, &ra) != 0) + err(1, "SIOCSLAGG"); +} + +static void +setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp) +{ + struct lagg_reqall ra; + + bzero(&ra, sizeof(ra)); + ra.ra_opts = d; + switch (ra.ra_opts) { + case LAGG_OPT_USE_FLOWID: + case -LAGG_OPT_USE_FLOWID: + case LAGG_OPT_LACP_STRICT: + case -LAGG_OPT_LACP_STRICT: + case LAGG_OPT_LACP_TXTEST: + case -LAGG_OPT_LACP_TXTEST: + case LAGG_OPT_LACP_RXTEST: + case -LAGG_OPT_LACP_RXTEST: + break; + default: + err(1, "Invalid lagg option"); + } + strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname)); + + if (ioctl(s, SIOCSLAGG, &ra) != 0) + err(1, "SIOCSLAGG"); +} + +static void setlagghash(const char *val, int d, int s, const struct afswtch *afp) { struct lagg_reqflags rf; @@ -169,7 +211,7 @@ lagg_status(int s) if (ioctl(s, SIOCGLAGG, &ra) == 0) { lp = (struct lacp_opreq *)&ra.ra_lacpreq; - for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) { + for (i = 0; i < nitems(lpr); i++) { if (ra.ra_proto == lpr[i].lpr_proto) { proto = lpr[i].lpr_name; break; @@ -197,9 +239,28 @@ lagg_status(int s) if (isport) printf(" laggdev %s", rp.rp_ifname); putchar('\n'); - if (verbose && ra.ra_proto == LAGG_PROTO_LACP) - printf("\tlag id: %s\n", - lacp_format_peer(lp, "\n\t\t ")); + if (verbose) { + printf("\tlagg options:\n"); + printf("\t\tuse_flowid: %d\n", + (ra.ra_opts & LAGG_OPT_USE_FLOWID) ? 1 : 0); + printf("\t\tflowid_shift: %d\n", ra.ra_flowid_shift); + switch (ra.ra_proto) { + case LAGG_PROTO_LACP: + printf("\t\tlacp_strict: %d\n", + (ra.ra_opts & LAGG_OPT_LACP_STRICT) ? 1 : 0); + printf("\t\tlacp_rxtest: %d\n", + (ra.ra_opts & LAGG_OPT_LACP_RXTEST) ? 1 : 0); + printf("\t\tlacp_txtest: %d\n", + (ra.ra_opts & LAGG_OPT_LACP_TXTEST) ? 1 : 0); + } + printf("\tlagg statistics:\n"); + printf("\t\tactive ports: %d\n", ra.ra_active); + printf("\t\tflapping: %u\n", ra.ra_flapping); + if (ra.ra_proto == LAGG_PROTO_LACP) { + printf("\tlag id: %s\n", + lacp_format_peer(lp, "\n\t\t ")); + } + } for (i = 0; i < ra.ra_ports; i++) { lp = (struct lacp_opreq *)&rpbuf[i].rp_lacpreq; @@ -226,6 +287,15 @@ static struct cmd lagg_cmds[] = { DEF_CMD_ARG("-laggport", unsetlaggport), DEF_CMD_ARG("laggproto", setlaggproto), DEF_CMD_ARG("lagghash", setlagghash), + DEF_CMD("use_flowid", LAGG_OPT_USE_FLOWID, setlaggsetopt), + DEF_CMD("-use_flowid", -LAGG_OPT_USE_FLOWID, setlaggsetopt), + DEF_CMD("lacp_strict", LAGG_OPT_LACP_STRICT, setlaggsetopt), + DEF_CMD("-lacp_strict", -LAGG_OPT_LACP_STRICT, setlaggsetopt), + DEF_CMD("lacp_txtest", LAGG_OPT_LACP_TXTEST, setlaggsetopt), + DEF_CMD("-lacp_txtest", -LAGG_OPT_LACP_TXTEST, setlaggsetopt), + DEF_CMD("lacp_rxtest", LAGG_OPT_LACP_RXTEST, setlaggsetopt), + DEF_CMD("-lacp_rxtest", -LAGG_OPT_LACP_RXTEST, setlaggsetopt), + DEF_CMD_ARG("flowid_shift", setlaggflowidshift), }; static struct afswtch af_lagg = { .af_name = "af_lagg", |