diff options
author | thompsa <thompsa@FreeBSD.org> | 2009-02-13 19:20:25 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2009-02-13 19:20:25 +0000 |
commit | b2e68e06f43f17f3dd40997504370104c66f97fa (patch) | |
tree | f84142916eee4494bfb53302846b5dcaa1d6fe22 /sys/net/if_bridge.c | |
parent | b04fb61e93b0a6892a6c6d2b22acd4e5524fc67e (diff) | |
download | FreeBSD-src-b2e68e06f43f17f3dd40997504370104c66f97fa.zip FreeBSD-src-b2e68e06f43f17f3dd40997504370104c66f97fa.tar.gz |
bridge_delete_member is called via the event handler from if_detach
after the LLADDR is reclaimed which causes a null pointer deref with
inherit_mac enabled. Record the ifnet pointer of the interface and then compare
that to find when to re-assign the bridge address.
Submitted by: sam
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r-- | sys/net/if_bridge.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 6d7aed0..da73543 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -220,6 +220,7 @@ struct bridge_softc { LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ struct bstp_state sc_stp; /* STP state */ uint32_t sc_brtexceeded; /* # of cache drops */ + struct ifnet *sc_ifaddr; /* member mac copied from */ u_char sc_defaddr[6]; /* Default MAC address */ }; @@ -930,15 +931,16 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif, * the mac address of the bridge to the address of the next member, or * to its default address if no members are left. */ - if (bridge_inherit_mac && - !memcmp(IF_LLADDR(sc->sc_ifp), IF_LLADDR(ifs), ETHER_ADDR_LEN)) { - if (LIST_EMPTY(&sc->sc_iflist)) + if (bridge_inherit_mac && sc->sc_ifaddr == ifs) { + if (LIST_EMPTY(&sc->sc_iflist)) { bcopy(sc->sc_defaddr, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); - else { + sc->sc_ifaddr = NULL; + } else { fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp; bcopy(IF_LLADDR(fif), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + sc->sc_ifaddr = fif; } } @@ -1039,8 +1041,10 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) * the default randomly generated one. */ if (bridge_inherit_mac && LIST_EMPTY(&sc->sc_iflist) && - !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN)) + !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN)) { bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + sc->sc_ifaddr = ifs; + } ifs->if_bridge = sc; bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp); |