Mostly around rtrequest(9) code, ok?
Index: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.270
diff -u -p -r1.270 route.c
--- net/route.c 11 Nov 2015 11:25:16 -0000 1.270
+++ net/route.c 11 Nov 2015 11:40:55 -0000
@@ -806,6 +806,7 @@ int
rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
struct rtentry **ret_nrt, u_int tableid)
{
+ struct ifnet *ifp;
struct rtentry *rt, *crt;
struct ifaddr *ifa;
struct sockaddr *ndst;
@@ -870,7 +871,12 @@ rtrequest(int req, struct rt_addrinfo *i
rt->rt_parent = NULL;
rt->rt_flags &= ~RTF_UP;
- rt->rt_ifp->if_rtrequest(rt->rt_ifp, RTM_DELETE, rt);
+
+ ifp = if_get(rt->rt_ifidx);
+ KASSERT(ifp != NULL);
+ ifp->if_rtrequest(ifp, RTM_DELETE, rt);
+ if_put(ifp);
+
atomic_inc_int(&rttrash);
if (ret_nrt != NULL)
@@ -911,8 +917,9 @@ rtrequest(int req, struct rt_addrinfo *i
if (info->rti_ifa == NULL && (error = rt_getifa(info, tableid)))
return (error);
ifa = info->rti_ifa;
+ ifp = ifa->ifa_ifp;
if (prio == 0)
- prio = ifa->ifa_ifp->if_priority + RTP_STATIC;
+ prio = ifp->if_priority + RTP_STATIC;
dlen = info->rti_info[RTAX_DST]->sa_len;
ndst = malloc(dlen, M_RTABLE, M_NOWAIT);
@@ -941,8 +948,8 @@ rtrequest(int req, struct rt_addrinfo *i
/* Check the link state if the table supports it. */
if (rtable_mpath_capable(tableid, ndst->sa_family) &&
!ISSET(rt->rt_flags, RTF_LOCAL) &&
- (!LINK_STATE_IS_UP(ifa->ifa_ifp->if_link_state) ||
- !ISSET(ifa->ifa_ifp->if_flags, IFF_UP))) {
+ (!LINK_STATE_IS_UP(ifp->if_link_state) ||
+ !ISSET(ifp->if_flags, IFF_UP))) {
rt->rt_flags &= ~RTF_UP;
rt->rt_priority |= RTP_DOWN;
}
@@ -989,7 +996,7 @@ rtrequest(int req, struct rt_addrinfo *i
ifa->ifa_refcnt++;
rt->rt_ifa = ifa;
- rt->rt_ifp = ifa->ifa_ifp;
+ rt->rt_ifp = ifp;
if (rt->rt_flags & RTF_CLONED) {
/*
* If the ifa of the cloning route was stale, a
@@ -998,16 +1005,21 @@ rtrequest(int req, struct rt_addrinfo *i
* route.
*/
if ((*ret_nrt)->rt_ifa->ifa_ifp == NULL) {
- printf("rtrequest RTM_RESOLVE: wrong ifa (%p) "
- "was (%p)\n", ifa, (*ret_nrt)->rt_ifa);
- (*ret_nrt)->rt_ifp->if_rtrequest(rt->rt_ifp,
- RTM_DELETE, *ret_nrt);
+ struct ifnet *ifp0;
+
+ printf("%s RTM_RESOLVE: wrong ifa (%p) was (%p)"
+ "\n", __func__, ifa, (*ret_nrt)->rt_ifa);
+
+ ifp0 = if_get((*ret_nrt)->rt_ifidx);
+ KASSERT(ifp0 != NULL);
+ ifp0->if_rtrequest(ifp0, RTM_DELETE, *ret_nrt);
ifafree((*ret_nrt)->rt_ifa);
- (*ret_nrt)->rt_ifa = ifa;
- (*ret_nrt)->rt_ifp = ifa->ifa_ifp;
+ if_put(ifp0);
+
ifa->ifa_refcnt++;
- (*ret_nrt)->rt_ifp->if_rtrequest(rt->rt_ifp,
- RTM_ADD, *ret_nrt);
+ (*ret_nrt)->rt_ifa = ifa;
+ (*ret_nrt)->rt_ifp = ifp;
+ ifp->if_rtrequest(ifp, RTM_ADD, *ret_nrt);
}
/*
* Copy both metrics and a back pointer to the cloned
@@ -1056,7 +1068,7 @@ rtrequest(int req, struct rt_addrinfo *i
pool_put(&rtentry_pool, rt);
return (EEXIST);
}
- rt->rt_ifp->if_rtrequest(rt->rt_ifp, req, rt);
+ ifp->if_rtrequest(ifp, req, rt);
if ((rt->rt_flags & RTF_CLONING) != 0) {
/* clean up any cloned children */
Index: net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.182
diff -u -p -r1.182 rtsock.c
--- net/rtsock.c 9 Nov 2015 10:26:26 -0000 1.182
+++ net/rtsock.c 11 Nov 2015 11:58:35 -0000
@@ -750,15 +750,18 @@ report:
goto flush;
if (ifa) {
if (rt->rt_ifa != ifa) {
- rt->rt_ifp->if_rtrequest(
- rt->rt_ifp, RTM_DELETE, rt);
+ ifp = if_get(rt->rt_ifidx);
+ KASSERT(ifp != NULL);
+ ifp->if_rtrequest(ifp, RTM_DELETE, rt);
ifafree(rt->rt_ifa);
- rt->rt_ifa = ifa;
+ if_put(ifp);
+
ifa->ifa_refcnt++;
+ rt->rt_ifa = ifa;
rt->rt_ifp = ifa->ifa_ifp;
#ifndef SMALL_KERNEL
/* recheck link state after ifp change*/
- rt_if_linkstate_change(rt, rt->rt_ifp,
+ rt_if_linkstate_change(rt, ifa->ifa_ifp,
tableid);
#endif
}
@@ -815,13 +818,17 @@ report:
rtm->rtm_index = rt->rt_ifidx;
rtm->rtm_priority = rt->rt_priority & RTP_MASK;
rtm->rtm_flags = rt->rt_flags;
- rt->rt_ifp->if_rtrequest(rt->rt_ifp, RTM_ADD, rt);
+
+ ifp = if_get(rt->rt_ifidx);
+ KASSERT(ifp != NULL);
+ ifp->if_rtrequest(ifp, RTM_ADD, rt);
+ if_put(ifp);
+
if (info.rti_info[RTAX_LABEL] != NULL) {
char *rtlabel = ((struct sockaddr_rtlabel *)
info.rti_info[RTAX_LABEL])->sr_label;
rtlabel_unref(rt->rt_labelid);
- rt->rt_labelid =
- rtlabel_name2id(rtlabel);
+ rt->rt_labelid = rtlabel_name2id(rtlabel);
}
if_group_routechange(info.rti_info[RTAX_DST],
info.rti_info[RTAX_NETMASK]);