Author: glebius
Date: Fri Sep 26 11:01:04 2014
New Revision: 272170
URL: http://svnweb.freebsd.org/changeset/base/272170

Log:
  - Provide lagg_proto_attach(), lagg_proto_detach().
  - Make detach a protocol method in lagg_protos.
  - Simplify code to lookup protocols.
  
  Sponsored by: Netflix
  Sponsored by: Nginx, Inc.

Modified:
  head/sys/net/if_lagg.c
  head/sys/net/if_lagg.h

Modified: head/sys/net/if_lagg.c
==============================================================================
--- head/sys/net/if_lagg.c      Fri Sep 26 10:47:57 2014        (r272169)
+++ head/sys/net/if_lagg.c      Fri Sep 26 11:01:04 2014        (r272170)
@@ -164,16 +164,39 @@ static void       lagg_callout(void *);
 
 /* lagg protocol table */
 static const struct lagg_proto {
-       lagg_proto      ti_proto;
-       void            (*ti_attach)(struct lagg_softc *);
+       lagg_proto      pr_num;
+       void            (*pr_attach)(struct lagg_softc *);
+       void            (*pr_detach)(struct lagg_softc *);
 } lagg_protos[] = {
-       { LAGG_PROTO_ROUNDROBIN,        lagg_rr_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 }
+    {
+       .pr_num = LAGG_PROTO_NONE
+    },
+    {
+       .pr_num = LAGG_PROTO_ROUNDROBIN,
+       .pr_attach = lagg_rr_attach,
+    },
+    {
+       .pr_num = LAGG_PROTO_FAILOVER,
+       .pr_attach = lagg_fail_attach,
+    },
+    {
+       .pr_num = LAGG_PROTO_LOADBALANCE,
+       .pr_attach = lagg_lb_attach,
+       .pr_detach = lagg_lb_detach,
+    },
+    {
+       .pr_num = LAGG_PROTO_LACP,
+       .pr_attach = lagg_lacp_attach,
+       .pr_detach = lagg_lacp_detach,
+    },
+    {
+       .pr_num = LAGG_PROTO_ETHERCHANNEL,
+       .pr_attach = lagg_lb_attach,
+    },
+    {
+       .pr_num = LAGG_PROTO_BROADCAST,
+       .pr_attach = lagg_bcast_attach,
+    },
 };
 
 SYSCTL_DECL(_net_link);
