svn commit: r359940 - in head/sys: net netinet6

Alexander V. Chernikov melifaro at FreeBSD.org
Tue Apr 14 22:48:34 UTC 2020


Author: melifaro
Date: Tue Apr 14 22:48:33 2020
New Revision: 359940
URL: https://svnweb.freebsd.org/changeset/base/359940

Log:
  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

Modified:
  head/sys/net/route.c
  head/sys/net/route.h
  head/sys/netinet6/nd6_rtr.c

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Tue Apr 14 22:16:40 2020	(r359939)
+++ head/sys/net/route.c	Tue Apr 14 22:48:33 2020	(r359940)
@@ -604,6 +604,18 @@ done:
 }
 
 /*
+ * 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
  * @dst: destination to install redirect to

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Tue Apr 14 22:16:40 2020	(r359939)
+++ head/sys/net/route.h	Tue Apr 14 22:48:33 2020	(r359940)
@@ -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 *, in
  */
 
 void	 rtfree(struct rtentry *);
+void	 rtfree_func(struct rtentry *);
 void	rt_updatemtu(struct ifnet *);
 
 typedef int rt_walktree_f_t(struct rtentry *, void *);

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c	Tue Apr 14 22:16:40 2020	(r359939)
+++ head/sys/netinet6/nd6_rtr.c	Tue Apr 14 22:48:33 2020	(r359940)
@@ -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, stru
 		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, stru
 
 			/* 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;


More information about the svn-src-head mailing list