summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2008-11-08 01:00:02 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2008-11-08 01:00:02 +0000
commit110070b785df9e67a94b00788cfd4c22e202ada0 (patch)
tree95973cfbc1e77ef259faf74ede61d9e92f008434 /sys
parent9d594ad3960f203a99672bae0398bdcdf497711f (diff)
Take into account that our ether_input() already strips the
ethernet header. This lets us actually process the incoming LACP-Packets. It should now work with a lot more switches. At least a Catalyst 3500 seems happy. OK brad@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_trunk.c4
-rw-r--r--sys/net/trunklacp.c81
-rw-r--r--sys/net/trunklacp.h7
3 files changed, 48 insertions, 44 deletions
diff --git a/sys/net/if_trunk.c b/sys/net/if_trunk.c
index faa2ebf92ed..47c87a80d5d 100644
--- a/sys/net/if_trunk.c
+++ b/sys/net/if_trunk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_trunk.c,v 1.58 2008/11/04 13:44:11 brad Exp $ */
+/* $OpenBSD: if_trunk.c,v 1.59 2008/11/08 01:00:01 mpf Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -1638,7 +1638,7 @@ trunk_lacp_input(struct trunk_softc *tr, struct trunk_port *tp,
/* Tap off LACP control messages */
if (etype == ETHERTYPE_SLOW) {
- m = lacp_input(tp, m);
+ m = lacp_input(tp, eh, m);
if (m == NULL)
return (-1);
}
diff --git a/sys/net/trunklacp.c b/sys/net/trunklacp.c
index 35216d042d4..517c126222a 100644
--- a/sys/net/trunklacp.c
+++ b/sys/net/trunklacp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trunklacp.c,v 1.7 2008/10/24 04:44:52 brad Exp $ */
+/* $OpenBSD: trunklacp.c,v 1.8 2008/11/08 01:00:01 mpf Exp $ */
/* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
/* $FreeBSD:ieee8023ad_lacp.c,v 1.15 2008/03/16 19:25:30 thompsa Exp $ */
@@ -123,8 +123,10 @@ void lacp_aggregator_delref(struct lacp_softc *,
/* receive machine */
-int lacp_pdu_input(struct lacp_port *, struct mbuf *);
-int lacp_marker_input(struct lacp_port *, struct mbuf *);
+int lacp_pdu_input(struct lacp_port *,
+ struct ether_header *, struct mbuf *);
+int lacp_marker_input(struct lacp_port *,
+ struct ether_header *, struct mbuf *);
void lacp_sm_rx(struct lacp_port *, const struct lacpdu *);
void lacp_sm_rx_timer(struct lacp_port *);
void lacp_sm_rx_set_expired(struct lacp_port *);
@@ -219,25 +221,25 @@ const lacp_timer_func_t lacp_timer_funcs[LACP_NTIMER] = {
};
struct mbuf *
-lacp_input(struct trunk_port *tp, struct mbuf *m)
+lacp_input(struct trunk_port *tp, struct ether_header *eh, struct mbuf *m)
{
struct lacp_port *lp = LACP_PORT(tp);
u_int8_t subtype;
- if (m->m_pkthdr.len < sizeof(struct ether_header) + sizeof(subtype)) {
+ if (m->m_pkthdr.len < sizeof(subtype)) {
m_freem(m);
return (NULL);
}
+ subtype = *mtod(m, u_int8_t *);
- m_copydata(m, sizeof(struct ether_header), sizeof(subtype), &subtype);
switch (subtype) {
/* FALLTHROUGH */
case SLOWPROTOCOLS_SUBTYPE_LACP:
- lacp_pdu_input(lp, m);
+ lacp_pdu_input(lp, eh, m);
return (NULL);
case SLOWPROTOCOLS_SUBTYPE_MARKER:
- lacp_marker_input(lp, m);
+ lacp_marker_input(lp, eh, m);
return (NULL);
}
@@ -249,18 +251,13 @@ lacp_input(struct trunk_port *tp, struct mbuf *m)
* lacp_pdu_input: process lacpdu
*/
int
-lacp_pdu_input(struct lacp_port *lp, struct mbuf *m)
+lacp_pdu_input(struct lacp_port *lp, struct ether_header *eh, struct mbuf *m)
{
struct lacpdu *du;
int error = 0;
- if (m->m_pkthdr.len != sizeof(*du)) {
+ if (m->m_pkthdr.len != sizeof(*du))
goto bad;
- }
-
- if ((m->m_flags & M_MCAST) == 0) {
- goto bad;
- }
if (m->m_len < sizeof(*du)) {
m = m_pullup(m, sizeof(*du));
@@ -268,13 +265,11 @@ lacp_pdu_input(struct lacp_port *lp, struct mbuf *m)
return (ENOMEM);
}
}
-
du = mtod(m, struct lacpdu *);
- if (memcmp(&du->ldu_eh.ether_dhost,
- &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
+ if (memcmp(&eh->ether_dhost,
+ &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN))
goto bad;
- }
/*
* ignore the version for compatibility with
@@ -287,8 +282,8 @@ lacp_pdu_input(struct lacp_port *lp, struct mbuf *m)
#endif
/*
- * ignore tlv types for compatibility with
- * the future protocol revisions.
+ * ignore tlv types for compatibility with the
+ * future protocol revisions. (IEEE 802.3-2005 43.4.12)
*/
if (tlv_check(du, sizeof(*du), &du->ldu_tlv_actor,
lacp_info_tlv_template, 0)) {
@@ -370,6 +365,7 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
{
struct trunk_port *tp = lp->lp_trunk;
struct mbuf *m;
+ struct ether_header *eh;
struct lacpdu *du;
int error;
@@ -377,15 +373,19 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
if (m == NULL) {
return (ENOMEM);
}
- m->m_len = m->m_pkthdr.len = sizeof(*du);
+ m->m_len = m->m_pkthdr.len = sizeof(*eh) + sizeof(*du);
+ eh = mtod(m, struct ether_header *);
+ memcpy(&eh->ether_dhost, ethermulticastaddr_slowprotocols,
+ ETHER_ADDR_LEN);
+ memcpy(&eh->ether_shost, tp->tp_lladdr, ETHER_ADDR_LEN);
+ eh->ether_type = htons(ETHERTYPE_SLOW);
+
+ m->m_data += sizeof(*eh);
du = mtod(m, struct lacpdu *);
- memset(du, 0, sizeof(*du));
+ m->m_data -= sizeof(*eh);
- memcpy(&du->ldu_eh.ether_dhost, ethermulticastaddr_slowprotocols,
- ETHER_ADDR_LEN);
- memcpy(&du->ldu_eh.ether_shost, tp->tp_lladdr, ETHER_ADDR_LEN);
- du->ldu_eh.ether_type = htons(ETHERTYPE_SLOW);
+ memset(du, 0, sizeof(*du));
du->ldu_sph.sph_subtype = SLOWPROTOCOLS_SUBTYPE_LACP;
du->ldu_sph.sph_version = 1;
@@ -421,6 +421,7 @@ lacp_xmit_marker(struct lacp_port *lp)
{
struct trunk_port *tp = lp->lp_trunk;
struct mbuf *m;
+ struct ether_header *eh;
struct markerdu *mdu;
int error;
@@ -428,15 +429,19 @@ lacp_xmit_marker(struct lacp_port *lp)
if (m == NULL) {
return (ENOMEM);
}
- m->m_len = m->m_pkthdr.len = sizeof(*mdu);
+ m->m_len = m->m_pkthdr.len = sizeof(*eh) + sizeof(*mdu);
+ eh = mtod(m, struct ether_header *);
+ memcpy(&eh->ether_dhost, ethermulticastaddr_slowprotocols,
+ ETHER_ADDR_LEN);
+ memcpy(&eh->ether_shost, tp->tp_lladdr, ETHER_ADDR_LEN);
+ eh->ether_type = htons(ETHERTYPE_SLOW);
+
+ m->m_data += sizeof(*eh);
mdu = mtod(m, struct markerdu *);
- memset(mdu, 0, sizeof(*mdu));
+ m->m_data -= sizeof(*eh);
- memcpy(&mdu->mdu_eh.ether_dhost, ethermulticastaddr_slowprotocols,
- ETHER_ADDR_LEN);
- memcpy(&mdu->mdu_eh.ether_shost, tp->tp_lladdr, ETHER_ADDR_LEN);
- mdu->mdu_eh.ether_type = htons(ETHERTYPE_SLOW);
+ memset(mdu, 0, sizeof(*mdu));
mdu->mdu_sph.sph_subtype = SLOWPROTOCOLS_SUBTYPE_MARKER;
mdu->mdu_sph.sph_version = 1;
@@ -1251,7 +1256,7 @@ lacp_sm_mux(struct lacp_port *lp)
{
enum lacp_mux_state new_state;
int p_sync =
- (lp->lp_partner.lip_state & LACP_STATE_SYNC) != 0;
+ (lp->lp_partner.lip_state & LACP_STATE_SYNC) != 0;
int p_collecting =
(lp->lp_partner.lip_state & LACP_STATE_COLLECTING) != 0;
enum lacp_selected selected = lp->lp_selected;
@@ -1649,7 +1654,7 @@ lacp_run_timers(struct lacp_port *lp)
}
int
-lacp_marker_input(struct lacp_port *lp, struct mbuf *m)
+lacp_marker_input(struct lacp_port *lp, struct ether_header *eh, struct mbuf *m)
{
struct lacp_softc *lsc = lp->lp_lsc;
struct trunk_port *tp = lp->lp_trunk;
@@ -1675,7 +1680,7 @@ lacp_marker_input(struct lacp_port *lp, struct mbuf *m)
mdu = mtod(m, struct markerdu *);
- if (memcmp(&mdu->mdu_eh.ether_dhost,
+ if (memcmp(&eh->ether_dhost,
&ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
goto bad;
}
@@ -1691,9 +1696,9 @@ lacp_marker_input(struct lacp_port *lp, struct mbuf *m)
goto bad;
}
mdu->mdu_tlv.tlv_type = MARKER_TYPE_RESPONSE;
- memcpy(&mdu->mdu_eh.ether_dhost,
+ memcpy(&eh->ether_dhost,
&ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN);
- memcpy(&mdu->mdu_eh.ether_shost,
+ memcpy(&eh->ether_shost,
tp->tp_lladdr, ETHER_ADDR_LEN);
error = trunk_enqueue(lp->lp_ifp, m);
break;
diff --git a/sys/net/trunklacp.h b/sys/net/trunklacp.h
index d9206602076..19618cf1d4b 100644
--- a/sys/net/trunklacp.h
+++ b/sys/net/trunklacp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: trunklacp.h,v 1.3 2008/10/12 19:03:12 mpf Exp $ */
+/* $OpenBSD: trunklacp.h,v 1.4 2008/11/08 01:00:01 mpf Exp $ */
/* $NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $ */
/*
@@ -125,7 +125,6 @@ struct lacp_collectorinfo {
} __packed;
struct lacpdu {
- struct ether_header ldu_eh;
struct slowprothdr ldu_sph;
struct tlvhdr ldu_tlv_actor;
@@ -149,7 +148,6 @@ struct lacp_markerinfo {
} __packed;
struct markerdu {
- struct ether_header mdu_eh;
struct slowprothdr mdu_sph;
struct tlvhdr mdu_tlv;
@@ -257,7 +255,8 @@ struct lacp_softc {
#define LACP_UNLOCK(_lsc) mtx_unlock(&(_lsc)->lsc_mtx)
#define LACP_LOCK_ASSERT(_lsc) mtx_assert(&(_lsc)->lsc_mtx, MA_OWNED)
-struct mbuf *lacp_input(struct trunk_port *, struct mbuf *);
+struct mbuf *lacp_input(struct trunk_port *,
+ struct ether_header *, struct mbuf *);
struct trunk_port *lacp_select_tx_port(struct trunk_softc *, struct mbuf *);
int lacp_attach(struct trunk_softc *);
int lacp_detach(struct trunk_softc *);