Index: sbin/ifconfig/ifconfig.8 =================================================================== --- sbin/ifconfig/ifconfig.8 +++ sbin/ifconfig/ifconfig.8 @@ -2319,8 +2319,8 @@ .It Cm laggproto Ar proto Set the aggregation protocol. The default is failover. -The available options are failover, fec, lacp, loadbalance, roundrobin and -none. +The available options are failover, fec, lacp, loadbalance, roundrobin, broadcast +and 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 Index: share/man/man4/lagg.4 =================================================================== --- share/man/man4/lagg.4 +++ share/man/man4/lagg.4 @@ -65,6 +65,7 @@ .Ic lacp , .Ic loadbalance , .Ic roundrobin , +.Ic broadcast , and .Ic none . The protocols determine which ports are used for outgoing traffic @@ -113,6 +114,9 @@ Distributes outgoing traffic using a round-robin scheduler through all active ports and accepts incoming traffic from any active port. +.It Ic broadcast +Sends frames to all ports of the LAG and receives frames on +any port of the LAG. .It Ic none This protocol is intended to do nothing: it disables any traffic without disabling the Index: sys/net/if_lagg.h =================================================================== --- sys/net/if_lagg.h +++ sys/net/if_lagg.h @@ -53,7 +53,8 @@ #define LAGG_PROTO_LOADBALANCE 3 /* loadbalance */ #define LAGG_PROTO_LACP 4 /* 802.3ad lacp */ #define LAGG_PROTO_ETHERCHANNEL 5 /* Cisco FEC */ -#define LAGG_PROTO_MAX 6 +#define LAGG_PROTO_BROADCAST 6 /* broadcast */ +#define LAGG_PROTO_MAX 7 struct lagg_protos { const char *lpr_name; @@ -62,11 +63,12 @@ #define LAGG_PROTO_DEFAULT LAGG_PROTO_FAILOVER #define LAGG_PROTOS { \ - { "failover", LAGG_PROTO_FAILOVER }, \ + { "failover", LAGG_PROTO_FAILOVER }, \ { "fec", LAGG_PROTO_ETHERCHANNEL }, \ { "lacp", LAGG_PROTO_LACP }, \ { "loadbalance", LAGG_PROTO_LOADBALANCE }, \ - { "roundrobin", LAGG_PROTO_ROUNDROBIN }, \ + { "roundrobin", LAGG_PROTO_ROUNDROBIN }, \ + { "broadcast", LAGG_PROTO_BROADCAST }, \ { "none", LAGG_PROTO_NONE }, \ { "default", LAGG_PROTO_DEFAULT } \ } Index: sys/net/if_lagg.c =================================================================== --- sys/net/if_lagg.c +++ sys/net/if_lagg.c @@ -3,6 +3,7 @@ /* * Copyright (c) 2005, 2006 Reyk Floeter * Copyright (c) 2007 Andrew Thompson + * Copyright (c) 2014 Marcelo Araujo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -147,6 +148,13 @@ struct mbuf *); static int lagg_lb_porttable(struct lagg_softc *, struct lagg_port *); +/* Broadcast */ +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 *); + /* 802.3ad LACP */ static int lagg_lacp_attach(struct lagg_softc *); static int lagg_lacp_detach(struct lagg_softc *); @@ -163,10 +171,11 @@ int (*ti_attach)(struct lagg_softc *); } lagg_protos[] = { { 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_ETHERCHANNEL, lagg_lb_attach }, { LAGG_PROTO_LACP, lagg_lacp_attach }, + { LAGG_PROTO_BROADCAST, lagg_bcast_attach }, { LAGG_PROTO_NONE, NULL } }; @@ -918,6 +927,7 @@ case LAGG_PROTO_ROUNDROBIN: case LAGG_PROTO_LOADBALANCE: case LAGG_PROTO_ETHERCHANNEL: + case LAGG_PROTO_BROADCAST: if (LAGG_PORTACTIVE(lp)) rp->rp_flags |= LAGG_PORT_ACTIVE; break; @@ -1440,6 +1450,7 @@ case LAGG_PROTO_ROUNDROBIN: case LAGG_PROTO_LOADBALANCE: case LAGG_PROTO_ETHERCHANNEL: + case LAGG_PROTO_BROADCAST: speed = 0; SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) speed += lp->lp_ifp->if_baudrate; @@ -1722,6 +1733,91 @@ } /* + * 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); +} + +/* * Active failover */