bgpd: Memory wasting in zebra by non used MPLS FECs

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
This commit is contained in:
Daniel Walton 2017-08-22 18:14:50 +00:00
parent 3f54388956
commit 318cac96ef
4 changed files with 85 additions and 44 deletions

View File

@ -2045,7 +2045,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
* to do this upon changes to best path except of the label index * to do this upon changes to best path except of the label index
* changes. * changes.
*/ */
if (safi == SAFI_UNICAST) { if (bgp->allocate_mpls_labels[afi][safi]) {
if (new_select) { if (new_select) {
if (!old_select if (!old_select
|| bgp_label_index_differs(new_select, old_select) || bgp_label_index_differs(new_select, old_select)
@ -2066,7 +2066,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
} else } else
bgp_register_for_label(rn, new_select); bgp_register_for_label(rn, new_select);
} }
} else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
bgp_unregister_for_label(rn);
}
} else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
bgp_unregister_for_label(rn); bgp_unregister_for_label(rn);
} }

View File

@ -7018,26 +7018,6 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
/*
* Return if we have a peer configured to use this afi/safi
*/
static int bgp_show_summary_afi_safi_peer_exists(struct bgp *bgp, int afi,
int safi)
{
struct listnode *node;
struct peer *peer;
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
if (peer->afc[afi][safi])
return 1;
}
return 0;
}
static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
int safi, u_char use_json, int safi, u_char use_json,
json_object *json) json_object *json)
@ -7056,8 +7036,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
if (safi_wildcard) if (safi_wildcard)
safi = 1; /* SAFI_UNICAST */ safi = 1; /* SAFI_UNICAST */
while (safi < SAFI_MAX) { while (safi < SAFI_MAX) {
if (bgp_show_summary_afi_safi_peer_exists(bgp, afi, if (bgp_afi_safi_peer_exists(bgp, afi, safi)) {
safi)) {
json_output = true; json_output = true;
if (is_wildcard) { if (is_wildcard) {
/* /*

View File

@ -1391,17 +1391,11 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer)
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
} }
/* Force a bestpath recalculation for all prefixes. This is used static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
* when 'bgp bestpath' commands are entered. safi_t safi)
*/
void bgp_recalculate_all_bestpaths(struct bgp *bgp)
{ {
afi_t afi;
safi_t safi;
struct bgp_node *rn, *nrn; struct bgp_node *rn, *nrn;
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
rn = bgp_route_next(rn)) { rn = bgp_route_next(rn)) {
if (rn->info != NULL) { if (rn->info != NULL) {
@ -1422,6 +1416,19 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
} }
} }
} }
/* Force a bestpath recalculation for all prefixes. This is used
* when 'bgp bestpath' commands are entered.
*/
void bgp_recalculate_all_bestpaths(struct bgp *bgp)
{
afi_t afi;
safi_t safi;
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
}
} }
} }
@ -1500,6 +1507,25 @@ struct peer *peer_create_accept(struct bgp *bgp)
return peer; return peer;
} }
/*
* Return true if we have a peer configured to use this afi/safi
*/
int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
{
struct listnode *node;
struct peer *peer;
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
if (peer->afc[afi][safi])
return 1;
}
return 0;
}
/* Change peer's AS number. */ /* Change peer's AS number. */
void peer_as_change(struct peer *peer, as_t as, int as_specified) void peer_as_change(struct peer *peer, as_t as, int as_specified)
{ {
@ -1714,11 +1740,14 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi)
struct peer_group *group; struct peer_group *group;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct peer *tmp_peer; struct peer *tmp_peer;
struct bgp *bgp;
/* Nothing to do if we've already activated this peer */ /* Nothing to do if we've already activated this peer */
if (peer->afc[afi][safi]) if (peer->afc[afi][safi])
return ret; return ret;
bgp = peer->bgp;
/* This is a peer-group so activate all of the members of the /* This is a peer-group so activate all of the members of the
* peer-group as well */ * peer-group as well */
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
@ -1741,6 +1770,17 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi)
ret |= non_peergroup_activate_af(peer, afi, safi); ret |= non_peergroup_activate_af(peer, afi, safi);
} }
/* If this is the first peer to be activated for this afi/labeled-unicast
* recalc bestpaths to trigger label allocation */
if (safi == SAFI_LABELED_UNICAST && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels");
bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 1;
bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
}
return ret; return ret;
} }
@ -1798,6 +1838,7 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
struct peer_group *group; struct peer_group *group;
struct peer *tmp_peer; struct peer *tmp_peer;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct bgp *bgp;
/* Nothing to do if we've already de-activated this peer */ /* Nothing to do if we've already de-activated this peer */
if (!peer->afc[afi][safi]) if (!peer->afc[afi][safi])
@ -1821,6 +1862,20 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
ret |= non_peergroup_deactivate_af(peer, afi, safi); ret |= non_peergroup_deactivate_af(peer, afi, safi);
} }
bgp = peer->bgp;
/* If this is the last peer to be deactivated for this afi/labeled-unicast
* recalc bestpaths to trigger label deallocation */
if (safi == SAFI_LABELED_UNICAST &&
bgp->allocate_mpls_labels[afi][SAFI_UNICAST] &&
!bgp_afi_safi_peer_exists(bgp, afi, safi)) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 0;
bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
}
return ret; return ret;
} }

View File

@ -333,6 +333,9 @@ struct bgp {
/* BGP redistribute configuration. */ /* BGP redistribute configuration. */
struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX]; struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX];
/* Allocate MPLS labels */
u_char allocate_mpls_labels[AFI_MAX][SAFI_MAX];
/* timer to re-evaluate neighbor default-originate route-maps */ /* timer to re-evaluate neighbor default-originate route-maps */
struct thread *t_rmap_def_originate_eval; struct thread *t_rmap_def_originate_eval;
#define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5 #define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5
@ -1280,6 +1283,7 @@ extern int bgp_listen_limit_unset(struct bgp *);
extern int bgp_update_delay_active(struct bgp *); extern int bgp_update_delay_active(struct bgp *);
extern int bgp_update_delay_configured(struct bgp *); extern int bgp_update_delay_configured(struct bgp *);
extern int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
extern void peer_as_change(struct peer *, as_t, int); extern void peer_as_change(struct peer *, as_t, int);
extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *, extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
int, afi_t, safi_t); int, afi_t, safi_t);