@@ -232,6 +255,36 @@ static moduledata_t lagg_mod = {
 DECLARE_MODULE(if_lagg, lagg_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 MODULE_VERSION(if_lagg, 1);
 
+static void
+lagg_proto_attach(struct lagg_softc *sc, lagg_proto pr)
+{
+
+       KASSERT(sc->sc_proto == LAGG_PROTO_NONE, ("%s: sc %p has proto",
+           __func__, sc));
+
+       if (sc->sc_ifflags & IFF_DEBUG)
+               if_printf(sc->sc_ifp, "using proto %u\n", pr);
+
+       lagg_protos[pr].pr_attach(sc);
+       sc->sc_proto = pr;
+}
+
+static void
+lagg_proto_detach(struct lagg_softc *sc)
+{
+       lagg_proto pr;
+
+       LAGG_WLOCK_ASSERT(sc);
+
+       pr = sc->sc_proto;
+       sc->sc_proto = LAGG_PROTO_NONE; 
+
+       if (lagg_protos[pr].pr_detach != NULL)
+               lagg_protos[pr].pr_detach(sc);
+       else
+               LAGG_WUNLOCK(sc);
+}
+
 /*
  * This routine is run via an vlan
  * config EVENT
@@ -284,7 +337,6 @@ lagg_clone_create(struct if_clone *ifc, 
        static const u_char eaddr[6];   /* 00:00:00:00:00:00 */
        struct sysctl_oid *oid;
        char num[14];                   /* sufficient for 32 bits */
-       int i;
 
        sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
        ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
@@ -324,14 +376,8 @@ lagg_clone_create(struct if_clone *ifc, 
        /* Hash all layers by default */
        sc->sc_flags = LAGG_F_HASHL2|LAGG_F_HASHL3|LAGG_F_HASHL4;
 
-       sc->sc_proto = LAGG_PROTO_NONE;
-       for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) {
-               if (lagg_protos[i].ti_proto == LAGG_PROTO_DEFAULT) {
-                       sc->sc_proto = lagg_protos[i].ti_proto;
-                       lagg_protos[i].ti_attach(sc);
-                       break;
-               }
-       }
+       lagg_proto_attach(sc, LAGG_PROTO_DEFAULT);
+
        LAGG_LOCK_INIT(sc);
        LAGG_CALLOUT_LOCK_INIT(sc);
        SLIST_INIT(&sc->sc_ports);
@@ -397,10 +443,7 @@ lagg_clone_destroy(struct ifnet *ifp)
        while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
                lagg_port_destroy(lp, 1);
        /* Unhook the aggregation protocol */
-       if (sc->sc_detach != NULL)
-               (*sc->sc_detach)(sc);
-       else
-               LAGG_WUNLOCK(sc);
+       lagg_proto_detach(sc);
 
        sysctl_ctx_free(&sc->ctx);
        ifmedia_removeall(&sc->sc_media);
@@ -980,7 +1023,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
        struct lagg_reqflags *rf = (struct lagg_reqflags *)data;
        struct ifreq *ifr = (struct ifreq *)data;
        struct lagg_port *lp;
-       const struct lagg_proto *proto;
        struct ifnet *tpif;
        struct thread *td = curthread;
        char *buf, *outbuf;
@@ -1028,32 +1070,14 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
                error = priv_check(td, PRIV_NET_LAGG);
                if (error)
                        break;
-               for (proto = lagg_protos; proto->ti_proto != LAGG_PROTO_NONE;
-                   proto++) {
-                       if (proto->ti_proto == ra->ra_proto) {
-                               if (sc->sc_ifflags & IFF_DEBUG)
-                                       printf("%s: using proto %u\n",
-                                           sc->sc_ifname, proto->ti_proto);
-                               break;
-                       }
-               }
-               if (proto->ti_proto == LAGG_PROTO_NONE) {
+               if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) {
                        error = EPROTONOSUPPORT;
                        break;
                }
-               /* Set to LAGG_PROTO_NONE during the attach. */
-               LAGG_WLOCK(sc);
-               if (sc->sc_proto != LAGG_PROTO_NONE) {
-                       sc->sc_proto = LAGG_PROTO_NONE;
-                       if (sc->sc_detach != NULL)
-                               sc->sc_detach(sc);
-                       else
-                               LAGG_WUNLOCK(sc);
-               }
-               proto->ti_attach(sc);
+
                LAGG_WLOCK(sc);
-               sc->sc_proto = proto->ti_proto;
-               LAGG_WUNLOCK(sc);
+               lagg_proto_detach(sc);
+               lagg_proto_attach(sc, ra->ra_proto);
                break;
        case SIOCGLAGGFLAGS:
                rf->rf_flags = sc->sc_flags;
@@ -1651,7 +1675,6 @@ lagg_rr_attach(struct lagg_softc *sc)
 {
        sc->sc_start = lagg_rr_start;
        sc->sc_input = lagg_rr_input;
-       sc->sc_detach = NULL;;
        sc->sc_port_create = NULL;
        sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX;
        sc->sc_seq = 0;
@@ -1704,7 +1727,6 @@ lagg_bcast_attach(struct lagg_softc *sc)
        sc->sc_port_create = NULL;
        sc->sc_port_destroy = NULL;
        sc->sc_linkstate = NULL;
-       sc->sc_detach = NULL;
        sc->sc_req = NULL;
        sc->sc_portreq = NULL;
 }
@@ -1779,7 +1801,6 @@ lagg_fail_attach(struct lagg_softc *sc)
        sc->sc_input = lagg_fail_input;
        sc->sc_port_create = NULL;
        sc->sc_port_destroy = NULL;
-       sc->sc_detach = NULL;
 }
 
 static int
@@ -1835,7 +1856,6 @@ lagg_lb_attach(struct lagg_softc *sc)
 
        lb = malloc(sizeof(struct lagg_lb), M_DEVBUF, M_WAITOK | M_ZERO);
 
-       sc->sc_detach = lagg_lb_detach;
        sc->sc_start = lagg_lb_start;
        sc->sc_input = lagg_lb_input;
        sc->sc_port_create = lagg_lb_port_create;
@@ -1942,7 +1962,6 @@ lagg_lacp_attach(struct lagg_softc *sc)
 {
        struct lagg_port *lp;
 
-       sc->sc_detach = lagg_lacp_detach;
        sc->sc_port_create = lacp_port_create;
        sc->sc_port_destroy = lacp_port_destroy;
        sc->sc_linkstate = lacp_linkstate;

Modified: head/sys/net/if_lagg.h
==============================================================================
--- head/sys/net/if_lagg.h      Fri Sep 26 10:47:57 2014        (r272169)
+++ head/sys/net/if_lagg.h      Fri Sep 26 11:01:04 2014        (r272170)
@@ -218,7 +218,6 @@ struct lagg_softc {
                                                           the lladdr on */
 
        /* lagg protocol callbacks */
-       void    (*sc_detach)(struct lagg_softc *);
        int     (*sc_start)(struct lagg_softc *, struct mbuf *);
        struct mbuf *(*sc_input)(struct lagg_softc *, struct lagg_port *,
                    struct mbuf *);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to