summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-05-24 07:51:54 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-05-24 07:51:54 +0000
commitc96e00f42bd82fc6ae8e02141aac174d6ff5dccc (patch)
tree911edbc066003167bcdfc42c5bcfa279543a3960 /sys/net
parentfd2f9a0f7f8d879591264cbd1781b81e6a4f0157 (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.c13
-rw-r--r--sys/net/if_trunk.c54
-rw-r--r--sys/net/if_trunk.h6
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 {