This diff changes the if_bridge pointer of an interface (struct ifnet) to 
not point to "the bridge" but to its own "bridge interface" configuration.
Should be safe because an interface can only be part of one bridge.

This way all the LIST_FOREACH lineair searches in the bridge code can be 
replaced.  There are also two of those in the forwarding path so this diff 
should make the bridge faster, especially with lots of interfaces.

I've renamed it to "if_bridge_port" to smoke out all users and because 
it's clearer.  (my fingers itch to rename "bridge_iflist" too as noted in 
the diff :-) )

Most of the diff is mechanical.  The if_ether.c change got pretty hairy 
though and could some more eyes.

And the whole thing could use some substantial testing...



Index: sys/dev/isa/if_ie.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/if_ie.c,v
retrieving revision 1.35
diff -u -r1.35 if_ie.c
--- sys/dev/isa/if_ie.c 28 Nov 2008 02:44:17 -0000      1.35
+++ sys/dev/isa/if_ie.c 24 Jun 2011 18:29:18 -0000
@@ -1054,16 +1054,16 @@
                 */
 #if NBPFILTER > 0
                *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
-                   (sc->sc_arpcom.ac_if.if_bridge != NULL);
+                   (sc->sc_arpcom.ac_if.if_bridge_port != NULL);
 #else
-               *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
+               *to_bpf = (sc->sc_arpcom.ac_if.if_bridge_port != NULL);
 #endif
                /* If for us, accept and hand up to BPF */
                if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
                        return 1;
 
 #if NBPFILTER > 0
-               if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
+               if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge_port == NULL)
                        *to_bpf = 2; /* we don't need to see it */
 #endif
 
@@ -1095,9 +1095,9 @@
                 */
 #if NBPFILTER > 0
                *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
-                   (sc->sc_arpcom.ac_if.if_bridge != NULL);
+                   (sc->sc_arpcom.ac_if.if_bridge_port != NULL);
 #else
-               *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
+               *to_bpf = (sc->sc_arpcom.ac_if.if_bridge_port != NULL);
 #endif
                /* We want to see multicasts. */
                if (eh->ether_dhost[0] & 1)
@@ -1109,7 +1109,7 @@
 
                /* Anything else goes to BPF but nothing else. */
 #if NBPFILTER > 0
-               if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
+               if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge_port == NULL)
                        *to_bpf = 2;
 #endif
                return 1;
Index: sys/net/bridgestp.c
===================================================================
RCS file: /cvs/src/sys/net/bridgestp.c,v
retrieving revision 1.39
diff -u -r1.39 bridgestp.c
--- sys/net/bridgestp.c 20 Nov 2010 14:23:09 -0000      1.39
+++ sys/net/bridgestp.c 24 Jun 2011 18:29:18 -0000
@@ -1644,7 +1644,7 @@
 
        if (ifp->if_type == IFT_BRIDGE)
                return;
-       sc = (struct bridge_softc *)ifp->if_bridge;
+       sc = ((struct bridge_iflist *)ifp->if_bridge_port)->bridge_sc;
 
        s = splnet();
        LIST_FOREACH(p, &sc->sc_iflist, next) {
@@ -2133,15 +2133,8 @@
                        err = ENOENT;
                        break;
                }
-               if ((caddr_t)sc != ifs->if_bridge) {
-                       err = ESRCH;
-                       break;
-               }
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (p->ifp == ifs)
-                               break;
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        err = ESRCH;
                        break;
                }
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.234
diff -u -r1.234 if.c
--- sys/net/if.c        13 Mar 2011 15:31:41 -0000      1.234
+++ sys/net/if.c        24 Jun 2011 18:29:18 -0000
@@ -531,7 +531,7 @@
 
 #if NBRIDGE > 0
        /* Remove the interface from any bridge it is part of.  */
-       if (ifp->if_bridge)
+       if (ifp->if_bridge_port)
                bridge_ifdetach(ifp);
 #endif
 
@@ -1101,7 +1101,7 @@
                carp_carpdev_state(ifp);
 #endif
 #if NBRIDGE > 0
-       if (ifp->if_bridge)
+       if (ifp->if_bridge_port)
                bstp_ifstate(ifp);
 #endif
        rt_ifmsg(ifp);
