summaryrefslogtreecommitdiff
path: root/bgpd/bgp_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_vty.c')
-rw-r--r--bgpd/bgp_vty.c890
1 files changed, 545 insertions, 345 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index b77c4b2297..f8ef5e2aa2 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -119,10 +119,15 @@ FRR_CFG_DEFAULT_BOOL(BGP_EBGP_REQUIRES_POLICY,
{ .val_bool = false, .match_version = "< 7.4", },
{ .val_bool = true },
)
+FRR_CFG_DEFAULT_BOOL(BGP_SUPPRESS_DUPLICATES,
+ { .val_bool = false, .match_version = "< 7.6", },
+ { .val_bool = true },
+)
DEFINE_HOOK(bgp_inst_config_write,
(struct bgp *bgp, struct vty *vty),
(bgp, vty))
+DEFINE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp))
#define GR_NO_OPER \
"The Graceful Restart No Operation was executed as cmd same as previous one."
@@ -209,34 +214,38 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
static const char *get_afi_safi_vty_str(afi_t afi, safi_t safi)
{
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- return "IPv4 Unicast";
- else if (afi == AFI_IP && safi == SAFI_MULTICAST)
- return "IPv4 Multicast";
- else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
- return "IPv4 Labeled Unicast";
- else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
- return "IPv4 VPN";
- else if (afi == AFI_IP && safi == SAFI_ENCAP)
- return "IPv4 Encap";
- else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
- return "IPv4 Flowspec";
- else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
- return "IPv6 Unicast";
- else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
- return "IPv6 Multicast";
- else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
- return "IPv6 Labeled Unicast";
- else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
- return "IPv6 VPN";
- else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
- return "IPv6 Encap";
- else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
- return "IPv6 Flowspec";
- else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
- return "L2VPN EVPN";
- else
- return "Unknown";
+ if (afi == AFI_IP) {
+ if (safi == SAFI_UNICAST)
+ return "IPv4 Unicast";
+ if (safi == SAFI_MULTICAST)
+ return "IPv4 Multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "IPv4 Labeled Unicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "IPv4 VPN";
+ if (safi == SAFI_ENCAP)
+ return "IPv4 Encap";
+ if (safi == SAFI_FLOWSPEC)
+ return "IPv4 Flowspec";
+ } else if (afi == AFI_IP6) {
+ if (safi == SAFI_UNICAST)
+ return "IPv6 Unicast";
+ if (safi == SAFI_MULTICAST)
+ return "IPv6 Multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "IPv6 Labeled Unicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "IPv6 VPN";
+ if (safi == SAFI_ENCAP)
+ return "IPv6 Encap";
+ if (safi == SAFI_FLOWSPEC)
+ return "IPv6 Flowspec";
+ } else if (afi == AFI_L2VPN) {
+ if (safi == SAFI_EVPN)
+ return "L2VPN EVPN";
+ }
+
+ return "Unknown";
}
/*
@@ -247,34 +256,38 @@ static const char *get_afi_safi_vty_str(afi_t afi, safi_t safi)
*/
static const char *get_afi_safi_json_str(afi_t afi, safi_t safi)
{
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- return "ipv4Unicast";
- else if (afi == AFI_IP && safi == SAFI_MULTICAST)
- return "ipv4Multicast";
- else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
- return "ipv4LabeledUnicast";
- else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
- return "ipv4Vpn";
- else if (afi == AFI_IP && safi == SAFI_ENCAP)
- return "ipv4Encap";
- else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
- return "ipv4Flowspec";
- else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
- return "ipv6Unicast";
- else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
- return "ipv6Multicast";
- else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
- return "ipv6LabeledUnicast";
- else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
- return "ipv6Vpn";
- else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
- return "ipv6Encap";
- else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
- return "ipv6Flowspec";
- else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
- return "l2VpnEvpn";
- else
- return "Unknown";
+ if (afi == AFI_IP) {
+ if (safi == SAFI_UNICAST)
+ return "ipv4Unicast";
+ if (safi == SAFI_MULTICAST)
+ return "ipv4Multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "ipv4LabeledUnicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "ipv4Vpn";
+ if (safi == SAFI_ENCAP)
+ return "ipv4Encap";
+ if (safi == SAFI_FLOWSPEC)
+ return "ipv4Flowspec";
+ } else if (afi == AFI_IP6) {
+ if (safi == SAFI_UNICAST)
+ return "ipv6Unicast";
+ if (safi == SAFI_MULTICAST)
+ return "ipv6Multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "ipv6LabeledUnicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "ipv6Vpn";
+ if (safi == SAFI_ENCAP)
+ return "ipv6Encap";
+ if (safi == SAFI_FLOWSPEC)
+ return "ipv6Flowspec";
+ } else if (afi == AFI_L2VPN) {
+ if (safi == SAFI_EVPN)
+ return "l2VpnEvpn";
+ }
+
+ return "Unknown";
}
/* return string maps to afi-safi specific container names
@@ -282,30 +295,34 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi)
*/
const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi)
{
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- return "ipv4-unicast";
- else if (afi == AFI_IP && safi == SAFI_MULTICAST)
- return "ipv4-multicast";
- else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
- return "ipv4-labeled-unicast";
- else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
- return "l3vpn-ipv4-unicast";
- else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
- return "ipv4-flowspec";
- else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
- return "ipv6-unicast";
- else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
- return "ipv6-multicast";
- else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
- return "ipv6-labeled-unicast";
- else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
- return "l3vpn-ipv6-unicast";
- else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
- return "ipv6-flowspec";
- else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
- return "l2vpn-evpn";
- else
- return "Unknown";
+ if (afi == AFI_IP) {
+ if (safi == SAFI_UNICAST)
+ return "ipv4-unicast";
+ if (safi == SAFI_MULTICAST)
+ return "ipv4-multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "ipv4-labeled-unicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "l3vpn-ipv4-unicast";
+ if (safi == SAFI_FLOWSPEC)
+ return "ipv4-flowspec";
+ } else if (afi == AFI_IP6) {
+ if (safi == SAFI_UNICAST)
+ return "ipv6-unicast";
+ if (safi == SAFI_MULTICAST)
+ return "ipv6-multicast";
+ if (safi == SAFI_LABELED_UNICAST)
+ return "ipv6-labeled-unicast";
+ if (safi == SAFI_MPLS_VPN)
+ return "l3vpn-ipv6-unicast";
+ if (safi == SAFI_FLOWSPEC)
+ return "ipv6-flowspec";
+ } else if (afi == AFI_L2VPN) {
+ if (safi == SAFI_EVPN)
+ return "l2vpn-evpn";
+ }
+
+ return "Unknown";
}
/* Utility function to get address family from current node. */
@@ -475,6 +492,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
SET_FLAG((*bgp)->flags, BGP_FLAG_DETERMINISTIC_MED);
if (DFLT_BGP_EBGP_REQUIRES_POLICY)
SET_FLAG((*bgp)->flags, BGP_FLAG_EBGP_REQUIRES_POLICY);
+ if (DFLT_BGP_SUPPRESS_DUPLICATES)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_SUPPRESS_DUPLICATES);
ret = BGP_SUCCESS;
}
@@ -864,6 +883,7 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
struct listnode **nnode, enum bgp_clear_type stype)
{
int ret = 0;
+ struct peer_af *paf;
/* if afi/.safi not specified, spin thru all of them */
if ((afi == AFI_UNSPEC) && (safi == SAFI_UNSPEC)) {
@@ -871,6 +891,11 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
safi_t tmp_safi;
FOREACH_AFI_SAFI (tmp_afi, tmp_safi) {
+ paf = peer_af_find(peer, tmp_afi, tmp_safi);
+ if (paf && paf->subgroup)
+ SET_FLAG(paf->subgroup->sflags,
+ SUBGRP_STATUS_FORCE_UPDATES);
+
if (!peer->afc[tmp_afi][tmp_safi])
continue;
@@ -889,6 +914,11 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
if (!peer->afc[afi][tmp_safi])
continue;
+ paf = peer_af_find(peer, afi, tmp_safi);
+ if (paf && paf->subgroup)
+ SET_FLAG(paf->subgroup->sflags,
+ SUBGRP_STATUS_FORCE_UPDATES);
+
if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, nnode);
else
@@ -900,6 +930,11 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
if (!peer->afc[afi][safi])
return 1;
+ paf = peer_af_find(peer, afi, safi);
+ if (paf && paf->subgroup)
+ SET_FLAG(paf->subgroup->sflags,
+ SUBGRP_STATUS_FORCE_UPDATES);
+
if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, nnode);
else
@@ -2543,6 +2578,37 @@ DEFUN_YANG(no_bgp_always_compare_med,
return nb_cli_apply_changes(vty, NULL);
}
+DEFUN_YANG(bgp_suppress_duplicates,
+ bgp_suppress_duplicates_cmd,
+ "bgp suppress-duplicates",
+ "BGP specific commands\n"
+ "Suppress duplicate updates if the route actually not changed\n")
+{
+ nb_cli_enqueue_change(vty, "./global/suppress-duplicates",
+ NB_OP_MODIFY, "true");
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG(no_bgp_suppress_duplicates,
+ no_bgp_suppress_duplicates_cmd,
+ "no bgp suppress-duplicates",
+ NO_STR
+ "BGP specific commands\n"
+ "Suppress duplicate updates if the route actually not changed\n")
+{
+ nb_cli_enqueue_change(vty, "./global/suppress-duplicates",
+ NB_OP_MODIFY, "false");
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_suppress_duplicates(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SUPPRESS_DUPLICATES)
+ vty_out(vty, " bgp suppress-duplicates\n");
+}
+
DEFUN_YANG(bgp_ebgp_requires_policy,
bgp_ebgp_requires_policy_cmd,
"bgp ebgp-requires-policy",
@@ -4887,27 +4953,63 @@ ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Enable the Address Family for this Neighbor\n")
-DEFUN_YANG (neighbor_set_peer_group,
- neighbor_set_peer_group_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Member of the peer-group\n"
- "Peer-group name\n")
+DEFUN (neighbor_set_peer_group,
+ neighbor_set_peer_group_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_peer = 1;
int idx_word = 3;
- char base_xpath[XPATH_MAXLEN];
+ int ret;
+ as_t as;
+ union sockunion su;
+ struct peer *peer;
+ struct peer_group *group;
- if (peer_and_group_lookup_nb(vty, argv[idx_peer]->arg, base_xpath,
- sizeof(base_xpath), NULL)
- < 0)
+ ret = str2sockunion(argv[idx_peer]->arg, &su);
+ if (ret < 0) {
+ peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
+ if (!peer) {
+ vty_out(vty, "%% Malformed address or name: %s\n",
+ argv[idx_peer]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ if (peer_address_self_check(bgp, &su)) {
+ vty_out(vty,
+ "%% Can not configure the local system as neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Disallow for dynamic neighbor. */
+ peer = peer_lookup(bgp, &su);
+ if (peer && peer_dynamic_neighbor(peer)) {
+ vty_out(vty,
+ "%% Operation not allowed on a dynamic neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ group = peer_group_lookup(bgp, argv[idx_word]->arg);
+ if (!group) {
+ vty_out(vty, "%% Configure the peer-group first\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- nb_cli_enqueue_change(vty, "./peer-group", NB_OP_MODIFY,
- argv[idx_word]->arg);
+ ret = peer_group_bind(bgp, &su, peer, group, &as);
- return nb_cli_apply_changes(vty, base_xpath);
+ if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
+ vty_out(vty,
+ "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
+ as);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return bgp_vty_return(vty, ret);
}
ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
@@ -4918,7 +5020,7 @@ ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
DEFUN_YANG (no_neighbor_set_peer_group,
no_neighbor_set_peer_group_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group [PGNAME]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -4939,7 +5041,7 @@ DEFUN_YANG (no_neighbor_set_peer_group,
}
ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group [PGNAME]",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Member of the peer-group\n"
"Peer-group name\n")
@@ -5463,7 +5565,6 @@ DEFUN_YANG (neighbor_nexthop_self,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5502,7 +5603,6 @@ DEFUN_YANG(neighbor_nexthop_self_force,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5587,7 +5687,6 @@ DEFUN_YANG (no_neighbor_nexthop_self_force,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5745,7 +5844,6 @@ DEFUN_YANG (neighbor_remove_private_as_all,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5785,7 +5883,6 @@ DEFUN_YANG (neighbor_remove_private_as_replace_as,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5826,7 +5923,6 @@ DEFUN_YANG (neighbor_remove_private_as_all_replace_as,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5907,7 +6003,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_all,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5948,7 +6043,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_replace_as,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -5990,7 +6084,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_all_replace_as,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -6280,7 +6373,6 @@ DEFUN_YANG (neighbor_soft_reconfiguration,
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
-
snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
yang_afi_safi_value2identity(afi, safi));
@@ -7667,69 +7759,44 @@ ALIAS_HIDDEN(
"Filter outgoing updates\n")
/* Set prefix list to the peer. */
-static int peer_prefix_list_set_vty(struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi,
- const char *name_str,
- const char *direct_str)
-{
- int ret;
- int direct = FILTER_IN;
- struct peer *peer;
-
- peer = peer_and_group_lookup_vty(vty, ip_str);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
-
- /* Check filter direction. */
- if (strncmp(direct_str, "i", 1) == 0)
- direct = FILTER_IN;
- else if (strncmp(direct_str, "o", 1) == 0)
- direct = FILTER_OUT;
-
- ret = peer_prefix_list_set(peer, afi, safi, direct, name_str);
-
- return bgp_vty_return(vty, ret);
-}
-
-static int peer_prefix_list_unset_vty(struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi,
- const char *direct_str)
+DEFPY_YANG(
+ neighbor_prefix_list, neighbor_prefix_list_cmd,
+ "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor_str prefix-list WORD$prefix_str <in|out>$direction",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Filter updates to/from this neighbor\n"
+ "Name of a prefix list\n"
+ "Filter incoming updates\n"
+ "Filter outgoing updates\n")
{
- int ret;
- struct peer *peer;
- int direct = FILTER_IN;
+ char base_xpath[XPATH_MAXLEN];
+ char af_xpath[XPATH_MAXLEN];
+ char plist_xpath[XPATH_MAXLEN];
+ afi_t afi = bgp_node_afi(vty);
+ safi_t safi = bgp_node_safi(vty);
- peer = peer_and_group_lookup_vty(vty, ip_str);
- if (!peer)
+ snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
+ yang_afi_safi_value2identity(afi, safi));
+ if (peer_and_group_lookup_nb(vty, neighbor_str, base_xpath,
+ sizeof(base_xpath), af_xpath)
+ < 0)
return CMD_WARNING_CONFIG_FAILED;
- /* Check filter direction. */
- if (strncmp(direct_str, "i", 1) == 0)
- direct = FILTER_IN;
- else if (strncmp(direct_str, "o", 1) == 0)
- direct = FILTER_OUT;
-
- ret = peer_prefix_list_unset(peer, afi, safi, direct);
+ if (strmatch(direction, "in"))
+ snprintf(plist_xpath, sizeof(plist_xpath),
+ "./%s/filter-config/plist-import",
+ bgp_afi_safi_get_container_str(afi, safi));
+ else if (strmatch(direction, "out"))
+ snprintf(plist_xpath, sizeof(plist_xpath),
+ "./%s/filter-config/plist-export",
+ bgp_afi_safi_get_container_str(afi, safi));
- return bgp_vty_return(vty, ret);
-}
+ if (!no)
+ nb_cli_enqueue_change(vty, plist_xpath, NB_OP_MODIFY,
+ prefix_str);
+ else
+ nb_cli_enqueue_change(vty, plist_xpath, NB_OP_DESTROY, NULL);
-DEFUN (neighbor_prefix_list,
- neighbor_prefix_list_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Filter updates to/from this neighbor\n"
- "Name of a prefix list\n"
- "Filter incoming updates\n"
- "Filter outgoing updates\n")
-{
- int idx_peer = 1;
- int idx_word = 3;
- int idx_in_out = 4;
- return peer_prefix_list_set_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
- argv[idx_word]->arg, argv[idx_in_out]->arg);
+ return nb_cli_apply_changes(vty, base_xpath);
}
ALIAS_HIDDEN(neighbor_prefix_list, neighbor_prefix_list_hidden_cmd,
@@ -7740,32 +7807,6 @@ ALIAS_HIDDEN(neighbor_prefix_list, neighbor_prefix_list_hidden_cmd,
"Filter incoming updates\n"
"Filter outgoing updates\n")
-DEFUN (no_neighbor_prefix_list,
- no_neighbor_prefix_list_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Filter updates to/from this neighbor\n"
- "Name of a prefix list\n"
- "Filter incoming updates\n"
- "Filter outgoing updates\n")
-{
- int idx_peer = 2;
- int idx_in_out = 5;
- return peer_prefix_list_unset_vty(vty, argv[idx_peer]->arg,
- bgp_node_afi(vty), bgp_node_safi(vty),
- argv[idx_in_out]->arg);
-}
-
-ALIAS_HIDDEN(no_neighbor_prefix_list, no_neighbor_prefix_list_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
- NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Filter updates to/from this neighbor\n"
- "Name of a prefix list\n"
- "Filter incoming updates\n"
- "Filter outgoing updates\n")
-
static int peer_aslist_set_vty(struct vty *vty, const char *ip_str, afi_t afi,
safi_t safi, const char *name_str,
const char *direct_str)
@@ -7926,106 +7967,54 @@ ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd,
"Name of the exist or non exist map\n")
/* Set route-map to the peer. */
-static int peer_route_map_set_vty(struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi, const char *name_str,
- const char *direct_str)
-{
- int ret;
- struct peer *peer;
- int direct = RMAP_IN;
- struct route_map *route_map;
-
- peer = peer_and_group_lookup_vty(vty, ip_str);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
-
- /* Check filter direction. */
- if (strncmp(direct_str, "in", 2) == 0)
- direct = RMAP_IN;
- else if (strncmp(direct_str, "o", 1) == 0)
- direct = RMAP_OUT;
-
- route_map = route_map_lookup_warn_noexist(vty, name_str);
- ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map);
-
- return bgp_vty_return(vty, ret);
-}
-
-static int peer_route_map_unset_vty(struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi,
- const char *direct_str)
+DEFPY_YANG(
+ neighbor_route_map, neighbor_route_map_cmd,
+ "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor_str route-map WORD$rmap_str <in|out>$direction",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Apply route map to neighbor\n"
+ "Name of route map\n"
+ "Apply map to incoming routes\n"
+ "Apply map to outbound routes\n")
{
- int ret;
- struct peer *peer;
- int direct = RMAP_IN;
+ char base_xpath[XPATH_MAXLEN];
+ char af_xpath[XPATH_MAXLEN];
+ char rmap_xpath[XPATH_MAXLEN];
+ afi_t afi = bgp_node_afi(vty);
+ safi_t safi = bgp_node_safi(vty);
- peer = peer_and_group_lookup_vty(vty, ip_str);
- if (!peer)
+ snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH,
+ yang_afi_safi_value2identity(afi, safi));
+ if (peer_and_group_lookup_nb(vty, neighbor_str, base_xpath,
+ sizeof(base_xpath), af_xpath)
+ < 0)
return CMD_WARNING_CONFIG_FAILED;
- /* Check filter direction. */
- if (strncmp(direct_str, "in", 2) == 0)
- direct = RMAP_IN;
- else if (strncmp(direct_str, "o", 1) == 0)
- direct = RMAP_OUT;
-
- ret = peer_route_map_unset(peer, afi, safi, direct);
-
- return bgp_vty_return(vty, ret);
-}
+ if (strmatch(direction, "in"))
+ snprintf(rmap_xpath, sizeof(rmap_xpath),
+ "./%s/filter-config/rmap-import",
+ bgp_afi_safi_get_container_str(afi, safi));
+ else if (strmatch(direction, "out"))
+ snprintf(rmap_xpath, sizeof(rmap_xpath),
+ "./%s/filter-config/rmap-export",
+ bgp_afi_safi_get_container_str(afi, safi));
-DEFUN (neighbor_route_map,
- neighbor_route_map_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Apply route map to neighbor\n"
- "Name of route map\n"
- "Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
-{
- int idx_peer = 1;
- int idx_word = 3;
- int idx_in_out = 4;
- return peer_route_map_set_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
- argv[idx_word]->arg, argv[idx_in_out]->arg);
-}
+ if (!no) {
+ if (!yang_dnode_exists(
+ vty->candidate_config->dnode,
+ "/frr-route-map:lib/route-map[name='%s']",
+ rmap_str)) {
+ if (vty_shell_serv(vty))
+ vty_out(vty,
+ "The route-map '%s' does not exist.\n",
+ rmap_str);
+ }
+ nb_cli_enqueue_change(vty, rmap_xpath, NB_OP_MODIFY, rmap_str);
+ } else
+ nb_cli_enqueue_change(vty, rmap_xpath, NB_OP_DESTROY, NULL);
-ALIAS_HIDDEN(neighbor_route_map, neighbor_route_map_hidden_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
- NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Apply route map to neighbor\n"
- "Name of route map\n"
- "Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
-
-DEFUN (no_neighbor_route_map,
- no_neighbor_route_map_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Apply route map to neighbor\n"
- "Name of route map\n"
- "Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
-{
- int idx_peer = 2;
- int idx_in_out = 5;
- return peer_route_map_unset_vty(vty, argv[idx_peer]->arg,
- bgp_node_afi(vty), bgp_node_safi(vty),
- argv[idx_in_out]->arg);
+ return nb_cli_apply_changes(vty, base_xpath);
}
-ALIAS_HIDDEN(no_neighbor_route_map, no_neighbor_route_map_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
- NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Apply route map to neighbor\n"
- "Name of route map\n"
- "Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
-
/* Set unsuppress-map to the peer. */
static int peer_unsuppress_map_set_vty(struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
@@ -8831,6 +8820,93 @@ DEFPY(
return CMD_SUCCESS;
}
+DEFPY(neighbor_damp,
+ neighbor_damp_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [(1-45)$half [(1-20000)$reuse (1-20000)$suppress (1-255)$max]]",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enable neighbor route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
+{
+ struct peer *peer = peer_and_group_lookup_vty(vty, neighbor);
+
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+ if (!half)
+ half = DEFAULT_HALF_LIFE;
+ if (!reuse) {
+ reuse = DEFAULT_REUSE;
+ suppress = DEFAULT_SUPPRESS;
+ max = half * 4;
+ }
+ if (suppress < reuse) {
+ vty_out(vty,
+ "Suppress value cannot be less than reuse value\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ bgp_peer_damp_enable(peer, bgp_node_afi(vty), bgp_node_safi(vty),
+ half * 60, reuse, suppress, max * 60);
+ return CMD_SUCCESS;
+}
+
+DEFPY(no_neighbor_damp,
+ no_neighbor_damp_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [HALF [REUSE SUPPRESS MAX]]",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enable neighbor route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
+{
+ struct peer *peer = peer_and_group_lookup_vty(vty, neighbor);
+
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+ bgp_peer_damp_disable(peer, bgp_node_afi(vty), bgp_node_safi(vty));
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ip_bgp_neighbor_damp_param,
+ show_ip_bgp_neighbor_damp_param_cmd,
+ "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD>$neighbor dampening parameters [json]$json",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ BGP_AFI_HELP_STR
+ "Address Family modifier\n"
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Neighbor route-flap dampening information\n"
+ "Display detail of configured dampening parameters\n"
+ JSON_STR)
+{
+ bool use_json = false;
+ int idx = 0;
+ afi_t afi = AFI_IP;
+ safi_t safi = SAFI_UNICAST;
+ struct peer *peer;
+
+ if (argv_find(argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ if (argv_find(argv, argc, "ipv4", &idx))
+ afi = AFI_IP;
+ if (argv_find(argv, argc, "ipv6", &idx))
+ afi = AFI_IP6;
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (!peer)
+ return CMD_WARNING;
+ if (json)
+ use_json = true;
+ bgp_show_peer_dampening_parameters(vty, peer, afi, safi, use_json);
+ return CMD_SUCCESS;
+}
+
static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
struct ecommunity **list, bool is_rt6)
{
@@ -9066,6 +9142,7 @@ DEFPY (af_label_vpn_export,
vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
bgp_get_default(), bgp);
+ hook_call(bgp_snmp_update_last_changed, bgp);
return CMD_SUCCESS;
}
@@ -10499,11 +10576,29 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
}
}
+/* If the peer's description includes whitespaces
+ * then return the first occurrence. Also strip description
+ * to the given size if needed.
+ */
+static char *bgp_peer_description_stripped(char *desc, uint32_t size)
+{
+ static char stripped[BUFSIZ];
+ char *pnt;
+ uint32_t len = size > strlen(desc) ? strlen(desc) : size;
+
+ pnt = strchr(desc, ' ');
+ if (pnt)
+ len = size > (uint32_t)(pnt - desc) ? (uint32_t)(pnt - desc)
+ : size;
+
+ strlcpy(stripped, desc, len + 1);
+
+ return stripped;
+}
/* Show BGP peer's summary information. */
static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
- bool show_failed, bool show_established,
- bool use_json)
+ uint8_t show_flags)
{
struct peer *peer;
struct listnode *node, *nnode;
@@ -10519,6 +10614,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json_object *json_peers = NULL;
struct peer_af *paf;
struct bgp_filter *filter;
+ bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
+ bool show_failed = CHECK_FLAG(show_flags, BGP_SHOW_OPT_FAILED);
+ bool show_established =
+ CHECK_FLAG(show_flags, BGP_SHOW_OPT_ESTABLISHED);
+ bool show_wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
/* labeled-unicast routes are installed in the unicast table so in order
* to
@@ -10815,10 +10915,13 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out(vty, "%*s", max_neighbor_width - 8,
" ");
if (show_failed)
- vty_out(vty, "EstdCnt DropCnt ResetTime Reason\n");
+ vty_out(vty,
+ BGP_SHOW_SUMMARY_HEADER_FAILED);
else
vty_out(vty,
- "V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc\n");
+ show_wide
+ ? BGP_SHOW_SUMMARY_HEADER_ALL_WIDE
+ : BGP_SHOW_SUMMARY_HEADER_ALL);
}
}
@@ -10858,6 +10961,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
peer->domainname);
json_object_int_add(json_peer, "remoteAs", peer->as);
+ json_object_int_add(
+ json_peer, "localAs",
+ peer->change_local_as
+ ? peer->change_local_as
+ : peer->local_as);
json_object_int_add(json_peer, "version", 4);
json_object_int_add(json_peer, "msgRcvd",
PEER_TOTAL_RX(peer));
@@ -11014,14 +11122,33 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
&peer->ibuf->count,
memory_order_relaxed);
- vty_out(vty,
- "4 %10u %9u %9u %8" PRIu64" %4zu %4zu %8s",
- peer->as, PEER_TOTAL_RX(peer),
- PEER_TOTAL_TX(peer),
- peer->version[afi][safi], inq_count,
- outq_count,
- peer_uptime(peer->uptime, timebuf,
- BGP_UPTIME_LEN, 0, NULL));
+ if (show_wide)
+ vty_out(vty,
+ "4 %10u %10u %9u %9u %8" PRIu64
+ " %4zu %4zu %8s",
+ peer->as,
+ peer->change_local_as
+ ? peer->change_local_as
+ : peer->local_as,
+ PEER_TOTAL_RX(peer),
+ PEER_TOTAL_TX(peer),
+ peer->version[afi][safi],
+ inq_count, outq_count,
+ peer_uptime(peer->uptime,
+ timebuf,
+ BGP_UPTIME_LEN, 0,
+ NULL));
+ else
+ vty_out(vty, "4 %10u %9u %9u %8" PRIu64
+ " %4zu %4zu %8s",
+ peer->as, PEER_TOTAL_RX(peer),
+ PEER_TOTAL_TX(peer),
+ peer->version[afi][safi],
+ inq_count, outq_count,
+ peer_uptime(peer->uptime,
+ timebuf,
+ BGP_UPTIME_LEN, 0,
+ NULL));
if (peer->status == Established) {
if (peer->afc_recv[afi][safi]) {
@@ -11039,7 +11166,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
[afi]
[pfx_rcd_safi]);
} else {
- vty_out(vty, " NoNeg");
+ vty_out(vty, " NoNeg");
}
if (paf && PAF_SUBGRP(paf)) {
@@ -11056,6 +11183,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
(PAF_SUBGRP(
paf))
->scount);
+ } else {
+ vty_out(vty, " NoNeg");
}
} else {
if (CHECK_FLAG(peer->flags,
@@ -11075,7 +11204,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out(vty, " %8u", 0);
}
if (peer->desc)
- vty_out(vty, " %s", peer->desc);
+ vty_out(vty, " %s",
+ bgp_peer_description_stripped(
+ peer->desc,
+ show_wide ? 64 : 20));
else
vty_out(vty, " N/A");
vty_out(vty, "\n");
@@ -11115,14 +11247,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
}
static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
- int safi, bool show_failed,
- bool show_established, bool use_json)
+ int safi, uint8_t show_flags)
{
int is_first = 1;
int afi_wildcard = (afi == AFI_MAX);
int safi_wildcard = (safi == SAFI_MAX);
int is_wildcard = (afi_wildcard || safi_wildcard);
bool nbr_output = false;
+ bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
if (use_json && is_wildcard)
vty_out(vty, "{\n");
@@ -11160,8 +11292,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
}
}
bgp_show_summary(vty, bgp, afi, safi,
- show_failed, show_established,
- use_json);
+ show_flags);
}
safi++;
if (!safi_wildcard)
@@ -11183,14 +11314,13 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
}
static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
- safi_t safi, bool show_failed,
- bool show_established,
- bool use_json)
+ safi_t safi, uint8_t show_flags)
{
struct listnode *node, *nnode;
struct bgp *bgp;
int is_first = 1;
bool nbr_output = false;
+ bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
if (use_json)
vty_out(vty, "{\n");
@@ -11213,8 +11343,7 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
? VRF_DEFAULT_NAME
: bgp->name);
}
- bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
- show_established, use_json);
+ bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_flags);
}
if (use_json)
@@ -11224,16 +11353,15 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
}
int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
- safi_t safi, bool show_failed, bool show_established,
- bool use_json)
+ safi_t safi, uint8_t show_flags)
{
struct bgp *bgp;
+ bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
if (name) {
if (strmatch(name, "all")) {
- bgp_show_all_instances_summary_vty(
- vty, afi, safi, show_failed, show_established,
- use_json);
+ bgp_show_all_instances_summary_vty(vty, afi, safi,
+ show_flags);
return CMD_SUCCESS;
} else {
bgp = bgp_lookup_by_name(name);
@@ -11248,8 +11376,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
}
bgp_show_summary_afi_safi(vty, bgp, afi, safi,
- show_failed, show_established,
- use_json);
+ show_flags);
return CMD_SUCCESS;
}
}
@@ -11257,8 +11384,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
bgp = bgp_get_default();
if (bgp)
- bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
- show_established, use_json);
+ bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_flags);
else {
if (use_json)
vty_out(vty, "{}\n");
@@ -11273,7 +11399,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
/* `show [ip] bgp summary' commands. */
DEFPY (show_ip_bgp_summary,
show_ip_bgp_summary_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] summary [established|failed] [json$uj]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] summary [established|failed] [wide] [json$uj]",
SHOW_STR
IP_STR
BGP_STR
@@ -11284,13 +11410,13 @@ DEFPY (show_ip_bgp_summary,
"Summary of BGP neighbor status\n"
"Show only sessions in Established state\n"
"Show only sessions not in Established state\n"
+ "Increase table width for longer output\n"
JSON_STR)
{
char *vrf = NULL;
afi_t afi = AFI_MAX;
safi_t safi = SAFI_MAX;
- bool show_failed = false;
- bool show_established = false;
+ uint8_t show_flags = 0;
int idx = 0;
@@ -11311,12 +11437,18 @@ DEFPY (show_ip_bgp_summary,
}
if (argv_find(argv, argc, "failed", &idx))
- show_failed = true;
+ SET_FLAG(show_flags, BGP_SHOW_OPT_FAILED);
+
if (argv_find(argv, argc, "established", &idx))
- show_established = true;
+ SET_FLAG(show_flags, BGP_SHOW_OPT_ESTABLISHED);
- return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed,
- show_established, uj);
+ if (argv_find(argv, argc, "wide", &idx))
+ SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
+
+ if (argv_find(argv, argc, "json", &idx))
+ SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
+
+ return bgp_show_summary_vty(vty, vrf, afi, safi, show_flags);
}
const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json)
@@ -13088,6 +13220,37 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
"received");
}
+ /* Enhanced Route Refresh */
+ if (CHECK_FLAG(p->cap, PEER_CAP_ENHANCED_RR_ADV)
+ || CHECK_FLAG(p->cap,
+ PEER_CAP_ENHANCED_RR_RCV)) {
+ if (CHECK_FLAG(p->cap,
+ PEER_CAP_ENHANCED_RR_ADV)
+ && CHECK_FLAG(
+ p->cap,
+ PEER_CAP_ENHANCED_RR_RCV))
+ json_object_string_add(
+ json_cap,
+ "enhancedRouteRefresh",
+ "advertisedAndReceived");
+ else if (
+ CHECK_FLAG(
+ p->cap,
+ PEER_CAP_ENHANCED_RR_ADV))
+ json_object_string_add(
+ json_cap,
+ "enhancedRouteRefresh",
+ "advertised");
+ else if (
+ CHECK_FLAG(
+ p->cap,
+ PEER_CAP_ENHANCED_RR_RCV))
+ json_object_string_add(
+ json_cap,
+ "enhancedRouteRefresh",
+ "received");
+ }
+
/* Multiprotocol Extensions */
json_object *json_multi = NULL;
json_multi = json_object_new_object();
@@ -13460,6 +13623,28 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
vty_out(vty, "\n");
}
+ /* Enhanced Route Refresh */
+ if (CHECK_FLAG(p->cap, PEER_CAP_ENHANCED_RR_ADV)
+ || CHECK_FLAG(p->cap,
+ PEER_CAP_ENHANCED_RR_RCV)) {
+ vty_out(vty,
+ " Enhanced Route Refresh:");
+ if (CHECK_FLAG(
+ p->cap,
+ PEER_CAP_ENHANCED_RR_ADV))
+ vty_out(vty, " advertised");
+ if (CHECK_FLAG(
+ p->cap,
+ PEER_CAP_ENHANCED_RR_RCV))
+ vty_out(vty, " %sreceived",
+ CHECK_FLAG(
+ p->cap,
+ PEER_CAP_REFRESH_ADV)
+ ? "and "
+ : "");
+ vty_out(vty, "\n");
+ }
+
/* Multiprotocol Extensions */
FOREACH_AFI_SAFI (afi, safi)
if (p->afc_adv[afi][safi]
@@ -16882,7 +17067,15 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
/* BGP flag dampening. */
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
- bgp_config_write_damp(vty, afi, safi);
+ bgp_config_write_damp(vty, bgp, afi, safi);
+ for (ALL_LIST_ELEMENTS_RO(bgp->group, node, group))
+ if (peer_af_flag_check(group->conf, afi, safi,
+ PEER_FLAG_CONFIG_DAMPENING))
+ bgp_config_write_peer_damp(vty, group->conf, afi, safi);
+ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer))
+ if (peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_CONFIG_DAMPENING))
+ bgp_config_write_peer_damp(vty, peer, afi, safi);
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
@@ -17019,6 +17212,16 @@ int bgp_config_write(struct vty *vty)
if (bgp->reject_as_sets)
vty_out(vty, " bgp reject-as-sets\n");
+ /* Suppress duplicate updates if the route actually not changed
+ */
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SUPPRESS_DUPLICATES)
+ != SAVE_BGP_SUPPRESS_DUPLICATES)
+ vty_out(vty, " %sbgp suppress-duplicates\n",
+ CHECK_FLAG(bgp->flags,
+ BGP_FLAG_SUPPRESS_DUPLICATES)
+ ? ""
+ : "no ");
+
/* BGP default ipv4-unicast. */
if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
vty_out(vty, " no bgp default ipv4-unicast\n");
@@ -17602,6 +17805,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
+ /* bgp suppress-duplicates */
+ install_element(BGP_NODE, &bgp_suppress_duplicates_cmd);
+ install_element(BGP_NODE, &no_bgp_suppress_duplicates_cmd);
+
/* bgp reject-as-sets */
install_element(BGP_NODE, &bgp_reject_as_sets_cmd);
install_element(BGP_NODE, &no_bgp_reject_as_sets_cmd);
@@ -18404,27 +18611,16 @@ void bgp_vty_init(void)
/* "neighbor prefix-list" commands. */
install_element(BGP_NODE, &neighbor_prefix_list_hidden_cmd);
- install_element(BGP_NODE, &no_neighbor_prefix_list_hidden_cmd);
install_element(BGP_IPV4_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV4_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_IPV4M_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV4M_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_IPV4L_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV4L_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_IPV6_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV6_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_IPV6M_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV6M_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_IPV6L_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_IPV6L_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_VPNV4_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_VPNV6_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_FLOWSPECV4_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_FLOWSPECV6_NODE, &neighbor_prefix_list_cmd);
- install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_prefix_list_cmd);
/* "neighbor filter-list" commands. */
install_element(BGP_NODE, &neighbor_filter_list_hidden_cmd);
@@ -18451,30 +18647,17 @@ void bgp_vty_init(void)
install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_filter_list_cmd);
/* "neighbor route-map" commands. */
- install_element(BGP_NODE, &neighbor_route_map_hidden_cmd);
- install_element(BGP_NODE, &no_neighbor_route_map_hidden_cmd);
install_element(BGP_IPV4_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV4_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_IPV4M_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV4M_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_IPV4L_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV4L_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_IPV6_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV6_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_IPV6M_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV6M_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_IPV6L_NODE, &neighbor_route_map_cmd);
- install_element(BGP_IPV6L_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_route_map_cmd);
- install_element(BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_route_map_cmd);
- install_element(BGP_VPNV6_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_FLOWSPECV4_NODE, &neighbor_route_map_cmd);
- install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_FLOWSPECV6_NODE, &neighbor_route_map_cmd);
- install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd);
- install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd);
/* "neighbor unsuppress-map" commands. */
install_element(BGP_NODE, &neighbor_unsuppress_map_hidden_cmd);
@@ -18633,6 +18816,23 @@ void bgp_vty_init(void)
install_element(BGP_EVPN_NODE, &neighbor_allowas_in_cmd);
install_element(BGP_EVPN_NODE, &no_neighbor_allowas_in_cmd);
+ /* "neighbor dampening" commands. */
+ install_element(BGP_NODE, &neighbor_damp_cmd);
+ install_element(BGP_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV4_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV4_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV4M_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV4M_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV4L_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV4L_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV6_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV6_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV6M_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV6M_NODE, &no_neighbor_damp_cmd);
+ install_element(BGP_IPV6L_NODE, &neighbor_damp_cmd);
+ install_element(BGP_IPV6L_NODE, &no_neighbor_damp_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_neighbor_damp_param_cmd);
+
/* address-family commands. */
install_element(BGP_NODE, &address_family_ipv4_safi_cmd);
install_element(BGP_NODE, &address_family_ipv6_safi_cmd);