svn commit: r248895 - stable/9/sys/net
Alexander V. Chernikov
melifaro at FreeBSD.org
Fri Mar 29 16:24:21 UTC 2013
Author: melifaro
Date: Fri Mar 29 16:24:20 2013
New Revision: 248895
URL: http://svnweb.freebsd.org/changeset/base/248895
Log:
Merge 248070.
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/9/sys/net/if.c
stable/9/sys/net/route.c
stable/9/sys/net/route.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/net/ (props changed)
Modified: stable/9/sys/net/if.c
==============================================================================
--- stable/9/sys/net/if.c Fri Mar 29 16:16:50 2013 (r248894)
+++ stable/9/sys/net/if.c Fri Mar 29 16:24:20 2013 (r248895)
@@ -1379,7 +1379,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/9/sys/net/route.c
==============================================================================
--- stable/9/sys/net/route.c Fri Mar 29 16:16:50 2013 (r248894)
+++ stable/9/sys/net/route.c Fri Mar 29 16:24:20 2013 (r248895)
@@ -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.
@@ -1435,6 +1443,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;
@@ -1493,7 +1502,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
@@ -1543,7 +1551,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
@@ -1555,6 +1564,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/9/sys/net/route.h
==============================================================================
--- stable/9/sys/net/route.h Fri Mar 29 16:16:50 2013 (r248894)
+++ stable/9/sys/net/route.h Fri Mar 29 16:24:20 2013 (r248895)
@@ -176,7 +176,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-stable-9
mailing list