Index: head/sys/net/route.h =================================================================== --- head/sys/net/route.h +++ head/sys/net/route.h @@ -422,6 +422,8 @@ RTFREE_LOCKED(_rt); \ } while (0) +#define RTFREE_FUNC(_rt) rtfree_func(_rt) + #define RO_RTFREE(_ro) do { \ if ((_ro)->ro_rt) \ RTFREE((_ro)->ro_rt); \ @@ -482,6 +484,7 @@ */ void rtfree(struct rtentry *); +void rtfree_func(struct rtentry *); void rt_updatemtu(struct ifnet *); typedef int rt_walktree_f_t(struct rtentry *, void *); Index: head/sys/net/route.c =================================================================== --- head/sys/net/route.c +++ head/sys/net/route.c @@ -604,6 +604,18 @@ } /* + * Temporary RTFREE() function wrapper. + * Intended to use in control plane code to + * avoid exposing internal layout of 'struct rtentry'. + */ +void +rtfree_func(struct rtentry *rt) +{ + + RTFREE(rt); +} + +/* * Adds a temporal redirect entry to the routing table. * @fibnum: fib number * @dst: destination to install redirect to Index: head/sys/netinet6/nd6_rtr.c =================================================================== --- head/sys/netinet6/nd6_rtr.c +++ head/sys/netinet6/nd6_rtr.c @@ -603,14 +603,6 @@ m_freem(m); } -/* tell the change to user processes watching the routing socket. */ -static void -nd6_rtmsg(int cmd, struct rtentry *rt) -{ - - rt_routemsg(cmd, rt, rt->rt_ifp, 0, rt->rt_fibnum); -} - /* PFXRTR */ static struct nd_pfxrouter * pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr) @@ -681,6 +673,7 @@ { struct sockaddr_in6 def, mask, gate; struct rtentry *newrt = NULL; + unsigned int fibnum; int error; bzero(&def, sizeof(def)); @@ -691,13 +684,14 @@ sizeof(struct sockaddr_in6); def.sin6_family = gate.sin6_family = AF_INET6; gate.sin6_addr = new->rtaddr; + fibnum = new->ifp->if_fib; error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def, (struct sockaddr *)&gate, (struct sockaddr *)&mask, - RTF_GATEWAY, &newrt, new->ifp->if_fib); + RTF_GATEWAY, &newrt, fibnum); if (newrt) { - nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ - RTFREE(newrt); + rt_routemsg(RTM_ADD, newrt, new->ifp, 0, fibnum); + RTFREE_FUNC(newrt); } if (error == 0) new->installed = 1; @@ -713,6 +707,7 @@ { struct sockaddr_in6 def, mask, gate; struct rtentry *oldrt = NULL; + unsigned int fibnum; bzero(&def, sizeof(def)); bzero(&mask, sizeof(mask)); @@ -722,13 +717,14 @@ sizeof(struct sockaddr_in6); def.sin6_family = gate.sin6_family = AF_INET6; gate.sin6_addr = dr->rtaddr; + fibnum = dr->ifp->if_fib; in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def, (struct sockaddr *)&gate, - (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, dr->ifp->if_fib); + (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, fibnum); if (oldrt) { - nd6_rtmsg(RTM_DELETE, oldrt); - RTFREE(oldrt); + rt_routemsg(RTM_DELETE, oldrt, dr->ifp, 0, fibnum); + RTFREE_FUNC(oldrt); } dr->installed = 0; @@ -2044,15 +2040,7 @@ error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix, (struct sockaddr *)&sdl, (struct sockaddr *)&mask6, rtflags, &rt, fibnum); - if (error == 0) { - KASSERT(rt != NULL, ("%s: in6_rtrequest return no " - "error(%d) but rt is NULL, pr=%p, ifa=%p", __func__, - error, pr, ifa)); - RT_LOCK(rt); - nd6_rtmsg(RTM_ADD, rt); - RT_UNLOCK(rt); - pr->ndpr_stateflags |= NDPRF_ONLINK; - } else { + if (error != 0) { char ip6buf[INET6_ADDRSTRLEN]; char ip6bufg[INET6_ADDRSTRLEN]; char ip6bufm[INET6_ADDRSTRLEN]; @@ -2070,13 +2058,12 @@ /* Save last error to return, see rtinit(). */ a_failure = error; + continue; } - if (rt != NULL) { - RT_LOCK(rt); - RT_REMREF(rt); - RT_UNLOCK(rt); - } + pr->ndpr_stateflags |= NDPRF_ONLINK; + rt_routemsg(RTM_ADD, rt, pr->ndpr_ifp, 0, fibnum); + RTFREE_FUNC(rt); } /* Return the last error we got. */ @@ -2209,17 +2196,15 @@ rt = NULL; error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, (struct sockaddr *)&mask6, 0, &rt, fibnum); - if (error == 0) { - /* report the route deletion to the routing socket. */ - if (rt != NULL) - nd6_rtmsg(RTM_DELETE, rt); - } else { + if (error != 0) { /* Save last error to return, see rtinit(). */ a_failure = error; + continue; } - if (rt != NULL) { - RTFREE(rt); - } + + /* report route deletion to the routing socket. */ + rt_routemsg(RTM_DELETE, rt, ifp, 0, fibnum); + RTFREE_FUNC(rt); } error = a_failure; a_failure = 1;