summaryrefslogtreecommitdiffstats
path: root/sys/netinet/raw_ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/raw_ip.c')
-rw-r--r--sys/netinet/raw_ip.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 0157afb..00ec423 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -678,9 +678,12 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
switch (cmd) {
case PRC_IFDOWN:
+ IN_IFADDR_RLOCK();
TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
if (ia->ia_ifa.ifa_addr == sa
&& (ia->ia_flags & IFA_ROUTE)) {
+ ifa_ref(&ia->ia_ifa);
+ IN_IFADDR_RUNLOCK();
/*
* in_ifscrub kills the interface route.
*/
@@ -692,18 +695,26 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
* routing process they will come back.
*/
in_ifadown(&ia->ia_ifa, 0);
+ ifa_free(&ia->ia_ifa);
break;
}
}
+ if (ia == NULL) /* If ia matched, already unlocked. */
+ IN_IFADDR_RUNLOCK();
break;
case PRC_IFUP:
+ IN_IFADDR_RLOCK();
TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
if (ia->ia_ifa.ifa_addr == sa)
break;
}
- if (ia == 0 || (ia->ia_flags & IFA_ROUTE))
+ if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) {
+ IN_IFADDR_RUNLOCK();
return;
+ }
+ ifa_ref(&ia->ia_ifa);
+ IN_IFADDR_RUNLOCK();
flags = RTF_UP;
ifp = ia->ia_ifa.ifa_ifp;
@@ -714,6 +725,7 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
if (err == 0)
ia->ia_flags |= IFA_ROUTE;
+ ifa_free(&ia->ia_ifa);
break;
}
}
OpenPOWER on IntegriCloud