summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig/iflagg.c
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2014-10-01 21:37:32 +0000
committerhrs <hrs@FreeBSD.org>2014-10-01 21:37:32 +0000
commit667a2b736994fabf5ccb434e354a82390b85607e (patch)
treeeac48fef50344f3ef26c23cfa7d7fd20d5e8afa6 /sbin/ifconfig/iflagg.c
parente6ca9a3b21e901c5d307611c1dde00e02f6549e1 (diff)
downloadFreeBSD-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.c80
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",
OpenPOWER on IntegriCloud