summaryrefslogtreecommitdiffstats
path: root/sbin
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
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')
-rw-r--r--sbin/ifconfig/ifconfig.845
-rw-r--r--sbin/ifconfig/iflagg.c80
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",
OpenPOWER on IntegriCloud