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