Fix gateway setup for the interface routes.

Currently rinit1() and its IPv6 counterpart
  nd6_prefix_onlink_rtrequest() uses dummy null_sdl gateway address
  during route insertion and change it afterwards. This behaviour
  brings complications to the routing stack and the users of its
  upcoming notification system.

This change fixes both rinit1() and nd6_prefix_onlink_rtrequest()
  by filling in proper gateway in the beginning. It does not change any
  of the userland notifications as in both cases, they happen after
  the insertion and fixup process (rt_newaddrmsg_fib() and nd6_rtmsg()).

MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D20328
This commit is contained in:
melifaro 2019-05-22 21:20:15 +00:00
parent 98b2a72b80
commit 86c5caf157
2 changed files with 18 additions and 29 deletions

View File

@ -1995,7 +1995,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
char tempbuf[_SOCKADDR_TMPSIZE];
int didwork = 0;
int a_failure = 0;
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
struct sockaddr_dl *sdl = NULL;
struct rib_head *rnh;
if (flags & RTF_HOST) {
@ -2046,7 +2046,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask);
dst = (struct sockaddr *)tempbuf;
}
}
} else if (cmd == RTM_ADD) {
sdl = (struct sockaddr_dl *)tempbuf;
bzero(sdl, sizeof(struct sockaddr_dl));
sdl->sdl_family = AF_LINK;
sdl->sdl_len = sizeof(struct sockaddr_dl);
sdl->sdl_type = ifa->ifa_ifp->if_type;
sdl->sdl_index = ifa->ifa_ifp->if_index;
}
/*
* Now go through all the requested tables (fibs) and do the
* requested action. Realistically, this will either be fib 0
@ -2109,8 +2116,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
* doing this for compatibility reasons
*/
if (cmd == RTM_ADD)
info.rti_info[RTAX_GATEWAY] =
(struct sockaddr *)&null_sdl;
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)sdl;
else
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
info.rti_info[RTAX_NETMASK] = netmask;
@ -2137,15 +2143,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
rt->rt_ifa = ifa;
}
#endif
/*
* doing this for compatibility reasons
*/
if (cmd == RTM_ADD) {
((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
rt->rt_ifp->if_type;
((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
rt->rt_ifp->if_index;
}
RT_ADDREF(rt);
RT_UNLOCK(rt);
rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);

View File

@ -1894,8 +1894,7 @@ restart:
static int
nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
{
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
struct rib_head *rnh;
struct sockaddr_dl sdl;
struct rtentry *rt;
struct sockaddr_in6 mask6;
u_long rtflags;
@ -1910,6 +1909,12 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
mask6.sin6_addr = pr->ndpr_mask;
rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP;
bzero(&sdl, sizeof(struct sockaddr_dl));
sdl.sdl_len = sizeof(struct sockaddr_dl);
sdl.sdl_family = AF_LINK;
sdl.sdl_type = ifa->ifa_ifp->if_type;
sdl.sdl_index = ifa->ifa_ifp->if_index;
if(V_rt_add_addr_allfibs) {
fibnum = 0;
maxfib = rt_numfibs;
@ -1922,26 +1927,13 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
rt = NULL;
error = in6_rtrequest(RTM_ADD,
(struct sockaddr *)&pr->ndpr_prefix, ifa->ifa_addr,
(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));
rnh = rt_tables_get_rnh(rt->rt_fibnum, AF_INET6);
/* XXX what if rhn == NULL? */
RIB_WLOCK(rnh);
RT_LOCK(rt);
if (rt_setgate(rt, rt_key(rt),
(struct sockaddr *)&null_sdl) == 0) {
struct sockaddr_dl *dl;
dl = (struct sockaddr_dl *)rt->rt_gateway;
dl->sdl_type = rt->rt_ifp->if_type;
dl->sdl_index = rt->rt_ifp->if_index;
}
RIB_WUNLOCK(rnh);
nd6_rtmsg(RTM_ADD, rt);
RT_UNLOCK(rt);
pr->ndpr_stateflags |= NDPRF_ONLINK;