summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_route.c131
-rw-r--r--bgpd/bgp_vty.c23
-rw-r--r--bgpd/bgpd.c95
-rw-r--r--bgpd/bgpd.h4
4 files changed, 166 insertions, 87 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index beb1e2a2a0..288271e5a1 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2046,7 +2046,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
* changes.
*/
- if (safi == SAFI_UNICAST) {
+ if (bgp->allocate_mpls_labels[afi][safi]) {
if (new_select) {
if (!old_select
|| bgp_label_index_differs(new_select, old_select)
@@ -2067,8 +2067,11 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
} else
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);
}
/* If best route remains the same and this is not due to user-initiated
@@ -8020,7 +8023,8 @@ static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
const char *prefix, afi_t afi, safi_t safi,
enum bgp_show_type type);
-static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
+static int bgp_show_regexp(struct vty *vty, struct bgp *bgp,
+ const char *regstr, afi_t afi,
safi_t safi, enum bgp_show_type type);
static int bgp_show_community(struct vty *vty, struct bgp *bgp, int argc,
struct cmd_token **argv, int exact, afi_t afi,
@@ -8838,32 +8842,28 @@ DEFUN (show_ip_bgp_large_community,
static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi);
-/* BGP route print out function. */
+
+/* BGP route print out function without JSON */
DEFUN (show_ip_bgp,
show_ip_bgp_cmd,
"show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
- [<\
- cidr-only\
- |dampening <flap-statistics|dampened-paths|parameters>\
- |route-map WORD\
- |prefix-list WORD\
- |filter-list WORD\
- |statistics\
- |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
- |community-list <(1-500)|WORD> [exact-match]\
- |A.B.C.D/M longer-prefixes\
- |X:X::X:X/M longer-prefixes>\
- ] [json]",
+ <dampening <parameters>\
+ |route-map WORD\
+ |prefix-list WORD\
+ |filter-list WORD\
+ |statistics\
+ |community <AA:NN|local-AS|no-advertise|no-export> [exact-match]\
+ |community-list <(1-500)|WORD> [exact-match]\
+ |A.B.C.D/M longer-prefixes\
+ |X:X::X:X/M longer-prefixes\
+ >",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
- "Display only routes with non-natural netmasks\n"
"Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display paths suppressed due to dampening\n"
"Display detail of configured dampening parameters\n"
"Display routes matching the route-map\n"
"A route-map to match on\n"
@@ -8885,13 +8885,11 @@ DEFUN (show_ip_bgp,
"IPv4 prefix\n"
"Display route and more specific routes\n"
"IPv6 prefix\n"
- "Display route and more specific routes\n"
- JSON_STR)
+ "Display route and more specific routes\n")
{
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
int exact_match = 0;
- enum bgp_show_type sh_type = bgp_show_type_normal;
struct bgp *bgp = NULL;
int idx = 0;
@@ -8900,23 +8898,8 @@ DEFUN (show_ip_bgp,
if (!idx)
return CMD_WARNING;
- int uj = use_json(argc, argv);
- if (uj)
- argc--;
-
- if (argv_find(argv, argc, "cidr-only", &idx))
- return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
- NULL, uj);
-
if (argv_find(argv, argc, "dampening", &idx)) {
- if (argv_find(argv, argc, "dampened-paths", &idx))
- return bgp_show(vty, bgp, afi, safi,
- bgp_show_type_dampend_paths, NULL, uj);
- else if (argv_find(argv, argc, "flap-statistics", &idx))
- return bgp_show(vty, bgp, afi, safi,
- bgp_show_type_flap_statistics, NULL,
- uj);
- else if (argv_find(argv, argc, "parameters", &idx))
+ if (argv_find(argv, argc, "parameters", &idx))
return bgp_show_dampening_parameters(vty, afi, safi);
}
@@ -8945,10 +8928,6 @@ DEFUN (show_ip_bgp,
return bgp_show_community(vty, bgp, argc, argv,
exact_match, afi, safi);
}
- /* show all communities */
- else
- return bgp_show(vty, bgp, afi, safi,
- bgp_show_type_community_all, NULL, uj);
}
if (argv_find(argv, argc, "community-list", &idx)) {
@@ -8965,6 +8944,66 @@ DEFUN (show_ip_bgp,
safi,
bgp_show_type_prefix_longer);
+ return CMD_WARNING;
+}
+
+/* BGP route print out function with JSON */
+DEFUN (show_ip_bgp_json,
+ show_ip_bgp_json_cmd,
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
+ [<\
+ cidr-only\
+ |dampening <flap-statistics|dampened-paths>\
+ |community \
+ >] [json]",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_WITH_LABEL_HELP_STR
+ "Display only routes with non-natural netmasks\n"
+ "Display detailed information about dampening\n"
+ "Display flap statistics of routes\n"
+ "Display paths suppressed due to dampening\n"
+ "Display routes matching the communities\n"
+ JSON_STR)
+{
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ enum bgp_show_type sh_type = bgp_show_type_normal;
+ struct bgp *bgp = NULL;
+ int idx = 0;
+
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
+
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
+
+ if (argv_find(argv, argc, "cidr-only", &idx))
+ return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
+ NULL, uj);
+
+ if (argv_find(argv, argc, "dampening", &idx)) {
+ if (argv_find(argv, argc, "dampened-paths", &idx))
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_dampend_paths, NULL, uj);
+ else if (argv_find(argv, argc, "flap-statistics", &idx))
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_flap_statistics, NULL,
+ uj);
+ }
+
+ if (argv_find(argv, argc, "community", &idx)) {
+ /* show all communities */
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_community_all, NULL, uj);
+ }
+
if (safi == SAFI_MPLS_VPN)
return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
NULL, 0, uj);
@@ -9074,7 +9113,7 @@ DEFUN (show_ip_bgp_regexp,
idx++;
char *regstr = argv_concat(argv, argc, idx);
- int rc = bgp_show_regexp(vty, (const char *)regstr, afi, safi,
+ int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
bgp_show_type_regexp);
XFREE(MTYPE_TMP, regstr);
return rc;
@@ -9109,7 +9148,8 @@ DEFUN (show_ip_bgp_instance_all,
return CMD_SUCCESS;
}
-static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
+static int bgp_show_regexp(struct vty *vty, struct bgp *bgp,
+ const char *regstr, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
regex_t *regex;
@@ -9121,7 +9161,7 @@ static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
return CMD_WARNING;
}
- rc = bgp_show(vty, NULL, afi, safi, type, regex, 0);
+ rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
bgp_regex_free(regex);
return rc;
}
@@ -11279,6 +11319,7 @@ void bgp_route_init(void)
/* IPv4 labeled-unicast configuration. */
install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
install_element(VIEW_NODE, &show_ip_bgp_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 2e18a6d44f..f040ed9a08 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7018,26 +7018,6 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
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)
@@ -7056,8 +7036,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
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) {
/*
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index e3650417fa..92121f6aef 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1391,6 +1391,32 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer)
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.
*/
@@ -1398,29 +1424,10 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
{
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);
}
}
}
@@ -1500,6 +1507,25 @@ struct peer *peer_create_accept(struct bgp *bgp)
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)
{
@@ -1714,11 +1740,14 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi)
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)) {
@@ -1741,6 +1770,17 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t 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;
}
@@ -1798,6 +1838,7 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
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])
@@ -1821,6 +1862,20 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t 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;
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index f6e7b2277f..5ede9ba13d 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -333,6 +333,9 @@ struct bgp {
/* 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
@@ -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_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);