summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-01-31 06:20:20 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-01-31 06:20:20 +0000
commit1d9519591e87ace4bba7e7aef4ec611f88b9d4cc (patch)
tree3bdc1862db862e144a0b3861bd3f5e6af15bea3f /sys
parent57f2b343dcf2b59e8b9cad0333ce1a803202c2be (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@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_trunk.c36
-rw-r--r--sys/net/if_trunk.h7
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 {