@@ -1137,7 +1137,7 @@
                carp_carpdev_state(ifp);
 #endif
 #if NBRIDGE > 0
-       if (ifp->if_bridge)
+       if (ifp->if_bridge_port)
                bstp_ifstate(ifp);
 #endif
        rt_ifmsg(ifp);
Index: sys/net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.122
diff -u -r1.122 if.h
--- sys/net/if.h        13 Mar 2011 15:31:41 -0000      1.122
+++ sys/net/if.h        24 Jun 2011 18:29:18 -0000
@@ -241,7 +241,7 @@
        char    if_xname[IFNAMSIZ];     /* external name (name + unit) */
        int     if_pcount;              /* number of promiscuous listeners */
        caddr_t if_bpf;                 /* packet filter structure */
-       caddr_t if_bridge;              /* bridge structure */
+       caddr_t if_bridge_port;         /* used by bridge ports */
        caddr_t if_tp;                  /* used by trunk ports */
        caddr_t if_pf_kif;              /* pf interface abstraction */
        union {
Index: sys/net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.192
diff -u -r1.192 if_bridge.c
--- sys/net/if_bridge.c 16 May 2011 20:06:28 -0000      1.192
+++ sys/net/if_bridge.c 24 Jun 2011 18:29:18 -0000
@@ -273,7 +273,7 @@
        if (p->bif_flags & IFBIF_STP)
                bstp_delete(p->bif_stp);
 
-       p->ifp->if_bridge = NULL;
+       p->ifp->if_bridge_port = NULL;
        error = ifpromisc(p->ifp, 0);
 
        LIST_REMOVE(p, next);
@@ -310,11 +310,7 @@
                        error = ENOENT;
                        break;
                }
-               if (ifs->if_bridge == (caddr_t)sc) {
-                       error = EEXIST;
-                       break;
-               }
-               if (ifs->if_bridge != NULL) {
+               if (ifs->if_bridge_port != NULL) {
                        error = EBUSY;
                        break;
                }
@@ -384,28 +380,28 @@
                        break;
                }
 
+               p->bridge_sc = sc;
                p->ifp = ifs;
                p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
                SIMPLEQ_INIT(&p->bif_brlin);
                SIMPLEQ_INIT(&p->bif_brlout);
-               ifs->if_bridge = (caddr_t)sc;
+               ifs->if_bridge_port = (caddr_t)p;
                LIST_INSERT_HEAD(&sc->sc_iflist, p, next);
                break;
        case SIOCBRDGDEL:
                if ((error = suser(curproc, 0)) != 0)
                        break;
-
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
-                           sizeof(p->ifp->if_xname)) == 0) {
-                               error = bridge_delete(sc, p);
-                               break;
-                       }
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               ifs = ifunit(req->ifbr_ifsname);
+               if (ifs == NULL) {
                        error = ENOENT;
                        break;
                }
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
+                       error = ESRCH;
+                       break;
+               }
+               error = bridge_delete(sc, p);
                break;
        case SIOCBRDGIFS:
                error = bridge_bifconf(sc, (struct ifbifconf *)data);
@@ -418,11 +414,7 @@
                        error = ENOENT;
                        break;
                }
-               if (ifs->if_bridge == (caddr_t)sc) {
-                       error = EEXIST;
-                       break;
-               }
-               if (ifs->if_bridge != NULL) {
+               if (ifs->if_bridge_port != NULL) {
                        error = EBUSY;
                        break;
                }
@@ -467,15 +459,8 @@
                        error = ENOENT;
                        break;
                }
-               if ((caddr_t)sc != ifs->if_bridge) {
-                       error = ESRCH;
-                       break;
-               }
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (p->ifp == ifs)
-                               break;
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        error = ESRCH;
                        break;
                }
@@ -515,15 +500,8 @@
                        error = ENOENT;
                        break;
                }
-               if ((caddr_t)sc != ifs->if_bridge) {
-                       error = ESRCH;
-                       break;
-               }
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (p->ifp == ifs)
-                               break;
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        error = ESRCH;
                        break;
                }
@@ -561,15 +539,13 @@
        case SIOCBRDGSADDR:
                if ((error = suser(curproc, 0)) != 0)
                        break;
-
                ifs = ifunit(bareq->ifba_ifsname);
                if (ifs == NULL) {                      /* no such interface */
                        error = ENOENT;
                        break;
                }
