aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorHiroki Sato <hrs@FreeBSD.org>2014-10-01 21:37:32 +0000
committerHiroki Sato <hrs@FreeBSD.org>2014-10-01 21:37:32 +0000
commit939a050ad96c08ea7793994fa42818ec29bccedd (patch)
treeeac48fef50344f3ef26c23cfa7d7fd20d5e8afa6 /sbin
parent8b1af054e8b6b9fae0a597a41c297f655bd3483a (diff)
downloadsrc-939a050ad96c08ea7793994fa42818ec29bccedd.tar.gz
src-939a050ad96c08ea7793994fa42818ec29bccedd.zip
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
Notes
Notes: svn path=/head/; revision=272386
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 61ccf3ce5681..02766a142fea 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 29b8574f4b1a..edb6121634b1 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",