Reorganise nd6 notification code to avoid direct rtentry field access.
One of the goals of the new routing KPI defined in r359823 is to entirely hide `struct rtentry` from the consumers. Doing so will allow to improve routing subsystem internals and deliver features more easily. This change is one of the ongoing changes to eliminate direct struct rtentry field accesses. It introduces rtfree_func() wrapper around RTFREE() and reorganises nd6 notification code to avoid accessing most of the rtentry fields. Reviewed by: ae Differential Revision: https://reviews.freebsd.org/D24404
This commit is contained in:
parent
47d45507e8
commit
dd4776f0cc
@ -603,6 +603,18 @@ rtfree(struct rtentry *rt)
|
||||
RT_UNLOCK(rt);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -422,6 +422,8 @@ struct rt_addrinfo {
|
||||
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 @@ int rtsock_routemsg_info(int, struct rt_addrinfo *, int);
|
||||
*/
|
||||
|
||||
void rtfree(struct rtentry *);
|
||||
void rtfree_func(struct rtentry *);
|
||||
void rt_updatemtu(struct ifnet *);
|
||||
|
||||
typedef int rt_walktree_f_t(struct rtentry *, void *);
|
||||
|
@ -603,14 +603,6 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
|
||||
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 @@ defrouter_addreq(struct nd_defrouter *new)
|
||||
{
|
||||
struct sockaddr_in6 def, mask, gate;
|
||||
struct rtentry *newrt = NULL;
|
||||
unsigned int fibnum;
|
||||
int error;
|
||||
|
||||
bzero(&def, sizeof(def));
|
||||
@ -691,13 +684,14 @@ defrouter_addreq(struct nd_defrouter *new)
|
||||
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 @@ defrouter_delreq(struct nd_defrouter *dr)
|
||||
{
|
||||
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 @@ defrouter_delreq(struct nd_defrouter *dr)
|
||||
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 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
|
||||
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 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
|
||||
|
||||
/* 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 @@ nd6_prefix_offlink(struct nd_prefix *pr)
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user