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 | |
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')
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 45 | ||||
-rw-r--r-- | sbin/ifconfig/iflagg.c | 80 |
2 files changed, 115 insertions, 10 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 61ccf3c..02766a1 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd September 9, 2014 +.Dd October 1, 2014 .Dt IFCONFIG 8 .Os .Sh NAME @@ -679,7 +679,7 @@ Set a flag to enable Neighbor Unreachability Detection. Clear a flag .Cm nud . .It Cm no_prefer_iface -Set a flag to not honor rule 5 of source address selection in RFC 3484. +Set a flag to not honor rule 5 of source address selection in RFC 3484. In practice this means the address on the outgoing interface will not be preferred, effectively yielding the decision to the address selection policy table, configurable with @@ -2331,9 +2331,16 @@ Remove the interface named by from the aggregation interface. .It Cm laggproto Ar proto Set the aggregation protocol. -The default is failover. -The available options are failover, lacp, loadbalance, roundrobin, broadcast -and none. +The default is +.Li failover . +The available options are +.Li failover , +.Li lacp , +.Li loadbalance , +.Li roundrobin , +.Li broadcast +and +.Li none . .It Cm lagghash Ar option Ns Oo , Ns Ar option Oc Set the packet layers to hash for aggregation protocols which load balance. The default is @@ -2348,6 +2355,34 @@ src/dst address for IPv4 or IPv6. .It Cm l4 src/dst port for TCP/UDP/SCTP. .El +.It Cm use_flowid +Enable local hash computation for RSS hash on the interface. +The +.Li loadbalance +and +.Li lacp +modes will use the RSS hash from the network card if available +to avoid computing one, this may give poor traffic distribution +if the hash is invalid or uses less of the protocol header information. +.Cm use_flowid +disables use of RSS hash from the network card. +The default value can be set via the +.Va net.link.lagg.default_use_flowid +.Xr sysctl 8 +variable. +.Li 0 +means +.Dq disabled +and +.Li 1 +means +.Dq enabled . +.It Cm -use_flowid +Disable local hash computation for RSS hash on the interface. +.It Cm flowid_shift Ar number +Set a shift parameter for RSS local hash computation. +Hash is calculated by using flowid bits in a packet header mbuf +which are shifted by the number of this parameter. .El .Pp The following parameters are specific to IP tunnel interfaces, 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", |