-
-               if (ifs->if_bridge == NULL ||
-                   ifs->if_bridge != (caddr_t)sc) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        error = ESRCH;
                        break;
                }
@@ -626,16 +602,8 @@
                        error = ENOENT;
                        break;
                }
-               if (ifs->if_bridge == NULL ||
-                   ifs->if_bridge != (caddr_t)sc) {
-                       error = ESRCH;
-                       break;
-               }
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (p->ifp == ifs)
-                               break;
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        error = ESRCH;
                        break;
                }
@@ -664,16 +632,8 @@
                        error = ENOENT;
                        break;
                }
-               if (ifs->if_bridge == NULL ||
-                   ifs->if_bridge != (caddr_t)sc) {
-                       error = ESRCH;
-                       break;
-               }
-               LIST_FOREACH(p, &sc->sc_iflist, next) {
-                       if (p->ifp == ifs)
-                               break;
-               }
-               if (p == LIST_END(&sc->sc_iflist)) {
+               p = (struct bridge_iflist *)ifs->if_bridge_port;
+               if (p == NULL || p->bridge_sc != sc) {
                        error = ESRCH;
                        break;
                }
@@ -731,51 +691,49 @@
 void
 bridge_ifdetach(struct ifnet *ifp)
 {
-       struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+       struct bridge_softc *sc;
        struct bridge_iflist *bif;
 
-       LIST_FOREACH(bif, &sc->sc_iflist, next)
-               if (bif->ifp == ifp) {
-                       bridge_delete(sc, bif);
-                       break;
-               }
+       bif = (struct bridge_iflist *)ifp->if_bridge_port;
+       sc = bif->bridge_sc;
+
+       bridge_delete(sc, bif);
 }
 
 void
 bridge_update(struct ifnet *ifp, struct ether_addr *ea, int delete)
 {
-       struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+       struct bridge_softc *sc;
        struct bridge_iflist *bif;
        u_int8_t *addr;
 
        addr = (u_int8_t *)ea;
 
-       LIST_FOREACH(bif, &sc->sc_iflist, next)
-               if (bif->ifp == ifp) {
-                       /*
-                        * Update the bridge interface if it is in
-                        * the learning state.
-                        */
-                       if ((bif->bif_flags & IFBIF_LEARNING) &&
-                           (ETHER_IS_MULTICAST(addr) == 0) &&
-                           !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 &&
-                           addr[3] == 0 && addr[4] == 0 && addr[5] == 0)) {
-                               /* Care must be taken with spanning tree */
-                               if ((bif->bif_flags & IFBIF_STP) &&
-                                   (bif->bif_state == BSTP_IFSTATE_DISCARDING))
-                                       return;
-
-                               /* Delete the address from the bridge */
-                               bridge_rtdaddr(sc, ea);
+       bif = (struct bridge_iflist *)ifp->if_bridge_port;
+       sc = bif->bridge_sc;
 
-                               if (!delete) {
-                                       /* Update the bridge table */
-                                       bridge_rtupdate(sc, ea, ifp, 0,
-                                           IFBAF_DYNAMIC);
-                               }
-                       }
+       /*
+        * Update the bridge interface if it is in
+        * the learning state.
+        */
+       if ((bif->bif_flags & IFBIF_LEARNING) &&
+           (ETHER_IS_MULTICAST(addr) == 0) &&
+           !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 &&
+           addr[3] == 0 && addr[4] == 0 && addr[5] == 0)) {
+               /* Care must be taken with spanning tree */
+               if ((bif->bif_flags & IFBIF_STP) &&
+                   (bif->bif_state == BSTP_IFSTATE_DISCARDING))
                        return;
+
+               /* Delete the address from the bridge */
+               bridge_rtdaddr(sc, ea);
+
+               if (!delete) {
+                       /* Update the bridge table */
+                       bridge_rtupdate(sc, ea, ifp, 0, IFBAF_DYNAMIC);
                }
+       }
+       return;
 }
 
 int
@@ -879,13 +837,8 @@
        ifp = ifunit(bc->ifbrl_ifsname);
        if (ifp == NULL)
                return (ENOENT);
