- 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