From 67174041d2d9d8908f8b2c915bc0d186d8442c68 Mon Sep 17 00:00:00 2001 From: Avneesh Sachdev Date: Fri, 17 Aug 2012 08:19:49 -0700 Subject: bgpd: make bgp_table a wrapper around table library Make the BGP table code a thin wrapper around the table implementation in libzebra. * bgpd/bgp_table.[ch] - Use the ROUTE_NODE_FIELDS macro to embed the fields of a route_node in the bgp_node structure. - Add a route_table field to the bgp_table structure. Initialize the route_table with a delegate, such that the nodes in the table are bgp_node structures. - Add inline wrappers that call route_table functions underneath, and accept/return the correct BGP types. * bgpd/bgp_route.c Change some code to use inline wrappers instead of accessing fields of nodes/tables directly. The latter does not always work because the types of some fields need to be translated now. Signed-off-by: David Lamparter --- bgpd/bgp_route.c | 44 ++--- bgpd/bgp_table.c | 481 ++++++------------------------------------------------- bgpd/bgp_table.h | 240 +++++++++++++++++++++++---- 3 files changed, 285 insertions(+), 480 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0337224a..2412503d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -240,11 +240,15 @@ bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri) static void bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) { - assert (rn && rn->table); + struct bgp_table *table; + + assert (rn && bgp_node_table (rn)); assert (ri && ri->peer && ri->peer->bgp); + table = bgp_node_table (rn); + /* Ignore 'pcount' for RS-client tables */ - if (rn->table->type != BGP_TABLE_MAIN + if (table->type != BGP_TABLE_MAIN || ri->peer == ri->peer->bgp->peer_self) return; @@ -255,8 +259,8 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) UNSET_FLAG (ri->flags, BGP_INFO_COUNTED); /* slight hack, but more robust against errors. */ - if (ri->peer->pcount[rn->table->afi][rn->table->safi]) - ri->peer->pcount[rn->table->afi][rn->table->safi]--; + if (ri->peer->pcount[table->afi][table->safi]) + ri->peer->pcount[table->afi][table->safi]--; else { zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s", @@ -269,7 +273,7 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) { SET_FLAG (ri->flags, BGP_INFO_COUNTED); - ri->peer->pcount[rn->table->afi][rn->table->safi]++; + ri->peer->pcount[table->afi][table->safi]++; } } @@ -1448,7 +1452,7 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected, /* It's initialized in bgp_announce_[check|check_rsclient]() */ attr.extra = &extra; - switch (rn->table->type) + switch (bgp_node_table (rn)->type) { case BGP_TABLE_MAIN: /* Announcement to peer->conf. If the route is filtered, @@ -1492,7 +1496,7 @@ bgp_process_rsclient (struct work_queue *wq, void *data) struct bgp_info *old_select; struct bgp_info_pair old_and_new; struct listnode *node, *nnode; - struct peer *rsclient = rn->table->owner; + struct peer *rsclient = bgp_node_table (rn)->owner; /* Best path selection. */ bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new); @@ -1623,7 +1627,7 @@ static void bgp_processq_del (struct work_queue *wq, void *data) { struct bgp_process_queue *pq = data; - struct bgp_table *table = pq->rn->table; + struct bgp_table *table = bgp_node_table (pq->rn); bgp_unlock (pq->bgp); bgp_unlock_node (pq->rn); @@ -1674,14 +1678,14 @@ bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi) return; /* all unlocked in bgp_processq_del */ - bgp_table_lock (rn->table); + bgp_table_lock (bgp_node_table (rn)); pqnode->rn = bgp_lock_node (rn); pqnode->bgp = bgp; bgp_lock (bgp); pqnode->afi = afi; pqnode->safi = safi; - switch (rn->table->type) + switch (bgp_node_table (rn)->type) { case BGP_TABLE_MAIN: work_queue_add (bm->process_main_queue, pqnode); @@ -2719,8 +2723,8 @@ bgp_clear_route_node (struct work_queue *wq, void *data) struct bgp_node *rn = cnq->rn; struct peer *peer = wq->spec.data; struct bgp_info *ri; - afi_t afi = rn->table->afi; - safi_t safi = rn->table->safi; + afi_t afi = bgp_node_table (rn)->afi; + safi_t safi = bgp_node_table (rn)->safi; assert (rn && peer); @@ -2745,7 +2749,7 @@ bgp_clear_node_queue_del (struct work_queue *wq, void *data) { struct bgp_clear_node_queue *cnq = data; struct bgp_node *rn = cnq->rn; - struct bgp_table *table = rn->table; + struct bgp_table *table = bgp_node_table (rn); bgp_unlock_node (rn); bgp_table_unlock (table); @@ -2847,7 +2851,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, struct bgp_clear_node_queue *cnq; /* both unlocked in bgp_clear_node_queue_del */ - bgp_table_lock (rn->table); + bgp_table_lock (bgp_node_table (rn)); bgp_lock_node (rn); cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, sizeof (struct bgp_clear_node_queue)); @@ -4669,7 +4673,7 @@ bgp_aggregate_increment (struct bgp *bgp, struct prefix *p, table = bgp->aggregate[afi][safi]; /* No aggregates configured. */ - if (table->top == NULL) + if (bgp_table_top_nolock (table) == NULL) return; if (p->prefixlen == 0) @@ -4681,7 +4685,7 @@ bgp_aggregate_increment (struct bgp *bgp, struct prefix *p, child = bgp_node_get (table, p); /* Aggregate address configuration check. */ - for (rn = child; rn; rn = rn->parent) + for (rn = child; rn; rn = bgp_node_parent_nolock (rn)) if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen) { bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate); @@ -4706,7 +4710,7 @@ bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p, table = bgp->aggregate[afi][safi]; /* No aggregates configured. */ - if (table->top == NULL) + if (bgp_table_top_nolock (table) == NULL) return; if (p->prefixlen == 0) @@ -4715,7 +4719,7 @@ bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p, child = bgp_node_get (table, p); /* Aggregate address configuration check. */ - for (rn = child; rn; rn = rn->parent) + for (rn = child; rn; rn = bgp_node_parent_nolock (rn)) if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen) { bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate); @@ -9299,7 +9303,7 @@ bgp_table_stats_walker (struct thread *t) for (rn = top; rn; rn = bgp_route_next (rn)) { struct bgp_info *ri; - struct bgp_node *prn = rn->parent; + struct bgp_node *prn = bgp_node_parent_nolock (rn); unsigned int rinum = 0; if (rn == top) @@ -9320,7 +9324,7 @@ bgp_table_stats_walker (struct thread *t) /* check if the prefix is included by any other announcements */ while (prn && !prn->info) - prn = prn->parent; + prn = bgp_node_parent_nolock (prn); if (prn == NULL || prn == top) { diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 3385a934..7a6c675d 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -28,24 +28,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" -static void bgp_node_delete (struct bgp_node *); -static void bgp_table_free (struct bgp_table *); - -struct bgp_table * -bgp_table_init (afi_t afi, safi_t safi) -{ - struct bgp_table *rt; - - rt = XCALLOC (MTYPE_BGP_TABLE, sizeof (struct bgp_table)); - - bgp_table_lock(rt); - rt->type = BGP_TABLE_MAIN; - rt->afi = afi; - rt->safi = safi; - - return rt; -} - void bgp_table_lock (struct bgp_table *rt) { @@ -58,97 +40,13 @@ bgp_table_unlock (struct bgp_table *rt) assert (rt->lock > 0); rt->lock--; - if (rt->lock == 0) - bgp_table_free (rt); -} - -void -bgp_table_finish (struct bgp_table **rt) -{ - if (*rt != NULL) + if (rt->lock != 0) { - bgp_table_unlock(*rt); - *rt = NULL; + return; } -} - -static struct bgp_node * -bgp_node_create (void) -{ - return XCALLOC (MTYPE_BGP_NODE, sizeof (struct bgp_node)); -} - -/* Allocate new route node with prefix set. */ -static struct bgp_node * -bgp_node_set (struct bgp_table *table, struct prefix *prefix) -{ - struct bgp_node *node; - - node = bgp_node_create (); - - prefix_copy (&node->p, prefix); - node->table = table; - - return node; -} - -/* Free route node. */ -static void -bgp_node_free (struct bgp_node *node) -{ - XFREE (MTYPE_BGP_NODE, node); -} - -/* Free route table. */ -static void -bgp_table_free (struct bgp_table *rt) -{ - struct bgp_node *tmp_node; - struct bgp_node *node; - - if (rt == NULL) - return; - - node = rt->top; - - /* Bulk deletion of nodes remaining in this table. This function is not - called until workers have completed their dependency on this table. - A final bgp_unlock_node() will not be called for these nodes. */ - while (node) - { - if (node->l_left) - { - node = node->l_left; - continue; - } - - if (node->l_right) - { - node = node->l_right; - continue; - } - tmp_node = node; - node = node->parent; - - tmp_node->table->count--; - tmp_node->lock = 0; /* to cause assert if unlocked after this */ - bgp_node_free (tmp_node); - - if (node != NULL) - { - if (node->l_left == tmp_node) - node->l_left = NULL; - else - node->l_right = NULL; - } - else - { - break; - } - } - - assert (rt->count == 0); + route_table_finish (rt->route_table); + rt->route_table = NULL; if (rt->owner) { @@ -157,354 +55,71 @@ bgp_table_free (struct bgp_table *rt) } XFREE (MTYPE_BGP_TABLE, rt); - return; -} - -/* Utility mask array. */ -static u_char maskbit[] = -{ - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff -}; - -/* Common prefix route genaration. */ -static void -route_common (struct prefix *n, struct prefix *p, struct prefix *new) -{ - int i; - u_char diff; - u_char mask; - - u_char *np = (u_char *)&n->u.prefix; - u_char *pp = (u_char *)&p->u.prefix; - u_char *newp = (u_char *)&new->u.prefix; - - for (i = 0; i < p->prefixlen / 8; i++) - { - if (np[i] == pp[i]) - newp[i] = np[i]; - else - break; - } - - new->prefixlen = i * 8; - - if (new->prefixlen != p->prefixlen) - { - diff = np[i] ^ pp[i]; - mask = 0x80; - while (new->prefixlen < p->prefixlen && !(mask & diff)) - { - mask >>= 1; - new->prefixlen++; - } - newp[i] = np[i] & maskbit[new->prefixlen % 8]; - } -} - -static void -set_link (struct bgp_node *node, struct bgp_node *new) -{ - unsigned int bit = prefix_bit (&new->p.u.prefix, node->p.prefixlen); - - node->link[bit] = new; - new->parent = node; } -/* Lock node. */ -struct bgp_node * -bgp_lock_node (struct bgp_node *node) -{ - node->lock++; - return node; -} - -/* Unlock node. */ void -bgp_unlock_node (struct bgp_node *node) -{ - assert (node->lock > 0); - node->lock--; - - if (node->lock == 0) - bgp_node_delete (node); -} - -/* Find matched prefix. */ -struct bgp_node * -bgp_node_match (const struct bgp_table *table, struct prefix *p) -{ - struct bgp_node *node; - struct bgp_node *matched; - - matched = NULL; - node = table->top; - - /* Walk down tree. If there is matched route then store it to - matched. */ - while (node && node->p.prefixlen <= p->prefixlen && - prefix_match (&node->p, p)) - { - if (node->info) - matched = node; - node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; - } - - /* If matched route found, return it. */ - if (matched) - return bgp_lock_node (matched); - - return NULL; -} - -struct bgp_node * -bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr) -{ - struct prefix_ipv4 p; - - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = *addr; - - return bgp_node_match (table, (struct prefix *) &p); -} - -#ifdef HAVE_IPV6 -struct bgp_node * -bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr) -{ - struct prefix_ipv6 p; - - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_PREFIXLEN; - p.prefix = *addr; - - return bgp_node_match (table, (struct prefix *) &p); -} -#endif /* HAVE_IPV6 */ - -/* Lookup same prefix node. Return NULL when we can't find route. */ -struct bgp_node * -bgp_node_lookup (const struct bgp_table *table, struct prefix *p) +bgp_table_finish (struct bgp_table **rt) { - struct bgp_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 (*rt != NULL) { - if (node->p.prefixlen == prefixlen && node->info) - return bgp_lock_node (node); - - node = node->link[prefix_bit(prefix, node->p.prefixlen)]; + bgp_table_unlock(*rt); + *rt = NULL; } - - return NULL; } -/* Add node to routing table. */ -struct bgp_node * -bgp_node_get (struct bgp_table *const table, struct prefix *p) +/* + * bgp_node_create + */ +static struct route_node * +bgp_node_create (route_table_delegate_t *delegate, struct route_table *table) { - struct bgp_node *new; struct bgp_node *node; - struct bgp_node *match; - u_char prefixlen = p->prefixlen; - const u_char *prefix = &p->u.prefix; - - match = NULL; - node = table->top; - while (node && node->p.prefixlen <= prefixlen && - prefix_match (&node->p, p)) - { - if (node->p.prefixlen == prefixlen) - { - bgp_lock_node (node); - return node; - } - match = node; - node = node->link[prefix_bit(prefix, node->p.prefixlen)]; - } - - if (node == NULL) - { - new = bgp_node_set (table, p); - if (match) - set_link (match, new); - else - table->top = new; - } - else - { - new = bgp_node_create (); - route_common (&node->p, p, &new->p); - new->p.family = p->family; - new->table = table; - set_link (new, node); - - if (match) - set_link (match, new); - else - table->top = new; - - if (new->p.prefixlen != prefixlen) - { - match = new; - new = bgp_node_set (table, p); - set_link (match, new); - table->count++; - } - } - table->count++; - bgp_lock_node (new); - - return new; + node = XCALLOC (MTYPE_BGP_NODE, sizeof (struct bgp_node)); + return bgp_node_to_rnode (node); } -/* Delete node from the routing table. */ +/* + * bgp_node_destroy + */ static void -bgp_node_delete (struct bgp_node *node) +bgp_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) { - struct bgp_node *child; - struct bgp_node *parent; - - assert (node->lock == 0); - assert (node->info == NULL); - - if (node->l_left && node->l_right) - return; - - if (node->l_left) - child = node->l_left; - else - child = node->l_right; - - parent = node->parent; - - if (child) - child->parent = parent; - - if (parent) - { - if (parent->l_left == node) - parent->l_left = child; - else - parent->l_right = child; - } - else - node->table->top = child; - - node->table->count--; - - bgp_node_free (node); - - /* If parent node is stub then delete it also. */ - if (parent && parent->lock == 0) - bgp_node_delete (parent); + struct bgp_node *bgp_node; + bgp_node = bgp_node_from_rnode (node); + XFREE (MTYPE_BGP_NODE, bgp_node); } -/* Get fist node and lock it. This function is useful when one want - to lookup all the node exist in the routing table. */ -struct bgp_node * -bgp_table_top (const struct bgp_table *const table) -{ - /* If there is no node in the routing table return NULL. */ - if (table->top == NULL) - return NULL; - - /* Lock the top node and return it. */ - bgp_lock_node (table->top); - return table->top; -} +/* + * Function vector to customize the behavior of the route table + * library for BGP route tables. + */ +route_table_delegate_t bgp_table_delegate = { + .create_node = bgp_node_create, + .destroy_node = bgp_node_destroy +}; -/* Unlock current node and lock next node then return it. */ -struct bgp_node * -bgp_route_next (struct bgp_node *node) +/* + * bgp_table_init + */ +struct bgp_table * +bgp_table_init (afi_t afi, safi_t safi) { - struct bgp_node *next; - struct bgp_node *start; - - /* Node may be deleted from bgp_unlock_node so we have to preserve - next node's pointer. */ - - if (node->l_left) - { - next = node->l_left; - bgp_lock_node (next); - bgp_unlock_node (node); - return next; - } - if (node->l_right) - { - next = node->l_right; - bgp_lock_node (next); - bgp_unlock_node (node); - return next; - } + struct bgp_table *rt; - start = node; - while (node->parent) - { - if (node->parent->l_left == node && node->parent->l_right) - { - next = node->parent->l_right; - bgp_lock_node (next); - bgp_unlock_node (start); - return next; - } - node = node->parent; - } - bgp_unlock_node (start); - return NULL; -} + rt = XCALLOC (MTYPE_BGP_TABLE, sizeof (struct bgp_table)); -/* Unlock current node and lock next node until limit. */ -struct bgp_node * -bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit) -{ - struct bgp_node *next; - struct bgp_node *start; + rt->route_table = route_table_init_with_delegate (&bgp_table_delegate); - /* Node may be deleted from bgp_unlock_node so we have to preserve - next node's pointer. */ + /* + * Set up back pointer to bgp_table. + */ + rt->route_table->info = rt; - if (node->l_left) - { - next = node->l_left; - bgp_lock_node (next); - bgp_unlock_node (node); - return next; - } - if (node->l_right) - { - next = node->l_right; - bgp_lock_node (next); - bgp_unlock_node (node); - return next; - } - - start = node; - while (node->parent && node != limit) - { - if (node->parent->l_left == node && node->parent->l_right) - { - next = node->parent->l_right; - bgp_lock_node (next); - bgp_unlock_node (start); - return next; - } - node = node->parent; - } - bgp_unlock_node (start); - return NULL; -} + bgp_table_lock (rt); + rt->type = BGP_TABLE_MAIN; + rt->afi = afi; + rt->safi = safi; -unsigned long -bgp_table_count (const struct bgp_table *table) -{ - return table->count; + return rt; } diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index 53df0bc6..ff42399f 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGP_TABLE_H #define _QUAGGA_BGP_TABLE_H +#include "table.h" + typedef enum { BGP_TABLE_MAIN, @@ -40,22 +42,20 @@ struct bgp_table /* The owner of this 'bgp_table' structure. */ struct peer *owner; - struct bgp_node *top; - - unsigned long count; + struct route_table *route_table; }; struct bgp_node { - struct prefix p; - - struct bgp_table *table; - struct bgp_node *parent; - struct bgp_node *link[2]; -#define l_left link[0] -#define l_right link[1] - - void *info; + /* + * CAUTION + * + * These fields must be the very first fields in this structure. + * + * @see bgp_node_to_rnode + * @see bgp_node_from_rnode + */ + ROUTE_NODE_FIELDS; struct bgp_adj_out *adj_out; @@ -63,8 +63,6 @@ struct bgp_node struct bgp_node *prn; - int lock; - u_char flags; #define BGP_NODE_PROCESS_SCHEDULED (1 << 0) }; @@ -73,19 +71,207 @@ extern struct bgp_table *bgp_table_init (afi_t, safi_t); extern void bgp_table_lock (struct bgp_table *); extern void bgp_table_unlock (struct bgp_table *); extern void bgp_table_finish (struct bgp_table **); -extern void bgp_unlock_node (struct bgp_node *node); -extern struct bgp_node *bgp_table_top (const struct bgp_table *const); -extern struct bgp_node *bgp_route_next (struct bgp_node *); -extern struct bgp_node *bgp_route_next_until (struct bgp_node *, struct bgp_node *); -extern struct bgp_node *bgp_node_get (struct bgp_table *const, struct prefix *); -extern struct bgp_node *bgp_node_lookup (const struct bgp_table *const, struct prefix *); -extern struct bgp_node *bgp_lock_node (struct bgp_node *node); -extern struct bgp_node *bgp_node_match (const struct bgp_table *, struct prefix *); -extern struct bgp_node *bgp_node_match_ipv4 (const struct bgp_table *, - struct in_addr *); + + +/* + * bgp_node_from_rnode + * + * Returns the bgp_node structure corresponding to a route_node. + */ +static inline struct bgp_node * +bgp_node_from_rnode (struct route_node *rnode) +{ + return (struct bgp_node *) rnode; +} + +/* + * bgp_node_to_rnode + * + * Returns the route_node structure corresponding to a bgp_node. + */ +static inline struct route_node * +bgp_node_to_rnode (struct bgp_node *node) +{ + return (struct route_node *) node; +} + +/* + * bgp_node_table + * + * Returns the bgp_table that the given node is in. + */ +static inline struct bgp_table * +bgp_node_table (struct bgp_node *node) +{ + return bgp_node_to_rnode (node)->table->info; +} + +/* + * bgp_node_info + * + * Returns the 'info' pointer corresponding to a bgp node. + */ +static inline void * +bgp_node_info (const struct bgp_node *node) +{ + return node->info; +} + +/* + * bgp_node_set_info + */ +static inline void +bgp_node_set_info (struct bgp_node *node, void *info) +{ + node->info = info; +} + +/* + * bgp_node_prefix + */ +static inline struct prefix * +bgp_node_prefix (struct bgp_node *node) +{ + return &node->p; +} + +/* + * bgp_node_prefixlen + */ +static inline u_char +bgp_node_prefixlen (struct bgp_node *node) +{ + return bgp_node_prefix (node)->prefixlen; +} + +/* + * bgp_node_parent_nolock + * + * Gets the parent node of the given node without locking it. + */ +static inline struct bgp_node * +bgp_node_parent_nolock (struct bgp_node *node) +{ + return bgp_node_from_rnode (node->parent); +} + +/* + * bgp_unlock_node + */ +static inline void +bgp_unlock_node (struct bgp_node *node) +{ + route_unlock_node (bgp_node_to_rnode (node)); +} + +/* + * bgp_table_top_nolock + * + * Gets the top node in the table without locking it. + * + * @see bgp_table_top + */ +static inline struct bgp_node * +bgp_table_top_nolock (const struct bgp_table *const table) +{ + return bgp_node_from_rnode (table->route_table->top); +} + +/* + * bgp_table_top + */ +static inline struct bgp_node * +bgp_table_top (const struct bgp_table *const table) +{ + return bgp_node_from_rnode (route_top (table->route_table)); +} + +/* + * bgp_route_next + */ +static inline struct bgp_node * +bgp_route_next (struct bgp_node *node) +{ + return bgp_node_from_rnode (route_next (bgp_node_to_rnode (node))); +} + +/* + * bgp_route_next_until + */ +static inline struct bgp_node * +bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit) +{ + struct route_node *rnode; + + rnode = route_next_until (bgp_node_to_rnode (node), + bgp_node_to_rnode (limit)); + return bgp_node_from_rnode (rnode); +} + +/* + * bgp_node_get + */ +static inline struct bgp_node * +bgp_node_get (struct bgp_table *const table, struct prefix *p) +{ + return bgp_node_from_rnode (route_node_get (table->route_table, p)); +} + +/* + * bgp_node_lookup + */ +static inline struct bgp_node * +bgp_node_lookup (const struct bgp_table *const table, struct prefix *p) +{ + return bgp_node_from_rnode (route_node_lookup (table->route_table, p)); +} + +/* + * bgp_lock_node + */ +static inline struct bgp_node * +bgp_lock_node (struct bgp_node *node) +{ + return bgp_node_from_rnode (route_lock_node (bgp_node_to_rnode (node))); +} + +/* + * bgp_node_match + */ +static inline struct bgp_node * +bgp_node_match (const struct bgp_table *table, struct prefix *p) +{ + return bgp_node_from_rnode (route_node_match (table->route_table, p)); +} + +/* + * bgp_node_match_ipv4 + */ +static inline struct bgp_node * +bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr) +{ + return bgp_node_from_rnode (route_node_match_ipv4 (table->route_table, + addr)); +} + #ifdef HAVE_IPV6 -extern struct bgp_node *bgp_node_match_ipv6 (const struct bgp_table *, - struct in6_addr *); + +/* + * bgp_node_match_ipv6 + */ +static inline struct bgp_node * +bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr) +{ + return bgp_node_from_rnode (route_node_match_ipv6 (table->route_table, + addr)); +} + #endif /* HAVE_IPV6 */ -extern unsigned long bgp_table_count (const struct bgp_table *const); + +static inline unsigned long +bgp_table_count (const struct bgp_table *const table) +{ + return route_table_count (table->route_table); +} + #endif /* _QUAGGA_BGP_TABLE_H */ -- cgit v1.2.1