- Unify the two hooks by passing the same argument
- Check for nullity before dereferencing `if_bridgeport', this will
  matter when we go MP
- Use the same pattern to find a member in the ioctl path

ok?

Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.314
diff -u -p -r1.314 if_bridge.c
--- net/if_bridge.c     7 Dec 2018 16:19:40 -0000       1.314
+++ net/if_bridge.c     11 Dec 2018 17:13:24 -0000
@@ -297,9 +297,10 @@ bridge_ioctl(struct ifnet *ifp, u_long c
                }
 
                /* If it's in the span list, it can't be a member. */
-               TAILQ_FOREACH(bif, &sc->sc_spanlist, next)
+               TAILQ_FOREACH(bif, &sc->sc_spanlist, next) {
                        if (bif->ifp == ifs)
                                break;
+               }
                if (bif != NULL) {
                        error = EBUSY;
                        break;
@@ -335,7 +336,7 @@ bridge_ioctl(struct ifnet *ifp, u_long c
                SIMPLEQ_INIT(&bif->bif_brlout);
                ifs->if_bridgeport = (caddr_t)bif;
                bif->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0,
-                   bridge_ifdetach, ifs);
+                   bridge_ifdetach, bif);
                if_ih_insert(bif->ifp, bridge_input, NULL);
                TAILQ_INSERT_TAIL(&sc->sc_iflist, bif, next);
                break;
@@ -399,17 +400,20 @@ bridge_ioctl(struct ifnet *ifp, u_long c
        case SIOCBRDGDELS:
                if ((error = suser(curproc)) != 0)
                        break;
+               ifs = ifunit(req->ifbr_ifsname);
+               if (ifs == NULL) {
+                       error = ENOENT;
+                       break;
+               }
                TAILQ_FOREACH(bif, &sc->sc_spanlist, next) {
-                       if (strncmp(bif->ifp->if_xname, req->ifbr_ifsname,
-                           sizeof(bif->ifp->if_xname)) == 0) {
-                               bridge_spandetach(bif);
+                       if (bif->ifp == ifs)
                                break;
-                       }
                }
                if (bif == NULL) {
                        error = ENOENT;
                        break;
                }
+               bridge_spandetach(bif);
                break;
        case SIOCBRDGGIFFLGS:
                ifs = ifunit(req->ifbr_ifsname);
@@ -569,12 +573,8 @@ bridge_ioctl(struct ifnet *ifp, u_long c
 void
 bridge_ifdetach(void *arg)
 {
-       struct ifnet *ifp = (struct ifnet *)arg;
-       struct bridge_softc *sc;
-       struct bridge_iflist *bif;
-
-       bif = (struct bridge_iflist *)ifp->if_bridgeport;
-       sc = bif->bridge_sc;
+       struct bridge_iflist *bif = (struct bridge_iflist *)arg;
+       struct bridge_softc *sc = bif->bridge_sc;
 
        bridge_delete(sc, bif);
 }
@@ -713,6 +713,7 @@ int
 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
     struct rtentry *rt)
 {
+       struct bridge_iflist *bif;
        struct ether_header *eh;
        struct ifnet *dst_if = NULL;
        struct bridge_rtnode *dst_p = NULL;
@@ -727,11 +728,12 @@ bridge_output(struct ifnet *ifp, struct 
        KERNEL_ASSERT_LOCKED();
 
        /* ifp must be a member interface of the bridge. */
-       if (ifp->if_bridgeport == NULL) {
+       bif = (struct bridge_iflist *)ifp->if_bridgeport;
+       if (bif == NULL) {
                m_freem(m);
                return (EINVAL);
        }
-       sc = ((struct bridge_iflist *)ifp->if_bridgeport)->bridge_sc;
+       sc = bif->bridge_sc;
 
        if (m->m_len < sizeof(*eh)) {
                m = m_pullup(m, sizeof(*eh));
Index: net/bridgectl.c
===================================================================
RCS file: /cvs/src/sys/net/bridgectl.c,v
retrieving revision 1.12
diff -u -p -r1.12 bridgectl.c
--- net/bridgectl.c     14 Nov 2018 17:07:44 -0000      1.12
+++ net/bridgectl.c     11 Dec 2018 17:04:16 -0000
@@ -355,10 +355,14 @@ void
 bridge_rtagenode(struct ifnet *ifp, int age)
 {
        struct bridge_softc *sc;
+       struct bridge_iflist *bif;
        struct bridge_rtnode *n;
        int i;
 
-       sc = ((struct bridge_iflist *)ifp->if_bridgeport)->bridge_sc;
+       bif = (struct bridge_iflist *)ifp->if_bridgeport;
+       if (bif == NULL)
+               return;
+       sc = bif->bridge_sc;
        if (sc == NULL)
                return;
 
@@ -525,7 +529,11 @@ bridge_update(struct ifnet *ifp, struct 
        addr = (u_int8_t *)ea;
 
        bif = (struct bridge_iflist *)ifp->if_bridgeport;
+       if (bif == NULL)
+               return;
        sc = bif->bridge_sc;
+       if (sc == NULL)
+               return;
 
        /*
         * Update the bridge interface if it is in

Reply via email to