Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_lagg.c
Show First 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | |||||
/* Active failover */ | /* Active failover */ | ||||
static int lagg_fail_attach(struct lagg_softc *); | static int lagg_fail_attach(struct lagg_softc *); | ||||
static int lagg_fail_detach(struct lagg_softc *); | static int lagg_fail_detach(struct lagg_softc *); | ||||
static int lagg_fail_start(struct lagg_softc *, struct mbuf *); | static int lagg_fail_start(struct lagg_softc *, struct mbuf *); | ||||
static struct mbuf *lagg_fail_input(struct lagg_softc *, struct lagg_port *, | static struct mbuf *lagg_fail_input(struct lagg_softc *, struct lagg_port *, | ||||
struct mbuf *); | struct mbuf *); | ||||
/* Broadcast mode */ | |||||
static int lagg_bcast_attach(struct lagg_softc *); | |||||
static int lagg_bcast_detach(struct lagg_softc *); | |||||
static int lagg_bcast_start(struct lagg_softc *, struct mbuf *); | |||||
static struct mbuf *lagg_bcast_input(struct lagg_softc *, struct lagg_port *, | |||||
struct mbuf *); | |||||
/* Loadbalancing */ | /* Loadbalancing */ | ||||
static int lagg_lb_attach(struct lagg_softc *); | static int lagg_lb_attach(struct lagg_softc *); | ||||
static int lagg_lb_detach(struct lagg_softc *); | static int lagg_lb_detach(struct lagg_softc *); | ||||
static int lagg_lb_port_create(struct lagg_port *); | static int lagg_lb_port_create(struct lagg_port *); | ||||
static void lagg_lb_port_destroy(struct lagg_port *); | static void lagg_lb_port_destroy(struct lagg_port *); | ||||
static int lagg_lb_start(struct lagg_softc *, struct mbuf *); | static int lagg_lb_start(struct lagg_softc *, struct mbuf *); | ||||
static struct mbuf *lagg_lb_input(struct lagg_softc *, struct lagg_port *, | static struct mbuf *lagg_lb_input(struct lagg_softc *, struct lagg_port *, | ||||
struct mbuf *); | struct mbuf *); | ||||
Show All 12 Lines | |||||
/* lagg protocol table */ | /* lagg protocol table */ | ||||
static const struct { | static const struct { | ||||
int ti_proto; | int ti_proto; | ||||
int (*ti_attach)(struct lagg_softc *); | int (*ti_attach)(struct lagg_softc *); | ||||
} lagg_protos[] = { | } lagg_protos[] = { | ||||
{ LAGG_PROTO_ROUNDROBIN, lagg_rr_attach }, | { LAGG_PROTO_ROUNDROBIN, lagg_rr_attach }, | ||||
{ LAGG_PROTO_FAILOVER, lagg_fail_attach }, | { LAGG_PROTO_FAILOVER, lagg_fail_attach }, | ||||
{ LAGG_PROTO_LOADBALANCE, lagg_lb_attach }, | { LAGG_PROTO_LOADBALANCE, lagg_lb_attach }, | ||||
{ LAGG_PROTO_ETHERCHANNEL, lagg_lb_attach }, | { LAGG_PROTO_BROADCAST, lagg_bcast_attach }, | ||||
{ LAGG_PROTO_LACP, lagg_lacp_attach }, | { LAGG_PROTO_LACP, lagg_lacp_attach }, | ||||
{ LAGG_PROTO_NONE, NULL } | { LAGG_PROTO_NONE, NULL } | ||||
}; | }; | ||||
SYSCTL_DECL(_net_link); | SYSCTL_DECL(_net_link); | ||||
SYSCTL_NODE(_net_link, OID_AUTO, lagg, CTLFLAG_RW, 0, | SYSCTL_NODE(_net_link, OID_AUTO, lagg, CTLFLAG_RW, 0, | ||||
"Link Aggregation"); | "Link Aggregation"); | ||||
▲ Show 20 Lines • Show All 735 Lines • ▼ Show 20 Lines | case LAGG_PROTO_FAILOVER: | ||||
if (lp == sc->sc_primary) | if (lp == sc->sc_primary) | ||||
rp->rp_flags |= LAGG_PORT_MASTER; | rp->rp_flags |= LAGG_PORT_MASTER; | ||||
if (lp == lagg_link_active(sc, sc->sc_primary)) | if (lp == lagg_link_active(sc, sc->sc_primary)) | ||||
rp->rp_flags |= LAGG_PORT_ACTIVE; | rp->rp_flags |= LAGG_PORT_ACTIVE; | ||||
break; | break; | ||||
case LAGG_PROTO_ROUNDROBIN: | case LAGG_PROTO_ROUNDROBIN: | ||||
case LAGG_PROTO_LOADBALANCE: | case LAGG_PROTO_LOADBALANCE: | ||||
case LAGG_PROTO_ETHERCHANNEL: | case LAGG_PROTO_BROADCAST: | ||||
if (LAGG_PORTACTIVE(lp)) | if (LAGG_PORTACTIVE(lp)) | ||||
rp->rp_flags |= LAGG_PORT_ACTIVE; | rp->rp_flags |= LAGG_PORT_ACTIVE; | ||||
break; | break; | ||||
case LAGG_PROTO_LACP: | case LAGG_PROTO_LACP: | ||||
/* LACP has a different definition of active */ | /* LACP has a different definition of active */ | ||||
if (lacp_isactive(lp)) | if (lacp_isactive(lp)) | ||||
rp->rp_flags |= LAGG_PORT_ACTIVE; | rp->rp_flags |= LAGG_PORT_ACTIVE; | ||||
▲ Show 20 Lines • Show All 501 Lines • ▼ Show 20 Lines | lagg_linkstate(struct lagg_softc *sc) | ||||
/* Update if_baudrate to reflect the max possible speed */ | /* Update if_baudrate to reflect the max possible speed */ | ||||
switch (sc->sc_proto) { | switch (sc->sc_proto) { | ||||
case LAGG_PROTO_FAILOVER: | case LAGG_PROTO_FAILOVER: | ||||
sc->sc_ifp->if_baudrate = sc->sc_primary != NULL ? | sc->sc_ifp->if_baudrate = sc->sc_primary != NULL ? | ||||
sc->sc_primary->lp_ifp->if_baudrate : 0; | sc->sc_primary->lp_ifp->if_baudrate : 0; | ||||
break; | break; | ||||
case LAGG_PROTO_ROUNDROBIN: | case LAGG_PROTO_ROUNDROBIN: | ||||
case LAGG_PROTO_LOADBALANCE: | case LAGG_PROTO_LOADBALANCE: | ||||
case LAGG_PROTO_ETHERCHANNEL: | case LAGG_PROTO_BROADCAST: | ||||
speed = 0; | speed = 0; | ||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) | SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) | ||||
speed += lp->lp_ifp->if_baudrate; | speed += lp->lp_ifp->if_baudrate; | ||||
sc->sc_ifp->if_baudrate = speed; | sc->sc_ifp->if_baudrate = speed; | ||||
break; | break; | ||||
case LAGG_PROTO_LACP: | case LAGG_PROTO_LACP: | ||||
/* LACP updates if_baudrate itself */ | /* LACP updates if_baudrate itself */ | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 262 Lines • ▼ Show 20 Lines | |||||
static struct mbuf * | static struct mbuf * | ||||
lagg_rr_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) | lagg_rr_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ifnet *ifp = sc->sc_ifp; | ||||
/* Just pass in the packet to our lagg device */ | /* Just pass in the packet to our lagg device */ | ||||
m->m_pkthdr.rcvif = ifp; | m->m_pkthdr.rcvif = ifp; | ||||
return (m); | |||||
} | |||||
/* | |||||
* Broadcast mode | |||||
*/ | |||||
static int | |||||
lagg_bcast_attach(struct lagg_softc *sc) | |||||
{ | |||||
sc->sc_detach = lagg_bcast_detach; | |||||
sc->sc_start = lagg_bcast_start; | |||||
sc->sc_input = lagg_bcast_input; | |||||
sc->sc_port_create = NULL; | |||||
sc->sc_port_destroy = NULL; | |||||
sc->sc_linkstate = NULL; | |||||
sc->sc_req = NULL; | |||||
sc->sc_portreq = NULL; | |||||
return (0); | |||||
} | |||||
static int | |||||
lagg_bcast_detach(struct lagg_softc *sc) | |||||
{ | |||||
return (0); | |||||
} | |||||
static int | |||||
lagg_bcast_start(struct lagg_softc *sc, struct mbuf *m) | |||||
{ | |||||
int active_ports = 0; | |||||
int errors = 0; | |||||
int ret; | |||||
struct lagg_port *lp, *last = NULL; | |||||
struct mbuf *m0; | |||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { | |||||
if (!LAGG_PORTACTIVE(lp)) | |||||
continue; | |||||
active_ports++; | |||||
if (last != NULL) { | |||||
m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT); | |||||
if (m0 == NULL) { | |||||
ret = ENOBUFS; | |||||
errors++; | |||||
break; | |||||
} | |||||
ret = lagg_enqueue(last->lp_ifp, m0); | |||||
if (ret != 0) | |||||
errors++; | |||||
} | |||||
last = lp; | |||||
} | |||||
if (last == NULL) { | |||||
m_freem(m); | |||||
return (ENOENT); | |||||
} | |||||
if ((last = lagg_link_active(sc, last)) == NULL) { | |||||
m_freem(m); | |||||
return (ENETDOWN); | |||||
} | |||||
ret = lagg_enqueue(last->lp_ifp, m); | |||||
if (ret != 0) | |||||
errors++; | |||||
if (errors == 0) | |||||
return (ret); | |||||
return (0); | |||||
} | |||||
static struct mbuf * | |||||
lagg_bcast_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) | |||||
{ | |||||
struct ifnet *ifp = sc->sc_ifp; | |||||
/* Just pass in the packet to our lagg device */ | |||||
m->m_pkthdr.rcvif = ifp; | |||||
return (m); | return (m); | ||||
} | } | ||||
/* | /* | ||||
* Active failover | * Active failover | ||||
*/ | */ | ||||
static int | static int | ||||
lagg_fail_attach(struct lagg_softc *sc) | lagg_fail_attach(struct lagg_softc *sc) | ||||
▲ Show 20 Lines • Show All 292 Lines • Show Last 20 Lines |