summaryrefslogtreecommitdiff
path: root/lib/table.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/table.c')
-rw-r--r--lib/table.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/table.c b/lib/table.c
index 5133ef6974..7f789dd3cd 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -28,7 +28,7 @@
#include "sockunion.h"
DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table")
-DEFINE_MTYPE_STATIC(LIB, ROUTE_NODE, "Route node")
+DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node")
static void route_node_delete (struct route_node *);
static void route_table_free (struct route_table *);
@@ -78,6 +78,8 @@ route_node_set (struct route_table *table, const struct prefix *prefix)
static void
route_node_free (struct route_table *table, struct route_node *node)
{
+ if (table->cleanup)
+ table->cleanup(table, node);
table->delegate->destroy_node (table->delegate, table, node);
}
@@ -250,7 +252,6 @@ route_node_match_ipv4 (const struct route_table *table,
return route_node_match (table, (struct prefix *) &p);
}
-#ifdef HAVE_IPV6
struct route_node *
route_node_match_ipv6 (const struct route_table *table,
const struct in6_addr *addr)
@@ -264,7 +265,6 @@ route_node_match_ipv6 (const struct route_table *table,
return route_node_match (table, (struct prefix *) &p);
}
-#endif /* HAVE_IPV6 */
/* Lookup same prefix node. Return NULL when we can't find route. */
struct route_node *
@@ -288,6 +288,28 @@ route_node_lookup (const struct route_table *table, const struct prefix *p)
return NULL;
}
+/* Lookup same prefix node. Return NULL when we can't find route. */
+struct route_node *
+route_node_lookup_maynull (const struct route_table *table, const struct prefix *p)
+{
+ struct route_node *node;
+ u_char prefixlen = p->prefixlen;
+ const u_char *prefix = &p->u.prefix;
+
+ node = table->top;
+
+ while (node && node->p.prefixlen <= prefixlen &&
+ prefix_match (&node->p, p))
+ {
+ if (node->p.prefixlen == prefixlen)
+ return route_lock_node (node);
+
+ node = node->link[prefix_bit(prefix, node->p.prefixlen)];
+ }
+
+ return NULL;
+}
+
/* Add node to routing table. */
struct route_node *
route_node_get (struct route_table *const table, const struct prefix *p)
@@ -380,6 +402,14 @@ route_node_delete (struct route_node *node)
node->table->count--;
+ /* WARNING: FRAGILE CODE!
+ * route_node_free may have the side effect of free'ing the entire table.
+ * this is permitted only if table->count got decremented to zero above,
+ * because in that case parent will also be NULL, so that we won't try to
+ * delete a now-stale parent below.
+ *
+ * cf. srcdest_srcnode_destroy() in zebra/zebra_rib.c */
+
route_node_free (node->table, node);
/* If parent node is stub then delete it also. */