diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-05-24 07:51:54 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-05-24 07:51:54 +0000 |
commit | c96e00f42bd82fc6ae8e02141aac174d6ff5dccc (patch) | |
tree | 911edbc066003167bcdfc42c5bcfa279543a3960 /sys/net | |
parent | fd2f9a0f7f8d879591264cbd1781b81e6a4f0157 (diff) |
support trunk stacking (trunks as trunk ports) and some fixes
ok brad@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_ethersubr.c | 13 | ||||
-rw-r--r-- | sys/net/if_trunk.c | 54 | ||||
-rw-r--r-- | sys/net/if_trunk.h | 6 |
3 files changed, 57 insertions, 16 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 4b440cb2dd1..08f93d7425e 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.90 2005/05/24 02:45:17 reyk Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.91 2005/05/24 07:51:53 reyk Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -612,7 +612,7 @@ ether_input(ifp, eh, m) { struct ifqueue *inq; u_int16_t etype; - int s, llcfound = 0; + int s, llcfound = 0, i = 0; struct llc *l; struct arpcom *ac; #if NPPPOE > 0 @@ -621,9 +621,14 @@ ether_input(ifp, eh, m) #if NTRUNK > 0 /* Handle input from a trunk port */ - if (ifp->if_type == IFT_IEEE8023ADLAG) { - if (trunk_input(ifp, eh, m) != 0) + while (ifp->if_type == IFT_IEEE8023ADLAG) { + if (++i > TRUNK_MAX_STACKING || + trunk_input(ifp, eh, m) != 0) { + if (m) + m_freem(m); return; + } + /* Has been set to the trunk interface */ ifp = m->m_pkthdr.rcvif; } diff --git a/sys/net/if_trunk.c b/sys/net/if_trunk.c index e0c7290b63f..c7b8d42a4c5 100644 --- a/sys/net/if_trunk.c +++ b/sys/net/if_trunk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.c,v 1.1 2005/05/24 02:45:17 reyk Exp $ */ +/* $OpenBSD: if_trunk.c,v 1.2 2005/05/24 07:51:53 reyk Exp $ */ /* * Copyright (c) 2005 Reyk Floeter <reyk@vantronix.net> @@ -61,6 +61,7 @@ int trunk_port_destroy(struct trunk_port *); void trunk_port_watchdog(struct ifnet *); int trunk_port_ioctl(struct ifnet *, u_long, caddr_t); struct trunk_port *trunk_port_get(struct trunk_softc *, struct ifnet *); +int trunk_port_checkstacking(struct trunk_softc *); void trunk_port2req(struct trunk_port *, struct trunk_reqport *); int trunk_ioctl(struct ifnet *, u_long, caddr_t); void trunk_start(struct ifnet *); @@ -162,12 +163,17 @@ trunk_clone_destroy(struct ifnet *ifp) { struct trunk_softc *tr = (struct trunk_softc *)ifp->if_softc; struct trunk_port *tp; - int error; + int error, s; + + s = splnet(); /* Shutdown and remove trunk ports, return on error */ - while ((tp = SLIST_FIRST(&tr->tr_ports)) != NULL) - if ((error = trunk_port_destroy(tp)) != 0) + while ((tp = SLIST_FIRST(&tr->tr_ports)) != NULL) { + if ((error = trunk_port_destroy(tp)) != 0) { + splx(s); return (error); + } + } ifmedia_delete_instance(&tr->tr_media, IFM_INST_ANY); #if NBPFILTER > 0 @@ -179,6 +185,8 @@ trunk_clone_destroy(struct ifnet *ifp) SLIST_REMOVE(&trunk_list, tr, trunk_softc, tr_entries); free(tr, M_DEVBUF); + splx(s); + return (0); } @@ -200,6 +208,7 @@ trunk_lladdr(struct trunk_softc *tr, u_int8_t *lladdr) int trunk_port_create(struct trunk_softc *tr, struct ifnet *ifp) { + struct trunk_softc *tr_ptr; struct trunk_port *tp; int error = 0; @@ -228,6 +237,18 @@ trunk_port_create(struct trunk_softc *tr, struct ifnet *ifp) bzero(tp, sizeof(struct trunk_port)); + /* Check if port is a stacked trunk */ + SLIST_FOREACH(tr_ptr, &trunk_list, tr_entries) { + if (ifp == &tr_ptr->tr_ac.ac_if) { + tp->tp_flags |= TRUNK_PORT_STACK; + if (trunk_port_checkstacking(tr_ptr) >= + TRUNK_MAX_STACKING) { + free(tp, M_DEVBUF); + return (E2BIG); + } + } + } + /* Change the interface type */ tp->tp_iftype = ifp->if_type; ifp->if_type = IFT_IEEE8023ADLAG; @@ -242,7 +263,7 @@ trunk_port_create(struct trunk_softc *tr, struct ifnet *ifp) if (SLIST_EMPTY(&tr->tr_ports)) { tr->tr_primary = tp; - tp->tp_flags = TRUNK_PORT_MASTER; + tp->tp_flags |= TRUNK_PORT_MASTER; trunk_lladdr(tr, ((struct arpcom *)ifp)->ac_enaddr); } @@ -254,6 +275,23 @@ trunk_port_create(struct trunk_softc *tr, struct ifnet *ifp) } int +trunk_port_checkstacking(struct trunk_softc *tr) +{ + struct trunk_softc *tr_ptr; + struct trunk_port *tp; + int m = 0; + + SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) { + if (tp->tp_flags & TRUNK_PORT_STACK) { + tr_ptr = (struct trunk_softc *)tp->tp_if->if_softc; + m = MAX(m, trunk_port_checkstacking(tr_ptr)); + } + } + + return (m + 1); +} + +int trunk_port_destroy(struct trunk_port *tp) { struct trunk_softc *tr = (struct trunk_softc *)tp->tp_trunk; @@ -366,9 +404,7 @@ trunk_port_ifdetach(struct ifnet *ifp) { struct trunk_port *tp; - if (SLIST_FIRST(&trunk_list) == NULL) - return; - if ((tp = trunk_port_get(NULL, ifp)) == NULL) + if ((tp = (struct trunk_port *)ifp->if_tp) == NULL) return; trunk_port_destroy(tp); @@ -652,8 +688,6 @@ trunk_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m) bad: trifp->if_ierrors++; - if (m) - m_free(m); return (error); } diff --git a/sys/net/if_trunk.h b/sys/net/if_trunk.h index 42c6d5fa264..d41497e5d1e 100644 --- a/sys/net/if_trunk.h +++ b/sys/net/if_trunk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.h,v 1.1 2005/05/24 02:45:17 reyk Exp $ */ +/* $OpenBSD: if_trunk.h,v 1.2 2005/05/24 07:51:53 reyk Exp $ */ /* * Copyright (c) 2005 Reyk Floeter <reyk@vantronix.net> @@ -25,12 +25,14 @@ #define TRUNK_MAX_PORTS 32 /* logically */ #define TRUNK_MAX_NAMESIZE 32 /* name of a protocol */ +#define TRUNK_MAX_STACKING 4 /* maximum number of stacked trunks */ /* Port flags */ #define TRUNK_PORT_SLAVE 0x00000000 /* normal enslaved port */ #define TRUNK_PORT_MASTER 0x00000001 /* primary port */ +#define TRUNK_PORT_STACK 0x00000002 /* stacked trunk port */ #define TRUNK_PORT_GLOBAL 0x80000000 /* IOCTL: global flag */ -#define TRUNK_PORT_BITS "\20\01MASTER" +#define TRUNK_PORT_BITS "\20\01MASTER\02STACK" /* Supported trunk PROTOs */ enum trunk_proto { |