Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Dec 2015 08:17:31 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r291643 - head/sys/net
Message-ID:  <201512020817.tB28HViF095714@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Wed Dec  2 08:17:31 2015
New Revision: 291643
URL: https://svnweb.freebsd.org/changeset/base/291643

Log:
  Move RTF_PINNED handling to generic route code.
  This eliminates last RTF_RNH_LOCKED rtrequest1_fib() user.

Modified:
  head/sys/net/route.c

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Wed Dec  2 05:36:45 2015	(r291642)
+++ head/sys/net/route.c	Wed Dec  2 08:17:31 2015	(r291643)
@@ -1089,6 +1089,7 @@ rt_unlinkrte(struct radix_node_head *rnh
 	rt = RNTORT(rn);
 	RT_LOCK(rt);
 	RT_ADDREF(rt);
+	rt->rt_flags &= ~RTF_UP;
 
 	*perror = 0;
 
@@ -1100,8 +1101,6 @@ rt_notifydelete(struct rtentry *rt, stru
 {
 	struct ifaddr *ifa;
 
-	rt->rt_flags &= ~RTF_UP;
-
 	/*
 	 * give the protocol a chance to keep things in sync.
 	 */
@@ -1434,7 +1433,7 @@ rtrequest1_fib(int req, struct rt_addrin
 				u_int fibnum)
 {
 	int error = 0, needlock = 0;
-	struct rtentry *rt;
+	struct rtentry *rt, *rt_old;
 #ifdef FLOWTABLE
 	struct rtentry *rt0;
 #endif
@@ -1577,6 +1576,26 @@ rtrequest1_fib(int req, struct rt_addrin
 
 		/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
 		rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
+
+		rt_old = NULL;
+		if (rn == NULL && (info->rti_flags & RTF_PINNED) != 0) {
+
+			/*
+			 * Force removal and re-try addition
+			 * TODO: better multipath&pinned support
+			 */
+			struct sockaddr *info_dst = info->rti_info[RTAX_DST];
+			info->rti_info[RTAX_DST] = ndst;
+			rt_old = rt_unlinkrte(rnh, info, &error);
+			info->rti_info[RTAX_DST] = info_dst;
+			if (rt_old != NULL)
+				rn = rnh->rnh_addaddr(ndst, netmask, rnh,
+				    rt->rt_nodes);
+		}
+
+		if (rt_old != NULL)
+			RT_UNLOCK(rt_old);
+
 		/*
 		 * If it still failed to go into the tree,
 		 * then un-make it (this should be a function)
@@ -1598,6 +1617,11 @@ rtrequest1_fib(int req, struct rt_addrin
 		}
 #endif
 
+		if (rt_old != NULL) {
+			rt_notifydelete(rt_old, info);
+			RTFREE(rt_old);
+		}
+
 		/*
 		 * If this protocol has something to add to this then
 		 * allow it to do that as well.
@@ -1974,32 +1998,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 		info.rti_info[RTAX_NETMASK] = netmask;
 		error = rtrequest1_fib(cmd, &info, &rt, fibnum);
 
-		if ((error == EEXIST) && (cmd == RTM_ADD)) {
-			/*
-			 * Interface route addition failed.
-			 * Atomically delete current prefix generating
-			 * RTM_DELETE message, and retry adding
-			 * interface prefix.
-			 */
-			rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
-			RADIX_NODE_HEAD_LOCK(rnh);
-
-			/* Delete old prefix */
-			info.rti_ifa = NULL;
-			info.rti_flags = RTF_RNH_LOCKED;
-
-			error = rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum);
-			if (error == 0) {
-				info.rti_ifa = ifa;
-				info.rti_flags = flags | RTF_RNH_LOCKED |
-				    (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
-				error = rtrequest1_fib(cmd, &info, &rt, fibnum);
-			}
-
-			RADIX_NODE_HEAD_UNLOCK(rnh);
-		}
-
-
 		if (error == 0 && rt != NULL) {
 			/*
 			 * notify any listening routing agents of the change



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512020817.tB28HViF095714>