lagg: Clean up handling of the rr_limit option.
- Don't allow an unprivileged user to set the stride. [1] - Only set the stride under the softc lock. - Rename the internal fields to accurately reflect their use. Keep ro_bkt to avoid changing the user API. - Simplify the implementation. The port index is just sc_seq / stride. - Document rr_limit in ifconfig.8. Reported by: Ilja Van Sprundel <ivansprundel@ioactive.com> [1] MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D22857
This commit is contained in:
parent
b649c2ac34
commit
c104c2990d
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user