aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/ifconfig.85
-rw-r--r--share/man/man4/lagg.42
-rw-r--r--sys/net/if_lagg.c48
-rw-r--r--sys/net/if_lagg.h5
4 files changed, 33 insertions, 27 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 3b6d29657e80..05c625360d25 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 August 26, 2019
+.Dd December 17, 2019
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2567,6 +2567,9 @@ means
.Dq enabled .
.It Cm -lacp_strict
Disable lacp strict compliance on the interface.
+.It Cm rr_limit Ar number
+Configure a stride for an interface in round-robin mode.
+The default stride is 1.
.El
.Pp
The following parameters apply to IP tunnel interfaces,
diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4
index 9622e7f594df..934593551905 100644
--- a/share/man/man4/lagg.4
+++ b/share/man/man4/lagg.4
@@ -166,7 +166,7 @@ Gigabit Ethernet interfaces:
.Pp
Create a link aggregation using ROUNDROBIN with two
.Xr bge 4
-Gigabit Ethernet interfaces and set the limit of 500 packets
+Gigabit Ethernet interfaces and set a stride of 500 packets
per interface:
.Bd -literal -offset indent
# ifconfig bge0 up
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index d9f1ac47d137..ab67ada833b0 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -1245,23 +1245,38 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
ro->ro_active += LAGG_PORTACTIVE(lp);
}
- ro->ro_bkt = sc->sc_bkt;
+ ro->ro_bkt = sc->sc_stride;
ro->ro_flapping = sc->sc_flapping;
ro->ro_flowid_shift = sc->flowid_shift;
LAGG_XUNLOCK(sc);
break;
case SIOCSLAGGOPTS:
- if (sc->sc_proto == LAGG_PROTO_ROUNDROBIN) {
- if (ro->ro_bkt == 0)
- sc->sc_bkt = 1; // Minimum 1 packet per iface.
- else
- sc->sc_bkt = ro->ro_bkt;
- }
error = priv_check(td, PRIV_NET_LAGG);
if (error)
break;
- if (ro->ro_opts == 0)
+
+ /*
+ * The stride option was added without defining a corresponding
+ * LAGG_OPT flag, so we must handle it before processing any
+ * remaining options.
+ */
+ LAGG_XLOCK(sc);
+ if (ro->ro_bkt != 0) {
+ if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN) {
+ LAGG_XUNLOCK(sc);
+ error = EINVAL;
+ break;
+ }
+ sc->sc_stride = ro->ro_bkt;
+ } else {
+ sc->sc_stride = 0;
+ }
+
+ if (ro->ro_opts == 0) {
+ LAGG_XUNLOCK(sc);
break;
+ }
+
/*
* Set options. LACP options are stored in sc->sc_psc,
* not in sc_opts.
@@ -1292,8 +1307,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
- LAGG_XLOCK(sc);
-
if (valid == 0 ||
(lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) {
/* Invalid combination of options specified. */
@@ -2033,7 +2046,6 @@ static void
lagg_rr_attach(struct lagg_softc *sc)
{
sc->sc_seq = 0;
- sc->sc_bkt_count = sc->sc_bkt;
}
static int
@@ -2042,17 +2054,9 @@ lagg_rr_start(struct lagg_softc *sc, struct mbuf *m)
struct lagg_port *lp;
uint32_t p;
- if (sc->sc_bkt_count == 0 && sc->sc_bkt > 0)
- sc->sc_bkt_count = sc->sc_bkt;
-
- if (sc->sc_bkt > 0) {
- atomic_subtract_int(&sc->sc_bkt_count, 1);
- if (atomic_cmpset_int(&sc->sc_bkt_count, 0, sc->sc_bkt))
- p = atomic_fetchadd_32(&sc->sc_seq, 1);
- else
- p = sc->sc_seq;
- } else
- p = atomic_fetchadd_32(&sc->sc_seq, 1);
+ p = atomic_fetchadd_32(&sc->sc_seq, 1);
+ if (sc->sc_stride > 0)
+ p /= sc->sc_stride;
p %= sc->sc_count;
lp = CK_SLIST_FIRST(&sc->sc_ports);
diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h
index 2c566c0de049..913605991180 100644
--- a/sys/net/if_lagg.h
+++ b/sys/net/if_lagg.h
@@ -153,7 +153,7 @@ struct lagg_reqopts {
u_int ro_active; /* active port count */
u_int ro_flapping; /* number of flapping */
int ro_flowid_shift; /* shift the flowid */
- uint32_t ro_bkt; /* packet bucket for roundrobin */
+ uint32_t ro_bkt; /* stride for RR */
};
#define SIOCGLAGGOPTS _IOWR('i', 152, struct lagg_reqopts)
@@ -216,6 +216,7 @@ struct lagg_softc {
struct ifmedia sc_media; /* media config */
void *sc_psc; /* protocol data */
uint32_t sc_seq; /* sequence counter */
+ uint32_t sc_stride; /* stride for RR */
uint32_t sc_flags;
int sc_destroying; /* destroying lagg */
@@ -227,8 +228,6 @@ struct lagg_softc {
struct callout sc_callout;
u_int sc_opts;
int flowid_shift; /* shift the flowid */
- uint32_t sc_bkt; /* packates bucket for roundrobin */
- uint32_t sc_bkt_count; /* packates bucket count for roundrobin */
struct lagg_counters detached_counters; /* detached ports sum */
};