-       if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc)
-               return (ESRCH);
-       LIST_FOREACH(ifl, &sc->sc_iflist, next) {
-               if (ifl->ifp == ifp)
-                       break;
-       }
-       if (ifl == LIST_END(&sc->sc_iflist))
+       ifl = (struct bridge_iflist *)ifp->if_bridge_port;
+       if (ifl == NULL || ifl->bridge_sc != sc)
                return (ESRCH);
 
        SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) {
@@ -1005,11 +958,11 @@
 #endif /* IPSEC */
 
        /* ifp must be a member interface of the bridge. */ 
-       sc = (struct bridge_softc *)ifp->if_bridge;
-       if (sc == NULL) {
+       if (ifp->if_bridge_port == NULL) {
                m_freem(m);
                return (EINVAL);
        }
+       sc = ((struct bridge_iflist *)ifp->if_bridge_port)->bridge_sc;
 
        if (m->m_len < sizeof(*eh)) {
                m = m_pullup(m, sizeof(*eh));
@@ -1207,15 +1160,7 @@
        sc->sc_if.if_ipackets++;
        sc->sc_if.if_ibytes += m->m_pkthdr.len;
 
-       LIST_FOREACH(ifl, &sc->sc_iflist, next)
-               if (ifl->ifp == src_if)
-                       break;
-
-       if (ifl == LIST_END(&sc->sc_iflist)) {
-               m_freem(m);
-               return;
-       }
-
+       ifl = (struct bridge_iflist *)src_if->if_bridge_port;
        if ((ifl->bif_flags & IFBIF_STP) &&
            (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) {
                m_freem(m);
@@ -1327,14 +1272,7 @@
                m_freem(m);
                return;
        }
-       LIST_FOREACH(ifl, &sc->sc_iflist, next) {
-               if (ifl->ifp == dst_if)
-                       break;
-       }
-       if (ifl == LIST_END(&sc->sc_iflist)) {
-               m_freem(m);
-               return;
-       }
+       ifl = (struct bridge_iflist *)dst_if->if_bridge_port;
        if ((ifl->bif_flags & IFBIF_STP) &&
            (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) {
                m_freem(m);
@@ -1379,7 +1317,7 @@
        /*
         * Make sure this interface is a bridge member.
         */
-       if (ifp == NULL || ifp->if_bridge == NULL || m == NULL)
+       if (ifp == NULL || ifp->if_bridge_port == NULL || m == NULL)
                return (m);
 
        if ((m->m_flags & M_PKTHDR) == 0)
@@ -1387,17 +1325,11 @@
 
        m->m_flags &= ~M_PROTO1;        /* Loop prevention */
 
-       sc = (struct bridge_softc *)ifp->if_bridge;
+       ifl = (struct bridge_iflist *)ifp->if_bridge_port;
+       sc = ifl->bridge_sc;
        if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
                return (m);
 
-       LIST_FOREACH(ifl, &sc->sc_iflist, next) {
-               if (ifl->ifp == ifp)
-                       break;
-       }
-       if (ifl == LIST_END(&sc->sc_iflist))
-               return (m);
-
 #if NBPFILTER > 0
        if (sc->sc_if.if_bpf)
                bpf_mtap_hdr(sc->sc_if.if_bpf, (caddr_t)eh,
@@ -1999,10 +1931,11 @@
 void
 bridge_rtagenode(struct ifnet *ifp, int age)
 {
-       struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+       struct bridge_softc *sc;
        struct bridge_rtnode *n;
        int i;
 
+       sc = ((struct bridge_iflist *)ifp->if_bridge_port)->bridge_sc;
        if (sc == NULL)
                return;
 
Index: sys/net/if_bridge.h
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.h,v
retrieving revision 1.34
diff -u -r1.34 if_bridge.h
--- sys/net/if_bridge.h 20 Nov 2010 14:23:09 -0000      1.34
+++ sys/net/if_bridge.h 24 Jun 2011 18:29:18 -0000
@@ -382,8 +382,10 @@
 /*
  * Bridge interface list
  */
+/* XXX: rename to "bridge_port", and "bif" to "bp", etc? */
 struct bridge_iflist {
        LIST_ENTRY(bridge_iflist)       next;           /* next in list */
+       struct bridge_softc             *bridge_sc;
        struct bstp_port                *bif_stp;       /* STP port state */
        struct brl_head                 bif_brlin;      /* input rules */
        struct brl_head                 bif_brlout;     /* output rules */
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.148
diff -u -r1.148 if_ethersubr.c
--- sys/net/if_ethersubr.c      28 Jan 2011 13:19:44 -0000      1.148
+++ sys/net/if_ethersubr.c      24 Jun 2011 18:29:19 -0000
@@ -449,7 +449,8 @@
         * Interfaces that are bridge members need special handling
         * for output.
         */
-       if (ifp->if_bridge) {
+       if (ifp->if_bridge_port) {
+               struct bridge_softc *bsc;
                struct m_tag *mtag;
 
                /*
@@ -457,27 +458,28 @@
                 * this bridge, in which case we simply send it out
                 * without further bridge processing.
                 */
+               bsc = ((struct bridge_iflist *)ifp->if_bridge_port)->bridge_sc;
                for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
                    mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
 #ifdef DEBUG
                        /* Check that the information is there */
-                       if (mtag->m_tag_len != sizeof(caddr_t)) {
+                       if (mtag->m_tag_len != sizeof(bsc)) {
                                error = EINVAL;
                                goto bad;
                        }
 #endif
-                       if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
+                       if (!bcmp(bsc, mtag + 1, sizeof(bsc)))
                                break;
                }
                if (mtag == NULL) {
                        /* Attach a tag so we can detect loops */
-                       mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
+                       mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(bsc),
                            M_NOWAIT);
                        if (mtag == NULL) {
                                error = ENOBUFS;
                                goto bad;
                        }
-                       bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
+                       bcopy(bsc, mtag + 1, sizeof(bsc));
                        m_tag_prepend(m, mtag);
                        error = bridge_output(ifp, m, NULL, NULL);
                        return (error);
@@ -627,7 +629,7 @@
         * NULL if it has consumed the packet, otherwise, it
         * gets processed as normal.
         */
-       if (ifp->if_bridge) {
+       if (ifp->if_bridge_port) {
                if (m->m_flags & M_PROTO1)
                        m->m_flags &= ~M_PROTO1;
                else {
Index: sys/net/if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.55
diff -u -r1.55 if_gif.c
--- sys/net/if_gif.c    3 Jul 2010 04:44:51 -0000       1.55
+++ sys/net/if_gif.c    24 Jun 2011 18:29:19 -0000
@@ -176,7 +176,7 @@
                 * the start function and bypasses the if_output function
                 * so we need to do the encap here.
                 */
-               if (ifp->if_bridge && (m->m_flags & M_PROTO1)) {
+               if (ifp->if_bridge_port && (m->m_flags & M_PROTO1)) {
                        int error = 0;
                        /*
                         * Remove multicast and broadcast flags or encapsulated
Index: sys/net80211/ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.63
diff -u -r1.63 ieee80211_node.c
--- sys/net80211/ieee80211_node.c       28 Mar 2011 14:49:40 -0000      1.63
+++ sys/net80211/ieee80211_node.c       24 Jun 2011 18:29:19 -0000
@@ -1385,7 +1385,7 @@
         * If the parent interface belongs to a bridge, learn
         * the node's address dynamically on this interface.
         */
-       if (ic->ic_if.if_bridge != NULL)
+       if (ic->ic_if.if_bridge_port != NULL)
                bridge_update(&ic->ic_if,
                    (struct ether_addr *)ni->ni_macaddr, 0);
 #endif
@@ -1536,7 +1536,7 @@
         * If the parent interface belongs to a bridge, delete
         * any dynamically learned address for this node.
         */
-       if (ic->ic_if.if_bridge != NULL)
+       if (ic->ic_if.if_bridge_port != NULL)
                bridge_update(&ic->ic_if,
                    (struct ether_addr *)ni->ni_macaddr, 1);
 #endif
Index: sys/netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.88
diff -u -r1.88 if_ether.c
--- sys/netinet/if_ether.c      22 Jul 2010 00:41:55 -0000      1.88
+++ sys/netinet/if_ether.c      24 Jun 2011 18:29:19 -0000
@@ -63,6 +63,9 @@
 #if NCARP > 0
 #include <netinet/ip_carp.h>
 #endif
+#if NBRIDGE > 0
+#include <net/if_bridge.h>
+#endif
 
 #define SIN(s) ((struct sockaddr_in *)s)
 #define SDL(s) ((struct sockaddr_dl *)s)
@@ -681,7 +684,9 @@
                                   ac->ac_if.if_xname);
                                goto out;
                        } else if (rt->rt_ifp != &ac->ac_if) {
+#if NCARP > 0
                                if (ac->ac_if.if_type != IFT_CARP)
+#endif
                                        log(LOG_WARNING,
                                           "arp: attempt to overwrite entry for"
                                           " %s on %s by %s on %s\n",
@@ -699,19 +704,33 @@
                                rt->rt_expire = 1; /* no longer static */
                        }
                    }
-               } else if (rt->rt_ifp != &ac->ac_if && !(ac->ac_if.if_bridge &&
-                   (rt->rt_ifp->if_bridge == ac->ac_if.if_bridge)) &&
-                   !(rt->rt_ifp->if_type == IFT_CARP &&
-                   rt->rt_ifp->if_carpdev == &ac->ac_if) &&
-                   !(ac->ac_if.if_type == IFT_CARP &&
-                   ac->ac_if.if_carpdev == rt->rt_ifp)) {
-                   log(LOG_WARNING,
-                       "arp: attempt to add entry for %s "
-                       "on %s by %s on %s\n",
-                       inet_ntoa(isaddr), rt->rt_ifp->if_xname,
-                       ether_sprintf(ea->arp_sha),
-                       ac->ac_if.if_xname);
-                   goto out;
+               } else if (rt->rt_ifp != &ac->ac_if) {
+#if NBRIDGE > 0
+                       /* Same bridge is ok. */
+                       if (ac->ac_if.if_bridge_port &&
+                           rt->rt_ifp->if_bridge_port &&
+                           (((struct bridge_iflist *)
+                           ac->ac_if.if_bridge_port)->bridge_sc ==
+                           ((struct bridge_iflist *)
+                           rt->rt_ifp->if_bridge_port)->bridge_sc))
+                               goto out;
+#endif
+#if NCARP > 0
+                       /* carpdev is ok. */
+                       if (rt->rt_ifp->if_type == IFT_CARP &&
+                           rt->rt_ifp->if_carpdev == &ac->ac_if)
+                               goto out;
+
+                       if (ac->ac_if.if_type == IFT_CARP &&
+                           ac->ac_if.if_carpdev == rt->rt_ifp)
+                               goto out;
+#endif
+                       log(LOG_WARNING,
+                           "arp: attempt to add entry for"
+                           " %s on %s by %s on %s\n",
+                           inet_ntoa(isaddr), rt->rt_ifp->if_xname,
+                           ether_sprintf(ea->arp_sha), ac->ac_if.if_xname);
+                       goto out;
                }
                bcopy(ea->arp_sha, LLADDR(sdl),
                    sdl->sdl_alen = sizeof(ea->arp_sha));
Index: sys/netinet/ip_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ether.c,v
retrieving revision 1.57
diff -u -r1.57 ip_ether.c
--- sys/netinet/ip_ether.c      13 Apr 2011 22:15:59 -0000      1.57
+++ sys/netinet/ip_ether.c      24 Jun 2011 18:29:19 -0000
@@ -231,7 +231,7 @@
        sc = etherip_getgif(m);
        if (sc == NULL)
                return;
-       if (sc->gif_if.if_bridge == NULL) {
+       if (sc->gif_if.if_bridge_port == NULL) {
                DPRINTF(("etherip_input(): interface not part of bridge\n"));
                etheripstat.etherip_noifdrops++;
                m_freem(m);
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.222
diff -u -r1.222 ip_output.c
--- sys/netinet/ip_output.c     15 Jun 2011 09:11:01 -0000      1.222
+++ sys/netinet/ip_output.c     24 Jun 2011 18:29:19 -0000
@@ -2147,13 +2147,13 @@
 {
        if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) {
                if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
-                   ifp->if_bridge != NULL) {
+                   ifp->if_bridge_port != NULL) {
                        in_delayed_cksum(m);
                        m->m_pkthdr.csum_flags &= ~M_TCP_CSUM_OUT; /* Clear */
                }
        } else if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) {
                if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
-                   ifp->if_bridge != NULL) {
+                   ifp->if_bridge_port != NULL) {
                        in_delayed_cksum(m);
                        m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */
                }

Reply via email to