int prefix_contains (const struct prefix *container, const struct prefix *containee) { int i; if (container->prefixlen > containee->prefixlen) return 0; if(container->family != containee->family) return 0; for (i = 0; i < container->prefixlen; i++) { if (prefix_bit (&container->u.prefix, i) != prefix_bit (&containee->u.prefix, i)) { return 0; } } return 1; }
void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, uint8_t maxlen, struct list *matches) { struct bgp_node *node = bgp_node_from_rnode(table->route_table->top); struct bgp_node *matched = NULL; while (node && node->p.prefixlen <= p->prefixlen && prefix_match(&node->p, p)) { if (node->info && node->p.prefixlen == p->prefixlen) { matched = node; break; } node = bgp_node_from_rnode(node->link[prefix_bit( &p->u.prefix, node->p.prefixlen)]); } if (node == NULL) return; if ((matched == NULL && node->p.prefixlen > maxlen) || !node->parent) return; else if (matched == NULL) matched = node = bgp_node_from_rnode(node->parent); if (matched->info) { bgp_lock_node(matched); listnode_add(matches, matched); } while ((node = bgp_route_next_until_maxlen(node, matched, maxlen))) { if (prefix_match(p, &node->p)) { if (node->info) { bgp_lock_node(node); listnode_add(matches, node); } } } }
unsigned int prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen) { return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen); }
struct ospf6_lsa * ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router, struct ospf6_lsdb *lsdb) { struct route_node *node; struct route_node *matched = NULL; struct prefix_ipv6 key; struct prefix *p; if (lsdb == NULL) return NULL; memset (&key, 0, sizeof (key)); ospf6_lsdb_set_key (&key, &type, sizeof (type)); ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); ospf6_lsdb_set_key (&key, &id, sizeof (id)); p = (struct prefix *) &key; { char buf[64]; prefix2str (p, buf, sizeof (buf)); zlog_debug ("lsdb_lookup_next: key: %s", buf); } node = lsdb->table->top; /* walk down tree. */ while (node && node->p.prefixlen <= p->prefixlen && prefix_match (&node->p, p)) { matched = node; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } if (matched) node = matched; else node = lsdb->table->top; route_lock_node (node); /* skip to real existing entry */ while (node && node->info == NULL) node = route_next (node); if (! node) return NULL; if (prefix_same (&node->p, p)) { struct route_node *prev = node; struct ospf6_lsa *lsa_prev; struct ospf6_lsa *lsa_next; node = route_next (node); while (node && node->info == NULL) node = route_next (node); lsa_prev = prev->info; lsa_next = (node ? node->info : NULL); assert (lsa_prev); assert (lsa_prev->next == lsa_next); if (lsa_next) assert (lsa_next->prev == lsa_prev); zlog_debug ("lsdb_lookup_next: assert OK with previous LSA"); } if (! node) return NULL; route_unlock_node (node); return (struct ospf6_lsa *) node->info; }