diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-01-31 06:20:20 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-01-31 06:20:20 +0000 |
commit | 1d9519591e87ace4bba7e7aef4ec611f88b9d4cc (patch) | |
tree | 3bdc1862db862e144a0b3861bd3f5e6af15bea3f | |
parent | 57f2b343dcf2b59e8b9cad0333ce1a803202c2be (diff) |
handle the full duplex link state in trunk(4). load sharing trunks
with at least two ports are always handled as full fuplex links. this
change will allow trunks as edge ports in a rstp bridge(4).
ok brad@ pyr@
-rw-r--r-- | sys/net/if_trunk.c | 36 | ||||
-rw-r--r-- | sys/net/if_trunk.h | 7 |
2 files changed, 30 insertions, 13 deletions
diff --git a/sys/net/if_trunk.c b/sys/net/if_trunk.c index 3723febfb03..c84ff4a670a 100644 --- a/sys/net/if_trunk.c +++ b/sys/net/if_trunk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.c,v 1.29 2006/05/28 01:14:15 reyk Exp $ */ +/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */ /* * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> @@ -250,17 +250,21 @@ int trunk_capabilities(struct trunk_softc *tr) { struct trunk_port *tp; - int cap = ~0; + int cap = ~0, priv; + /* Preserve private capabilities */ + priv = tr->tr_capabilities & IFCAP_TRUNK_MASK; + + /* Get capabilities from the trunk ports */ SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) cap &= tp->tp_capabilities; if (tr->tr_ifflags & IFF_DEBUG) { printf("%s: capabilities 0x%08x\n", - tr->tr_ifname, cap == ~0 ? 0 : cap); + tr->tr_ifname, cap == ~0 ? priv : (cap | priv)); } - return (cap == ~0 ? 0 : cap); + return (cap == ~0 ? priv : (cap | priv)); } void @@ -1013,14 +1017,10 @@ struct trunk_port * trunk_link_active(struct trunk_softc *tr, struct trunk_port *tp) { struct trunk_port *tp_next, *rval = NULL; - int new_link = LINK_STATE_UP; + int new_link = LINK_STATE_DOWN; /* * Search a port which reports an active link state. - * Normally, this should be LINK_STATE_UP but not all - * drivers seem to report this correctly so we assume - * that LINK_STATE_DOWN is the opposite from - * LINK_STATE_UNKNOWN and LINK_STATE_UP. */ if (tp == NULL) @@ -1044,8 +1044,20 @@ trunk_link_active(struct trunk_softc *tr, struct trunk_port *tp) } found: - if (rval == NULL) - new_link = LINK_STATE_DOWN; + if (rval != NULL) { + /* + * The IEEE 802.1D standard assumes that a trunk with + * multiple ports is always full duplex. This is valid + * for load sharing trunks and if at least two links + * are active. Unfortunately, checking the latter would + * be too expensive at this point. + */ + if ((tr->tr_capabilities & IFCAP_TRUNK_FULLDUPLEX) && + (tr->tr_count > 1)) + new_link = LINK_STATE_FULL_DUPLEX; + else + new_link = rval->tp_link_state; + } if (tr->tr_ac.ac_if.if_link_state != new_link) { tr->tr_ac.ac_if.if_link_state = new_link; @@ -1069,6 +1081,7 @@ trunk_rr_attach(struct trunk_softc *tr) tr->tr_input = trunk_rr_input; tr->tr_port_create = NULL; tr->tr_port_destroy = trunk_rr_port_destroy; + tr->tr_capabilities = IFCAP_TRUNK_FULLDUPLEX; tp = SLIST_FIRST(&tr->tr_ports); tr->tr_psc = (caddr_t)tp; @@ -1227,6 +1240,7 @@ trunk_lb_attach(struct trunk_softc *tr) tr->tr_input = trunk_lb_input; tr->tr_port_create = trunk_lb_port_create; tr->tr_port_destroy = trunk_lb_port_destroy; + tr->tr_capabilities = IFCAP_TRUNK_FULLDUPLEX; lb->lb_key = arc4random(); tr->tr_psc = (caddr_t)lb; diff --git a/sys/net/if_trunk.h b/sys/net/if_trunk.h index 92a70187a26..0ab4ed719f2 100644 --- a/sys/net/if_trunk.h +++ b/sys/net/if_trunk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.h,v 1.10 2006/05/28 01:14:15 reyk Exp $ */ +/* $OpenBSD: if_trunk.h,v 1.11 2007/01/31 06:20:19 reyk Exp $ */ /* * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> @@ -115,7 +115,7 @@ struct trunk_port { #define tp_capabilities tp_if->if_capabilities /* capabilities */ #define TRUNK_PORTACTIVE(_tp) ( \ - ((_tp)->tp_link_state != LINK_STATE_DOWN) && \ + (LINK_STATE_IS_UP((_tp)->tp_link_state)) && \ ((_tp)->tp_ifflags & IFF_UP) \ ) @@ -168,6 +168,9 @@ struct trunk_softc { #define tr_ifname tr_ac.ac_if.if_xname /* name */ #define tr_capabilities tr_ac.ac_if.if_capabilities /* capabilities */ +#define IFCAP_TRUNK_MASK 0xffff0000 /* private capabilities */ +#define IFCAP_TRUNK_FULLDUPLEX 0x00010000 /* full duplex with >1 ports */ + /* Private data used by the loadbalancing protocol */ #define TRUNK_LB_MAXKEYS 8 struct trunk_lb { |