diff options
Diffstat (limited to 'bgpd/bgp_table.c')
| -rw-r--r-- | bgpd/bgp_table.c | 107 | 
1 files changed, 58 insertions, 49 deletions
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index cb658c0308..e01bf39113 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -47,16 +47,6 @@ void bgp_table_finish(struct bgp_table **rt)  }  /* - * bgp_dest_unlock_node - */ -void bgp_dest_unlock_node(struct bgp_dest *dest) -{ -	frrtrace(1, frr_bgp, bgp_dest_unlock, dest); -	bgp_delete_listnode(dest); -	route_unlock_node(bgp_dest_to_rnode(dest)); -} - -/*   * bgp_dest_lock_node   */  struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest) @@ -73,7 +63,7 @@ struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest)  const char *bgp_dest_get_prefix_str(struct bgp_dest *dest)  {  	const struct prefix *p = NULL; -	static char str[PREFIX_STRLEN] = {0}; +	static char str[PREFIX_STRLEN_EXTENDED] = {0};  	p = bgp_dest_get_prefix(dest);  	if (p) @@ -83,44 +73,62 @@ const char *bgp_dest_get_prefix_str(struct bgp_dest *dest)  }  /* - * bgp_node_create + * bgp_dest_unlock_node   */ -static struct route_node *bgp_node_create(route_table_delegate_t *delegate, -					  struct route_table *table) +inline struct bgp_dest *bgp_dest_unlock_node(struct bgp_dest *dest)  { -	struct bgp_node *node; -	node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node)); +	frrtrace(1, frr_bgp, bgp_dest_unlock, dest); +	bgp_delete_listnode(dest); +	struct route_node *rn = bgp_dest_to_rnode(dest); + +	if (rn->lock == 1) { +		struct bgp_table *rt = bgp_dest_table(dest); +		if (rt->bgp) { +			bgp_addpath_free_node_data(&rt->bgp->tx_addpath, +						   &dest->tx_addpath, rt->afi, +						   rt->safi); +		} +		XFREE(MTYPE_BGP_NODE, dest); +		dest = NULL; +		rn->info = NULL; +	} +	route_unlock_node(rn); -	RB_INIT(bgp_adj_out_rb, &node->adj_out); -	return bgp_dest_to_rnode(node); +	return dest;  }  /*   * bgp_node_destroy   */  static void bgp_node_destroy(route_table_delegate_t *delegate, -			     struct route_table *table, struct route_node *node) +							struct route_table *table, struct route_node *node)  { -	struct bgp_node *bgp_node; +	struct bgp_dest *dest;  	struct bgp_table *rt; -	bgp_node = bgp_dest_from_rnode(node); +	dest = bgp_dest_from_rnode(node);  	rt = table->info; - -	if (rt->bgp) { -		bgp_addpath_free_node_data(&rt->bgp->tx_addpath, -					 &bgp_node->tx_addpath, -					 rt->afi, rt->safi); +	if (dest) { +		if (rt->bgp) { +			bgp_addpath_free_node_data(&rt->bgp->tx_addpath, +										&dest->tx_addpath, +										rt->afi, rt->safi); +		} +		XFREE(MTYPE_BGP_NODE, dest); +		node->info = NULL;  	} -	XFREE(MTYPE_BGP_NODE, bgp_node); +	if (family2afi(node->p.family) == AFI_LINKSTATE) +		prefix_linkstate_ptr_free(&node->p); + +	XFREE(MTYPE_ROUTE_NODE, node);  }  /*   * 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}; +route_table_delegate_t bgp_table_delegate = { .create_node = route_node_create, +					      .destroy_node = bgp_node_destroy };  /*   * bgp_table_init @@ -151,9 +159,9 @@ struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi)  }  /* Delete the route node from the selection deferral route list */ -void bgp_delete_listnode(struct bgp_node *node) +void bgp_delete_listnode(struct bgp_dest *dest)  { -	struct route_node *rn = NULL; +	const struct route_node *rn = NULL;  	struct bgp_table *table = NULL;  	struct bgp *bgp = NULL;  	afi_t afi; @@ -162,8 +170,8 @@ void bgp_delete_listnode(struct bgp_node *node)  	/* If the route to be deleted is selection pending, update the  	 * route node in gr_info  	 */ -	if (CHECK_FLAG(node->flags, BGP_NODE_SELECT_DEFER)) { -		table = bgp_dest_table(node); +	if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { +		table = bgp_dest_table(dest);  		if (table) {  			bgp = table->bgp; @@ -172,47 +180,48 @@ void bgp_delete_listnode(struct bgp_node *node)  		} else  			return; -		rn = bgp_dest_to_rnode(node); +		rn = bgp_dest_to_rnode(dest);  		if (bgp && rn && rn->lock == 1) {  			/* Delete the route from the selection pending list */  			bgp->gr_info[afi][safi].gr_deferred--; -			UNSET_FLAG(node->flags, BGP_NODE_SELECT_DEFER); +			UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);  		}  	}  } -struct bgp_node *bgp_table_subtree_lookup(const struct bgp_table *table, +struct bgp_dest *bgp_table_subtree_lookup(const struct bgp_table *table,  					  const struct prefix *p)  { -	struct bgp_node *node = bgp_dest_from_rnode(table->route_table->top); -	struct bgp_node *matched = NULL; +	struct bgp_dest *dest = bgp_dest_from_rnode(table->route_table->top); +	struct bgp_dest *matched = NULL; -	if (node == NULL) +	if (dest == NULL)  		return NULL; -	while (node) { -		const struct prefix *node_p = bgp_dest_get_prefix(node); +	while (dest) { +		const struct prefix *dest_p = bgp_dest_get_prefix(dest); +		struct route_node *node = dest->rn; -		if (node_p->prefixlen >= p->prefixlen) { -			if (!prefix_match(p, node_p)) +		if (dest_p->prefixlen >= p->prefixlen) { +			if (!prefix_match(p, dest_p))  				return NULL; -			matched = node; +			matched = dest;  			break;  		} -		if (!prefix_match(node_p, p)) +		if (!prefix_match(dest_p, p))  			return NULL; -		if (node_p->prefixlen == p->prefixlen) { -			matched = node; +		if (dest_p->prefixlen == p->prefixlen) { +			matched = dest;  			break;  		} -		node = bgp_dest_from_rnode(node->link[prefix_bit( -			&p->u.prefix, node_p->prefixlen)]); +		dest = bgp_dest_from_rnode( +			node->link[prefix_bit(&p->u.prefix, dest_p->prefixlen)]);  	}  	if (!matched)  | 
