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,
int safi, u_char use_json,
json_object *json)
if (safi_wildcard)
safi = 1; /* SAFI_UNICAST */
while (safi < SAFI_MAX) {
- if (bgp_show_summary_afi_safi_peer_exists(bgp, afi,
- safi)) {
+ if (bgp_afi_safi_peer_exists(bgp, afi, safi)) {
json_output = true;
if (is_wildcard) {
/*
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
}
+static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
+ safi_t safi)
+{
+ struct bgp_node *rn, *nrn;
+
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info != NULL) {
+ /* Special handling for 2-level routing
+ * tables. */
+ if (safi == SAFI_MPLS_VPN
+ || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN) {
+ for (nrn = bgp_table_top((
+ struct bgp_table
+ *)(rn->info));
+ nrn;
+ nrn = bgp_route_next(nrn))
+ bgp_process(bgp, nrn,
+ afi, safi);
+ } else
+ bgp_process(bgp, rn, afi, safi);
+ }
+ }
+}
+
/* Force a bestpath recalculation for all prefixes. This is used
* when 'bgp bestpath' commands are entered.
*/
{
afi_t afi;
safi_t safi;
- 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;
- rn = bgp_route_next(rn)) {
- if (rn->info != NULL) {
- /* Special handling for 2-level routing
- * tables. */
- if (safi == SAFI_MPLS_VPN
- || safi == SAFI_ENCAP
- || safi == SAFI_EVPN) {
- for (nrn = bgp_table_top((
- struct bgp_table
- *)(rn->info));
- nrn;
- nrn = bgp_route_next(nrn))
- bgp_process(bgp, nrn,
- afi, safi);
- } else
- bgp_process(bgp, rn, afi, safi);
- }
- }
+ bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
}
}
}
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. */
void peer_as_change(struct peer *peer, as_t as, int as_specified)
{
struct peer_group *group;
struct listnode *node, *nnode;
struct peer *tmp_peer;
+ struct bgp *bgp;
/* Nothing to do if we've already activated this peer */
if (peer->afc[afi][safi])
return ret;
+ bgp = peer->bgp;
+
/* This is a peer-group so activate all of the members of the
* peer-group as well */
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
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;
}
struct peer_group *group;
struct peer *tmp_peer;
struct listnode *node, *nnode;
+ struct bgp *bgp;
/* Nothing to do if we've already de-activated this peer */
if (!peer->afc[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;
}
/* BGP redistribute configuration. */
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 */
struct thread *t_rmap_def_originate_eval;
#define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5
extern int bgp_update_delay_active(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 int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
int, afi_t, safi_t);