svn commit: r248942 - stable/8/sys/net

Alexander V. Chernikov melifaro at FreeBSD.org
Sun Mar 31 10:17:40 UTC 2013


Author: melifaro
Date: Sun Mar 31 10:17:39 2013
New Revision: 248942
URL: http://svnweb.freebsd.org/changeset/base/248942

Log:
  Merge r248070.
  
  Fix long-standing issue with interface routes being unprotected:
  Use RTM_PINNED flag to mark route as immutable.
  Forbid deleting immutable routes without special rtrequest1_fib() flag.
  Adding interface address with prefix already in route table is handled
  by atomically deleting old prefix and adding interface one.

Modified:
  stable/8/sys/net/if.c
  stable/8/sys/net/route.c
  stable/8/sys/net/route.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/net/   (props changed)

Modified: stable/8/sys/net/if.c
==============================================================================
--- stable/8/sys/net/if.c	Sun Mar 31 08:54:04 2013	(r248941)
+++ stable/8/sys/net/if.c	Sun Mar 31 10:17:39 2013	(r248942)
@@ -1412,7 +1412,8 @@ if_rtdel(struct radix_node *rn, void *ar
 			return (0);
 
 		err = rtrequest_fib(RTM_DELETE, rt_key(rt), rt->rt_gateway,
-				rt_mask(rt), rt->rt_flags|RTF_RNH_LOCKED,
+				rt_mask(rt),
+				rt->rt_flags|RTF_RNH_LOCKED|RTF_PINNED,
 				(struct rtentry **) NULL, rt->rt_fibnum);
 		if (err) {
 			log(LOG_WARNING, "if_rtdel: error %d\n", err);

Modified: stable/8/sys/net/route.c
==============================================================================
--- stable/8/sys/net/route.c	Sun Mar 31 08:54:04 2013	(r248941)
+++ stable/8/sys/net/route.c	Sun Mar 31 10:17:39 2013	(r248942)
@@ -1112,6 +1112,14 @@ rtrequest1_fib(int req, struct rt_addrin
 			error = 0;
 		}
 #endif
+		if ((flags & RTF_PINNED) == 0) {
+			/* Check if target route can be deleted */
+			rt = (struct rtentry *)rnh->rnh_lookup(dst,
+			    netmask, rnh);
+			if ((rt != NULL) && (rt->rt_flags & RTF_PINNED))
+				senderr(EADDRINUSE);
+		}
+
 		/*
 		 * Remove the item from the tree and return it.
 		 * Complain if it is not there and do no more processing.
@@ -1439,6 +1447,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 	int didwork = 0;
 	int a_failure = 0;
 	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+	struct radix_node_head *rnh;
 
 	if (flags & RTF_HOST) {
 		dst = ifa->ifa_dstaddr;
@@ -1497,7 +1506,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 	 */
 	for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
 		if (cmd == RTM_DELETE) {
-			struct radix_node_head *rnh;
 			struct radix_node *rn;
 			/*
 			 * Look up an rtentry that is in the routing tree and
@@ -1547,7 +1555,8 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 		 */
 		bzero((caddr_t)&info, sizeof(info));
 		info.rti_ifa = ifa;
-		info.rti_flags = flags | (ifa->ifa_flags & ~IFA_RTSELF);
+		info.rti_flags = flags |
+		    (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
 		info.rti_info[RTAX_DST] = dst;
 		/* 
 		 * doing this for compatibility reasons
@@ -1559,6 +1568,33 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
 		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, &rt, 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

Modified: stable/8/sys/net/route.h
==============================================================================
--- stable/8/sys/net/route.h	Sun Mar 31 08:54:04 2013	(r248941)
+++ stable/8/sys/net/route.h	Sun Mar 31 10:17:39 2013	(r248942)
@@ -171,7 +171,7 @@ struct ortentry {
 /*			0x20000		   unused, was RTF_WASCLONED */
 #define RTF_PROTO3	0x40000		/* protocol specific routing flag */
 /*			0x80000		   unused */
-#define RTF_PINNED	0x100000	/* future use */
+#define RTF_PINNED	0x100000	/* route is immutable */
 #define	RTF_LOCAL	0x200000 	/* route represents a local address */
 #define	RTF_BROADCAST	0x400000	/* route represents a bcast address */
 #define	RTF_MULTICAST	0x800000	/* route represents a mcast address */


More information about the svn-src-all mailing list