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:
parent
98b2a72b80
commit
86c5caf157
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user