summaryrefslogtreecommitdiff
path: root/sys/netinet/in.c
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2018-04-30 19:07:45 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2018-04-30 19:07:45 +0000
commitc5715eb7792149be764c7083fc46d6dc0081e12a (patch)
tree759d4a46814212692f13971980a70a12116b0923 /sys/netinet/in.c
parent896330ed72a6b6850a3911ff8f27c287e3eac9bd (diff)
Reduce the scope of the NET_LOCK() in in_control(). Two functions were
protected: mrt_ioctl() and in_ioctl(). The former has no other callers and only needs a read lock. The latter will need refactoring to reduce the lock's scope further. In a first step, establish a single exit point and protect most of the function body with the NET_LOCK() while removing the NET_LOCK() from a handful of callers. suggested by & ok mpi, ok visa
Diffstat (limited to 'sys/netinet/in.c')
-rw-r--r--sys/netinet/in.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index eda6ac60b97..32d5f6777ad 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.c,v 1.149 2018/04/24 19:53:38 florian Exp $ */
+/* $OpenBSD: in.c,v 1.150 2018/04/30 19:07:44 tb Exp $ */
/* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
/*
@@ -187,7 +187,6 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
int privileged;
int error;
- NET_LOCK();
privileged = 0;
if ((so->so_state & SS_PRIV) != 0)
privileged++;
@@ -204,7 +203,6 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
break;
}
- NET_UNLOCK();
return error;
}
@@ -216,13 +214,13 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
struct in_ifaddr *ia = NULL;
struct in_aliasreq *ifra = (struct in_aliasreq *)data;
struct sockaddr_in oldaddr;
- int error;
+ int error = 0;
int newifaddr;
if (ifp == NULL)
return (ENXIO);
- NET_ASSERT_LOCKED();
+ NET_LOCK();
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family == AF_INET) {
@@ -244,12 +242,16 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
}
ia = ifatoia(ifa);
}
- if (cmd == SIOCDIFADDR && ia == NULL)
- return (EADDRNOTAVAIL);
+ if (cmd == SIOCDIFADDR && ia == NULL) {
+ error = EADDRNOTAVAIL;
+ goto err;
+ }
/* FALLTHROUGH */
case SIOCSIFADDR:
- if (!privileged)
- return (EPERM);
+ if (!privileged) {
+ error = EPERM;
+ goto err;
+ }
if (ia == NULL) {
ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
@@ -273,8 +275,10 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
case SIOCSIFNETMASK:
case SIOCSIFDSTADDR:
case SIOCSIFBRDADDR:
- if (!privileged)
- return (EPERM);
+ if (!privileged) {
+ error = EPERM;
+ goto err;
+ }
/* FALLTHROUGH */
case SIOCGIFADDR:
@@ -291,8 +295,10 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
}
}
}
- if (ia == NULL)
- return (EADDRNOTAVAIL);
+ if (ia == NULL) {
+ error = EADDRNOTAVAIL;
+ goto err;
+ }
break;
}
switch (cmd) {
@@ -302,14 +308,18 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
break;
case SIOCGIFBRDADDR:
- if ((ifp->if_flags & IFF_BROADCAST) == 0)
- return (EINVAL);
+ if ((ifp->if_flags & IFF_BROADCAST) == 0) {
+ error = EINVAL;
+ break;
+ }
*satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
break;
case SIOCGIFDSTADDR:
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
- return (EINVAL);
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
+ error = EINVAL;
+ break;
+ }
*satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
break;
@@ -318,31 +328,36 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
break;
case SIOCSIFDSTADDR:
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
- return (EINVAL);
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
+ error = EINVAL;
+ break;
+ }
oldaddr = ia->ia_dstaddr;
ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (caddr_t)ia);
if (error) {
ia->ia_dstaddr = oldaddr;
- return (error);
+ break;
}
in_scrubhost(ia, &oldaddr);
in_addhost(ia, &ia->ia_dstaddr);
break;
case SIOCSIFBRDADDR:
- if ((ifp->if_flags & IFF_BROADCAST) == 0)
- return (EINVAL);
+ if ((ifp->if_flags & IFF_BROADCAST) == 0) {
+ error = EINVAL;
+ break;
+ }
ifa_update_broadaddr(ifp, &ia->ia_ifa, &ifr->ifr_broadaddr);
break;
case SIOCSIFADDR:
in_ifscrub(ifp, ia);
error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), newifaddr);
- if (!error)
- dohooks(ifp->if_addrhooks, 0);
- return (error);
+ if (error)
+ break;
+ dohooks(ifp->if_addrhooks, 0);
+ break;
case SIOCSIFNETMASK:
ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
@@ -352,8 +367,6 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
case SIOCAIFADDR: {
int needinit = 0;
- error = 0;
-
if (ia->ia_addr.sin_family == AF_INET) {
if (ifra->ifra_addr.sin_len == 0)
ifra->ifra_addr = ia->ia_addr;
@@ -384,9 +397,10 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
if (ifra->ifra_addr.sin_family == AF_INET && needinit) {
error = in_ifinit(ifp, ia, &ifra->ifra_addr, newifaddr);
}
- if (!error)
- dohooks(ifp->if_addrhooks, 0);
- return (error);
+ if (error)
+ break;
+ dohooks(ifp->if_addrhooks, 0);
+ break;
}
case SIOCDIFADDR:
/*
@@ -400,9 +414,13 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
break;
default:
- return (EOPNOTSUPP);
+ error = EOPNOTSUPP;
+ break;
}
- return (0);
+
+err:
+ NET_UNLOCK();
+ return (error);
}
/*
* Delete any existing route for an interface.