patch-2.4.3 linux/net/ipv6/ip6_fib.c
Next file: linux/net/ipv6/ipv6_sockglue.c
Previous file: linux/net/ipv4/sysctl_net_ipv4.c
Back to the patch index
Back to the overall index
- Lines: 73
- Date:
Sun Mar 25 18:14:25 2001
- Orig file:
v2.4.2/linux/net/ipv6/ip6_fib.c
- Orig date:
Sun Sep 17 10:03:43 2000
diff -u --recursive --new-file v2.4.2/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.22 2000/09/12 00:38:34 davem Exp $
+ * $Id: ip6_fib.c,v 1.23 2001/03/19 20:31:17 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -76,7 +76,7 @@
#endif
static void fib6_prune_clones(struct fib6_node *fn, struct rt6_info *rt);
-static void fib6_repair_tree(struct fib6_node *fn);
+static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
/*
* A routing update causes an increase of the serial number on the
@@ -774,7 +774,7 @@
* is the node we want to try and remove.
*/
-static void fib6_repair_tree(struct fib6_node *fn)
+static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
{
int children;
int nstate;
@@ -809,7 +809,7 @@
}
#endif
atomic_inc(&fn->leaf->rt6i_ref);
- return;
+ return fn->parent;
}
pn = fn->parent;
@@ -865,7 +865,7 @@
node_free(fn);
if (pn->fn_flags&RTN_RTINFO || SUBTREE(pn))
- return;
+ return pn;
rt6_release(pn->leaf);
pn->leaf = NULL;
@@ -903,7 +903,26 @@
if (fn->leaf == NULL) {
fn->fn_flags &= ~RTN_RTINFO;
rt6_stats.fib_route_nodes--;
- fib6_repair_tree(fn);
+ fn = fib6_repair_tree(fn);
+ }
+
+ if (atomic_read(&rt->rt6i_ref) != 1) {
+ /* This route is used as dummy address holder in some split
+ * nodes. It is not leaked, but it still holds other resources,
+ * which must be released in time. So, scan ascendant nodes
+ * and replace dummy references to this route with references
+ * to still alive ones.
+ */
+ while (fn) {
+ if (!(fn->fn_flags&RTN_RTINFO) && fn->leaf == rt) {
+ fn->leaf = fib6_find_prefix(fn);
+ atomic_inc(&fn->leaf->rt6i_ref);
+ rt6_release(rt);
+ }
+ fn = fn->parent;
+ }
+ /* No more references are possiible at this point. */
+ if (atomic_read(&rt->rt6i_ref) != 1) BUG();
}
#ifdef CONFIG_RTNETLINK
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)