lib: Fix bug in prefix trie lookup

* lib/table.c: (route_node_match) fix overshoot that was causing this
  function to go 1 bit too far and thus reading past end of prefix.
  (route_node_lookup) be defensive - don't assume others will clean up
  leaves when removing info.
This commit is contained in:
Paul Jakma 2010-04-13 22:42:33 +01:00
parent d358344759
commit f8416810aa

View File

@ -209,6 +209,10 @@ route_node_match (const struct route_table *table, const struct prefix *p)
{ {
if (node->info) if (node->info)
matched = node; matched = node;
if (node->p.prefixlen == p->prefixlen)
break;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
} }
@ -260,8 +264,8 @@ route_node_lookup (struct route_table *table, struct prefix *p)
while (node && node->p.prefixlen <= p->prefixlen && while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p)) prefix_match (&node->p, p))
{ {
if (node->p.prefixlen == p->prefixlen && node->info) if (node->p.prefixlen == p->prefixlen)
return route_lock_node (node); return node->info ? route_lock_node (node) : NULL;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
} }
@ -283,10 +287,8 @@ route_node_get (struct route_table *table, struct prefix *p)
prefix_match (&node->p, p)) prefix_match (&node->p, p))
{ {
if (node->p.prefixlen == p->prefixlen) if (node->p.prefixlen == p->prefixlen)
{ return route_lock_node (node);
route_lock_node (node);
return node;
}
match = node; match = node;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
} }