patch-2.1.79 linux/net/ipv6/ip6_fib.c
Next file: linux/net/ipv6/ip6_fw.c
Previous file: linux/net/ipv6/icmp.c
Back to the patch index
Back to the overall index
- Lines: 152
- Date:
Mon Jan 12 15:28:28 1998
- Orig file:
v2.1.78/linux/net/ipv6/ip6_fib.c
- Orig date:
Mon Dec 1 12:04:17 1997
diff -u --recursive --new-file v2.1.78/linux/net/ipv6/ip6_fib.c linux/net/ipv6/ip6_fib.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: ip6_fib.c,v 1.9 1997/09/20 20:48:27 davem Exp $
+ * $Id: ip6_fib.c,v 1.10 1997/12/13 21:53:10 kuznet Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -182,6 +182,16 @@
kfree(fn);
}
+extern __inline__ void rt6_release(struct rt6_info *rt)
+{
+ struct dst_entry *dst = (struct dst_entry *) rt;
+ if (atomic_dec_and_test(&dst->refcnt)) {
+ rt->rt6i_node = NULL;
+ dst_free(dst);
+ }
+}
+
+
/*
* Routing Table
*
@@ -409,8 +419,12 @@
if ((iter->rt6i_dev == rt->rt6i_dev) &&
(iter->rt6i_flowr == rt->rt6i_flowr) &&
(ipv6_addr_cmp(&iter->rt6i_gateway,
- &rt->rt6i_gateway) == 0))
+ &rt->rt6i_gateway) == 0)) {
+ if (rt->rt6i_expires == 0 ||
+ rt->rt6i_expires - iter->rt6i_expires > 0)
+ rt->rt6i_expires = iter->rt6i_expires;
return -EEXIST;
+ }
}
if (iter->rt6i_metric > rt->rt6i_metric)
@@ -426,6 +440,9 @@
*ins = rt;
rt->u.next = iter;
atomic_inc(&rt->rt6i_ref);
+#ifdef CONFIG_RTNETLINK
+ inet6_rt_notify(RTM_NEWROUTE, rt);
+#endif
rt6_stats.fib_rt_entries++;
if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -513,6 +530,8 @@
if (err == 0)
fib6_start_gc(rt);
out:
+ if (err)
+ dst_free(&rt->u.dst);
return err;
}
@@ -782,7 +801,11 @@
*/
*back = lf->u.next;
+#ifdef CONFIG_RTNETLINK
+ inet6_rt_notify(RTM_DELROUTE, lf);
+#endif
rt6_release(lf);
+ rt6_stats.fib_rt_entries--;
return fn;
}
back = &lf->u.next;
@@ -810,14 +833,19 @@
/*
* Tree transversal function
*
+ * Wau... It is NOT REENTERABLE!!!!!!! It is cathastrophe. --ANK
*/
+int fib6_walk_count;
+
void fib6_walk_tree(struct fib6_node *root, f_pnode func, void *arg,
int filter)
{
struct fib6_node *fn;
fn = root;
+
+ fib6_walk_count++;
do {
if (!(fn->fn_flags & RTN_TAG)) {
@@ -858,6 +886,8 @@
} while (!(fn->fn_flags & RTN_TAG));
} while (!(fn->fn_flags & RTN_ROOT) || (fn->fn_flags & RTN_TAG));
+
+ fib6_walk_count--;
}
/*
@@ -884,6 +914,10 @@
*back = rt;
old->rt6i_node = NULL;
+#ifdef CONFIG_RTNETLINK
+ inet6_rt_notify(RTM_DELROUTE, old);
+#endif
+ old->u.dst.obsolete = 1;
rt6_release(old);
rt6_stats.fib_rt_entries--;
continue;
@@ -893,7 +927,28 @@
/*
* check addrconf expiration here.
+ *
+ * BUGGGG Crossing fingers and ...
+ * Seems, radix tree walking is absolutely broken,
+ * but we will try in any case --ANK
*/
+ if (rt->rt6i_expires && now - rt->rt6i_expires < 0) {
+ struct rt6_info *old;
+
+ old = rt;
+ rt = rt->u.next;
+
+ *back = rt;
+
+ old->rt6i_node = NULL;
+#ifdef CONFIG_RTNETLINK
+ inet6_rt_notify(RTM_DELROUTE, old);
+#endif
+ old->u.dst.obsolete = 1;
+ rt6_release(old);
+ rt6_stats.fib_rt_entries--;
+ continue;
+ }
back = &rt->u.next;
rt = rt->u.next;
}
@@ -994,7 +1049,10 @@
0
};
- fib6_walk_tree(&ip6_routing_table, fib6_garbage_collect, &arg, 0);
+ if (fib6_walk_count == 0)
+ fib6_walk_tree(&ip6_routing_table, fib6_garbage_collect, &arg, 0);
+ else
+ arg.more = 1;
if (arg.more) {
ip6_fib_timer.expires = jiffies + ipv6_config.rt_gc_period;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov