patch-2.1.9 linux/net/ipv6/ipv6_route.c

Next file: linux/net/ipv6/ipv6_sockglue.c
Previous file: linux/net/ipv6/ipv6_output.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.8/linux/net/ipv6/ipv6_route.c linux/net/ipv6/ipv6_route.c
@@ -838,7 +838,7 @@
 
 void fib6_flush(void)
 {
-	rt6_walk_tree(fib6_flush_1, NULL, 0);
+	rt6_walk_tree(fib6_flush_1, NULL, RT6_FILTER_NONE);
 }
 
 int ipv6_route_add(struct in6_rtmsg *rtmsg)
@@ -958,10 +958,12 @@
 	{
 		if (src_dev)
 		{
-			for (; rt; rt=rt->next)
+			struct rt6_info *sprt;
+
+			for (sprt=rt; sprt; sprt=sprt->next)
 			{
-				if (rt->rt_dev == src_dev)
-					return rt;
+				if (sprt->rt_dev == src_dev)
+					return sprt;
 			}
 			
 			if (flags & RTI_DEVRT)
@@ -980,7 +982,7 @@
 			return rt;
 		}
 
-		return last_resort_rt;		
+		return last_resort_rt;
 	}
 
 	return NULL;
@@ -1535,7 +1537,7 @@
 				args.timeout = DC_LONG_TIMEOUT;
 
 			args.more = 0;
-			rt6_walk_tree(dc_garbage_collect, &args, 0);
+			rt6_walk_tree(dc_garbage_collect, &args, RT6_FILTER_NONE);
 
 			last_gc_run = jiffies;
 			
@@ -1570,7 +1572,7 @@
 		 *	route expiry
 		 */
 		
-		rt6_walk_tree(rt6_rt_timeout, NULL, 1);
+		rt6_walk_tree(rt6_rt_timeout, NULL, RT6_FILTER_RTNODES);
 	}
 
 	restore_flags(flags);
@@ -1631,6 +1633,31 @@
 	return -EINVAL;
 }
 
+static void rt6_ifdown_scan(struct fib6_node *fn, void *arg)
+{
+	struct rt6_info *rt;
+	struct device *dev = (struct device *) arg;
+
+	for (rt = fn->leaf; rt; rt=rt->next)
+	{
+		if (((rt->rt_flags & RTI_DCACHE) == 0) && rt->rt_dev == dev)
+		{
+			struct rt6_req *req;
+
+			req = kmalloc(sizeof(struct rt6_req), GFP_ATOMIC);
+			req->operation = RT_OPER_DEL;
+			req->ptr  = rt;
+			req->next = req->prev = NULL;
+			rt6_bh_mask |= RT_BH_REQUEST;
+		}
+	}
+}
+
+void rt6_ifdown(struct device *dev)
+{
+	rt6_walk_tree(rt6_ifdown_scan, (void *) dev, RT6_FILTER_RTNODES);
+}
+
 static void rt6_walk_tree(f_pnode func, void * arg, int filter)
 {
 	struct fib6_node *fn;
@@ -1751,7 +1778,7 @@
 	arg.skip = 0;
 	arg.len = 0;
 
-	rt6_walk_tree(rt6_info_node, &arg, 1);
+	rt6_walk_tree(rt6_info_node, &arg, RT6_FILTER_RTNODES);
 	
 	sfn.leaf = default_rt_list;
 	rt6_info_node(&sfn, &arg);
@@ -1795,6 +1822,11 @@
 
 #endif			/* CONFIG_PROC_FS */
 
+/*
+ *	init/cleanup code
+ *
+ */
+
 void ipv6_route_init(void)
 {
 #ifdef 	CONFIG_PROC_FS
@@ -1875,6 +1907,11 @@
 	struct in6_rtmsg *msg;
 	
 	skb = alloc_skb(sizeof(struct in6_rtmsg), GFP_ATOMIC);
+	if (skb == NULL)
+		return;
+
+	skb->free = 1;
+
 	msg = (struct in6_rtmsg *) skb_put(skb, sizeof(struct in6_rtmsg));
 	
 	msg->rtmsg_type = type;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov