Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/if_lagg.c
Show First 20 Lines • Show All 1,251 Lines • ▼ Show 20 Lines | case SIOCGLAGGOPTS: | ||||
break; | break; | ||||
case SIOCSLAGGOPTS: | case SIOCSLAGGOPTS: | ||||
error = priv_check(td, PRIV_NET_LAGG); | error = priv_check(td, PRIV_NET_LAGG); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
/* | /* | ||||
* The stride option was added without defining a corresponding | * The stride option was added without defining a corresponding | ||||
* LAGG_OPT flag, so we must handle it before processing any | * LAGG_OPT flag, so handle a non-zero value before checking | ||||
* remaining options. | * anything else to preserve compatibility. | ||||
*/ | */ | ||||
LAGG_XLOCK(sc); | LAGG_XLOCK(sc); | ||||
if (ro->ro_bkt != 0) { | if (ro->ro_opts == 0 && ro->ro_bkt != 0) { | ||||
if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN) { | if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN) { | ||||
LAGG_XUNLOCK(sc); | LAGG_XUNLOCK(sc); | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
sc->sc_stride = ro->ro_bkt; | sc->sc_stride = ro->ro_bkt; | ||||
} else { | |||||
sc->sc_stride = 0; | |||||
} | } | ||||
if (ro->ro_opts == 0) { | if (ro->ro_opts == 0) { | ||||
LAGG_XUNLOCK(sc); | LAGG_XUNLOCK(sc); | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Set options. LACP options are stored in sc->sc_psc, | * Set options. LACP options are stored in sc->sc_psc, | ||||
* not in sc_opts. | * not in sc_opts. | ||||
*/ | */ | ||||
int valid, lacp; | int valid, lacp; | ||||
switch (ro->ro_opts) { | switch (ro->ro_opts) { | ||||
case LAGG_OPT_USE_FLOWID: | case LAGG_OPT_USE_FLOWID: | ||||
case -LAGG_OPT_USE_FLOWID: | case -LAGG_OPT_USE_FLOWID: | ||||
case LAGG_OPT_USE_NUMA: | case LAGG_OPT_USE_NUMA: | ||||
case -LAGG_OPT_USE_NUMA: | case -LAGG_OPT_USE_NUMA: | ||||
case LAGG_OPT_FLOWIDSHIFT: | case LAGG_OPT_FLOWIDSHIFT: | ||||
case LAGG_OPT_RR_LIMIT: | |||||
valid = 1; | valid = 1; | ||||
lacp = 0; | lacp = 0; | ||||
break; | break; | ||||
case LAGG_OPT_LACP_TXTEST: | case LAGG_OPT_LACP_TXTEST: | ||||
case -LAGG_OPT_LACP_TXTEST: | case -LAGG_OPT_LACP_TXTEST: | ||||
case LAGG_OPT_LACP_RXTEST: | case LAGG_OPT_LACP_RXTEST: | ||||
case -LAGG_OPT_LACP_RXTEST: | case -LAGG_OPT_LACP_RXTEST: | ||||
case LAGG_OPT_LACP_STRICT: | case LAGG_OPT_LACP_STRICT: | ||||
Show All 9 Lines | case SIOCSLAGGOPTS: | ||||
if (valid == 0 || | if (valid == 0 || | ||||
(lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) { | (lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) { | ||||
/* Invalid combination of options specified. */ | /* Invalid combination of options specified. */ | ||||
error = EINVAL; | error = EINVAL; | ||||
LAGG_XUNLOCK(sc); | LAGG_XUNLOCK(sc); | ||||
break; /* Return from SIOCSLAGGOPTS. */ | break; /* Return from SIOCSLAGGOPTS. */ | ||||
} | } | ||||
/* | /* | ||||
* Store new options into sc->sc_opts except for | * Store new options into sc->sc_opts except for | ||||
* FLOWIDSHIFT and LACP options. | * FLOWIDSHIFT, RR and LACP options. | ||||
*/ | */ | ||||
if (lacp == 0) { | if (lacp == 0) { | ||||
if (ro->ro_opts == LAGG_OPT_FLOWIDSHIFT) | if (ro->ro_opts == LAGG_OPT_FLOWIDSHIFT) | ||||
sc->flowid_shift = ro->ro_flowid_shift; | sc->flowid_shift = ro->ro_flowid_shift; | ||||
else if (ro->ro_opts > 0) | else if (ro->ro_opts == LAGG_OPT_RR_LIMIT) { | ||||
if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN || | |||||
ro->ro_bkt == 0) { | |||||
error = EINVAL; | |||||
LAGG_XUNLOCK(sc); | |||||
break; | |||||
} | |||||
sc->sc_stride = ro->ro_bkt; | |||||
} else if (ro->ro_opts > 0) | |||||
sc->sc_opts |= ro->ro_opts; | sc->sc_opts |= ro->ro_opts; | ||||
else | else | ||||
sc->sc_opts &= ~ro->ro_opts; | sc->sc_opts &= ~ro->ro_opts; | ||||
} else { | } else { | ||||
struct lacp_softc *lsc; | struct lacp_softc *lsc; | ||||
struct lacp_port *lp; | struct lacp_port *lp; | ||||
lsc = (struct lacp_softc *)sc->sc_psc; | lsc = (struct lacp_softc *)sc->sc_psc; | ||||
▲ Show 20 Lines • Show All 708 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Simple round robin aggregation | * Simple round robin aggregation | ||||
*/ | */ | ||||
static void | static void | ||||
lagg_rr_attach(struct lagg_softc *sc) | lagg_rr_attach(struct lagg_softc *sc) | ||||
{ | { | ||||
sc->sc_seq = 0; | sc->sc_seq = 0; | ||||
sc->sc_stride = 1; | |||||
} | } | ||||
static int | static int | ||||
lagg_rr_start(struct lagg_softc *sc, struct mbuf *m) | lagg_rr_start(struct lagg_softc *sc, struct mbuf *m) | ||||
{ | { | ||||
struct lagg_port *lp; | struct lagg_port *lp; | ||||
uint32_t p; | uint32_t p; | ||||
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_stride; | ||||
p %= sc->sc_count; | p %= sc->sc_count; | ||||
lp = CK_SLIST_FIRST(&sc->sc_ports); | lp = CK_SLIST_FIRST(&sc->sc_ports); | ||||
while (p--) | while (p--) | ||||
lp = CK_SLIST_NEXT(lp, lp_entries); | lp = CK_SLIST_NEXT(lp, lp_entries); | ||||
/* | /* | ||||
* Check the port's link state. This will return the next active | * Check the port's link state. This will return the next active | ||||
▲ Show 20 Lines • Show All 327 Lines • Show Last 20 Lines |