Fix multiple problems:

* A sign extension error creating the bridge ID corrupted the
    priority (always making it the maximum).
    * Do not catch STP packets on an interface for which STP is not
    enabled -- it's a violation of the spec, and causes STP to fail on
    neighboring bridges.
    * An optimization to bstp_input() -- some information is already
    known when we call it.

contributed anonymously.
This commit is contained in:
mrg 2009-01-18 10:28:55 +00:00
parent 3cafe960ea
commit c30587badd
3 changed files with 23 additions and 31 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: bridgestp.c,v 1.13 2007/12/25 18:33:44 perry Exp $ */
/* $NetBSD: bridgestp.c,v 1.14 2009/01/18 10:28:55 mrg Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.13 2007/12/25 18:33:44 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.14 2009/01/18 10:28:55 mrg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -580,10 +580,8 @@ bstp_acknowledge_topology_change(struct bridge_softc *sc,
}
struct mbuf *
bstp_input(struct ifnet *ifp, struct mbuf *m)
bstp_input(struct bridge_softc *sc, struct bridge_iflist *bif, struct mbuf *m)
{
struct bridge_softc *sc = ifp->if_bridge;
struct bridge_iflist *bif = NULL;
struct ether_header *eh;
struct bstp_tbpdu tpdu;
struct bstp_cbpdu cpdu;
@ -593,14 +591,8 @@ bstp_input(struct ifnet *ifp, struct mbuf *m)
eh = mtod(m, struct ether_header *);
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
if ((bif->bif_flags & IFBIF_STP) == 0)
continue;
if (bif->bif_ifp == ifp)
break;
}
if (bif == NULL)
goto out;
if ((bif->bif_flags & IFBIF_STP) == 0)
return (m);
len = ntohs(eh->ether_type);
if (len < sizeof(tpdu))
@ -835,12 +827,12 @@ bstp_initialization(struct bridge_softc *sc)
sc->sc_bridge_id =
(((uint64_t)sc->sc_bridge_priority) << 48) |
(((uint64_t)CLLADDR(mif->bif_ifp->if_sadl)[0]) << 40) |
(((uint64_t)CLLADDR(mif->bif_ifp->if_sadl)[1]) << 32) |
(CLLADDR(mif->bif_ifp->if_sadl)[2] << 24) |
(CLLADDR(mif->bif_ifp->if_sadl)[3] << 16) |
(CLLADDR(mif->bif_ifp->if_sadl)[4] << 8) |
(CLLADDR(mif->bif_ifp->if_sadl)[5]);
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[0]) << 40) |
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[1]) << 32) |
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[2]) << 24) |
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[3]) << 16) |
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[4]) << 8) |
(((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[5]) << 0);
sc->sc_designated_root = sc->sc_bridge_id;
sc->sc_root_path_cost = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bridge.c,v 1.63 2008/11/07 00:20:13 dyoung Exp $ */
/* $NetBSD: if_bridge.c,v 1.64 2009/01/18 10:28:55 mrg Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.63 2008/11/07 00:20:13 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.64 2009/01/18 10:28:55 mrg Exp $");
#include "opt_bridge_ipf.h"
#include "opt_inet.h"
@ -1449,15 +1449,15 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
eh = mtod(m, struct ether_header *);
if (m->m_flags & (M_BCAST|M_MCAST)) {
/* Tap off 802.1D packets; they do not get forwarded. */
if (memcmp(eh->ether_dhost, bstp_etheraddr,
ETHER_ADDR_LEN) == 0) {
m = bstp_input(ifp, m);
if (m == NULL)
return (NULL);
}
if (bif->bif_flags & IFBIF_STP) {
/* Tap off 802.1D packets; they do not get forwarded. */
if (memcmp(eh->ether_dhost, bstp_etheraddr,
ETHER_ADDR_LEN) == 0) {
m = bstp_input(sc, bif, m);
if (m == NULL)
return (NULL);
}
switch (bif->bif_state) {
case BSTP_IFSTATE_BLOCKING:
case BSTP_IFSTATE_LISTENING:

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bridgevar.h,v 1.12 2009/01/11 02:45:54 christos Exp $ */
/* $NetBSD: if_bridgevar.h,v 1.13 2009/01/18 10:28:55 mrg Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -313,7 +313,7 @@ struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
void bstp_initialization(struct bridge_softc *);
void bstp_stop(struct bridge_softc *);
struct mbuf *bstp_input(struct ifnet *, struct mbuf *);
struct mbuf *bstp_input(struct bridge_softc *, struct bridge_iflist *, struct mbuf *);
void bridge_enqueue(struct bridge_softc *, struct ifnet *, struct mbuf *,
int);