summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
authormvs <mvs@openbsd.org>2021-01-25 19:47:16 +0000
committermvs <mvs@openbsd.org>2021-01-25 19:47:16 +0000
commit044aaac6d42ec1f1777a52f2fa98b542d731d25c (patch)
tree56434ca1dd6831d94bb976bfd425c231bb38b9c3 /sys/net/if_bridge.c
parentGive machdep.c a thorough cleanup that is long overdue. (diff)
downloadwireguard-openbsd-044aaac6d42ec1f1777a52f2fa98b542d731d25c.tar.xz
wireguard-openbsd-044aaac6d42ec1f1777a52f2fa98b542d731d25c.zip
We have this sequence in bridge(4) ioctl(2) path:
ifs = ifunit(req->ifbr_ifsname); if (ifs == NULL) { error = ENOENT; break; } if (ifs->if_bridgeidx != ifp->if_index) { error = ESRCH; break; } bif = bridge_getbif(ifs); This sequence repeats 8 times. Also we don't check value returned by bridge_getbig() before use. Newly introduced bridge_getbig() function replaces this sequence. This not only reduces duplicated code but also makes `bif' dereference safe. ok bluhm@
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c80
1 files changed, 40 insertions, 40 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 337e133661b..769b3845e39 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.347 2021/01/08 23:31:53 dlg Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.348 2021/01/25 19:47:16 mvs Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -336,16 +336,9 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCBRDGDEL:
if ((error = suser(curproc)) != 0)
break;
- ifs = ifunit(req->ifbr_ifsname);
- if (ifs == NULL) {
- error = ENOENT;
- break;
- }
- if (ifs->if_bridgeidx != ifp->if_index) {
- error = ESRCH;
+ error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
+ if (error != 0)
break;
- }
- bif = bridge_getbif(ifs);
bridge_ifremove(bif);
break;
case SIOCBRDGIFS:
@@ -411,16 +404,9 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
bridge_spanremove(bif);
break;
case SIOCBRDGGIFFLGS:
- ifs = ifunit(req->ifbr_ifsname);
- if (ifs == NULL) {
- error = ENOENT;
- break;
- }
- if (ifs->if_bridgeidx != ifp->if_index) {
- error = ESRCH;
+ error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
+ if (error != 0)
break;
- }
- bif = bridge_getbif(ifs);
req->ifbr_ifsflags = bif->bif_flags;
req->ifbr_portno = bif->ifp->if_index & 0xfff;
req->ifbr_protected = bif->bif_protected;
@@ -428,22 +414,15 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
bridge_bifgetstp(sc, bif, req);
break;
case SIOCBRDGSIFFLGS:
- if ((error = suser(curproc)) != 0)
- break;
- ifs = ifunit(req->ifbr_ifsname);
- if (ifs == NULL) {
- error = ENOENT;
- break;
- }
- if (ifs->if_bridgeidx != ifp->if_index) {
- error = ESRCH;
- break;
- }
if (req->ifbr_ifsflags & IFBIF_RO_MASK) {
error = EINVAL;
break;
}
- bif = bridge_getbif(ifs);
+ if ((error = suser(curproc)) != 0)
+ break;
+ error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
+ if (error != 0)
+ break;
if (req->ifbr_ifsflags & IFBIF_STP) {
if ((bif->bif_flags & IFBIF_STP) == 0) {
/* Enable STP */
@@ -489,16 +468,9 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec;
break;
case SIOCBRDGSIFPROT:
- ifs = ifunit(req->ifbr_ifsname);
- if (ifs == NULL) {
- error = ENOENT;
- break;
- }
- if (ifs->if_bridgeidx != ifp->if_index) {
- error = ESRCH;
+ error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
+ if (error != 0)
break;
- }
- bif = bridge_getbif(ifs);
bif->bif_protected = req->ifbr_protected;
break;
case SIOCBRDGRTS:
@@ -703,6 +675,34 @@ done:
return (error);
}
+int
+bridge_findbif(struct bridge_softc *sc, const char *name,
+ struct bridge_iflist **rbif)
+{
+ struct ifnet *ifp;
+ struct bridge_iflist *bif;
+
+ KERNEL_ASSERT_LOCKED();
+
+ if ((ifp = ifunit(name)) == NULL)
+ return (ENOENT);
+
+ if (ifp->if_bridgeidx != sc->sc_if.if_index)
+ return (ESRCH);
+
+ SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
+ if (bif->ifp == ifp)
+ break;
+ }
+
+ if (bif == NULL)
+ return (ENOENT);
+
+ *rbif = bif;
+
+ return (0);
+}
+
struct bridge_iflist *
bridge_getbif(struct ifnet *ifp)
{