]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_vty.c
Merge pull request #7781 from chiragshah6/evpn_dev
[mirror_frr.git] / bgpd / bgp_vty.c
index 4cdd4d2e629b66e446e8f1f3c4ccfb9260ab9c56..bd13b5cd5b1996322ab06db08f27c6b69618e640 100644 (file)
@@ -4952,27 +4952,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,
@@ -5528,7 +5564,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));
 
@@ -5567,7 +5602,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));
 
@@ -5652,7 +5686,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));
 
@@ -5810,7 +5843,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));
 
@@ -5850,7 +5882,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));
 
@@ -5891,7 +5922,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));
 
@@ -5972,7 +6002,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));
 
@@ -6013,7 +6042,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));
 
@@ -6055,7 +6083,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));
 
@@ -6345,7 +6372,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));
 
@@ -7732,69 +7758,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,
@@ -7805,32 +7806,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)
@@ -7991,70 +7966,52 @@ 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);
+       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));
 
-       return bgp_vty_return(vty, ret);
-}
+       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);
 
-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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(neighbor_route_map, neighbor_route_map_hidden_cmd,
@@ -8065,25 +8022,7 @@ ALIAS_HIDDEN(neighbor_route_map, neighbor_route_map_hidden_cmd,
             "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);
-}
-
-ALIAS_HIDDEN(no_neighbor_route_map, no_neighbor_route_map_hidden_cmd,
+ALIAS_HIDDEN(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"
@@ -8896,6 +8835,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)
 {
@@ -13153,6 +13179,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();
@@ -13525,6 +13582,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]
@@ -16947,7 +17026,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);
@@ -18483,27 +18570,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);
@@ -18533,27 +18609,16 @@ void bgp_vty_init(void)
        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);
@@ -18712,6 +18777,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);