svn commit: r348121 - in head/sys: net netinet6
Alexander V. Chernikov
melifaro at FreeBSD.org
Wed May 22 21:20:17 UTC 2019
Author: melifaro
Date: Wed May 22 21:20:15 2019
New Revision: 348121
URL: https://svnweb.freebsd.org/changeset/base/348121
Log:
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
Modified:
head/sys/net/route.c
head/sys/netinet6/nd6_rtr.c
Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c Wed May 22 21:06:10 2019 (r348120)
+++ head/sys/net/route.c Wed May 22 21:20:15 2019 (r348121)
@@ -1995,7 +1995,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fi
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 fi
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 fi
* 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 fi
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);
Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c Wed May 22 21:06:10 2019 (r348120)
+++ head/sys/netinet6/nd6_rtr.c Wed May 22 21:20:15 2019 (r348121)
@@ -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, stru
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, stru
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;
More information about the svn-src-head
mailing list