]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
bgpd: Add 'rd all' keyword to EVPN/L3VPN show cmds
[mirror_frr.git] / bgpd / bgp_route.c
index 19761d701ae1c396c168261fd3eb57a424104a58..b3c6fbff8f58a6380196de16eea2a1ecd957e53a 100644 (file)
@@ -97,6 +97,11 @@ DEFINE_HOOK(bgp_snmp_update_stats,
            (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
            (rn, pi, added))
 
+DEFINE_HOOK(bgp_rpki_prefix_status,
+           (struct peer *peer, struct attr *attr,
+            const struct prefix *prefix),
+           (peer, attr, prefix))
+
 /* Extern from bgp_dump.c */
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
@@ -525,13 +530,14 @@ static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
        }
 }
 
-void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
+void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
+                                           size_t buf_len)
 {
        if (pi->addpath_rx_id)
-               sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
-                       pi->addpath_rx_id);
+               snprintf(buf, buf_len, "path %s (addpath rxid %d)",
+                        pi->peer->host, pi->addpath_rx_id);
        else
-               sprintf(buf, "path %s", pi->peer->host);
+               snprintf(buf, buf_len, "path %s", pi->peer->host);
 }
 
 /* Compare two bgp route entity.  If 'new' is preferable over 'exist' return 1.
@@ -582,7 +588,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
        }
 
        if (debug)
-               bgp_path_info_path_with_addpath_rx_str(new, new_buf);
+               bgp_path_info_path_with_addpath_rx_str(new, new_buf,
+                                                      sizeof(new_buf));
 
        if (exist == NULL) {
                *reason = bgp_path_selection_first;
@@ -593,7 +600,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
        }
 
        if (debug) {
-               bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
+               bgp_path_info_path_with_addpath_rx_str(exist, exist_buf,
+                                                      sizeof(exist_buf));
                zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
                           pfx_buf, new_buf, new->flags, exist_buf,
                           exist->flags);
@@ -621,10 +629,10 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                                prefix2str(
                                        bgp_dest_get_prefix(new->net), pfx_buf,
                                        sizeof(*pfx_buf) * PREFIX2STR_BUFFER);
-                               bgp_path_info_path_with_addpath_rx_str(new,
-                                                                      new_buf);
                                bgp_path_info_path_with_addpath_rx_str(
-                                       exist, exist_buf);
+                                       new, new_buf, sizeof(new_buf));
+                               bgp_path_info_path_with_addpath_rx_str(
+                                       exist, exist_buf, sizeof(exist_buf));
                        }
 
                        if (newattr->sticky && !existattr->sticky) {
@@ -987,7 +995,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
        if (newm < existm) {
                if (debug)
                        zlog_debug(
-                               "%s: %s wins over %s due to IGP metric %d < %d",
+                               "%s: %s wins over %s due to IGP metric %u < %u",
                                pfx_buf, new_buf, exist_buf, newm, existm);
                ret = 1;
        }
@@ -995,7 +1003,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
        if (newm > existm) {
                if (debug)
                        zlog_debug(
-                               "%s: %s loses to %s due to IGP metric %d > %d",
+                               "%s: %s loses to %s due to IGP metric %u > %u",
                                pfx_buf, new_buf, exist_buf, newm, existm);
                ret = 0;
        }
@@ -1017,7 +1025,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                        if (newm < existm) {
                                if (debug)
                                        zlog_debug(
-                                               "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
+                                               "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
                                                pfx_buf, new_buf, exist_buf,
                                                newm, existm);
                                ret = 1;
@@ -1026,7 +1034,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                        if (newm > existm) {
                                if (debug)
                                        zlog_debug(
-                                               "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
+                                               "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
                                                pfx_buf, new_buf, exist_buf,
                                                newm, existm);
                                ret = 0;
@@ -2348,7 +2356,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
 
                        if (debug) {
                                bgp_path_info_path_with_addpath_rx_str(
-                                       new_select, path_buf);
+                                       new_select, path_buf, sizeof(path_buf));
                                zlog_debug(
                                        "%pBD: %s is the bestpath from AS %u",
                                        dest, path_buf,
@@ -2422,8 +2430,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
         */
        if (debug) {
                if (new_select)
-                       bgp_path_info_path_with_addpath_rx_str(new_select,
-                                                              path_buf);
+                       bgp_path_info_path_with_addpath_rx_str(
+                               new_select, path_buf, sizeof(path_buf));
                else
                        snprintf(path_buf, sizeof(path_buf), "NONE");
                zlog_debug(
@@ -2438,7 +2446,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
 
                        if (debug)
                                bgp_path_info_path_with_addpath_rx_str(
-                                       pi, path_buf);
+                                       pi, path_buf, sizeof(path_buf));
 
                        if (pi == new_select) {
                                if (debug)
@@ -3594,19 +3602,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
        if (has_valid_label)
                assert(label != NULL);
 
-       /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
-        * condition :
-        * Suppress fib is enabled
-        * BGP_OPT_NO_FIB is not enabled
-        * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
-        * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
-        */
-       if (BGP_SUPPRESS_FIB_ENABLED(bgp) &&
-           (sub_type == BGP_ROUTE_NORMAL) &&
-           (!bgp_option_check(BGP_OPT_NO_FIB)) &&
-           (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
-               SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
-
        /* When peer's soft reconfiguration enabled.  Record input packet in
           Adj-RIBs-In.  */
        if (!soft_reconfig
@@ -3788,6 +3783,19 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                                     evpn == NULL ? NULL : &evpn->gw_ip);
        }
 
+       /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
+        * condition :
+        * Suppress fib is enabled
+        * BGP_OPT_NO_FIB is not enabled
+        * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
+        * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
+        */
+       if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
+           && (sub_type == BGP_ROUTE_NORMAL)
+           && (!bgp_option_check(BGP_OPT_NO_FIB))
+           && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
+               SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
+
        attr_new = bgp_attr_intern(&new_attr);
 
        /* If maximum prefix count is configured and current prefix
@@ -5247,26 +5255,18 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                /* Check address. */
                if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
                        if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
-                               char buf[BUFSIZ];
-
                                flog_err(
                                        EC_BGP_UPDATE_RCV,
-                                       "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
-                                       peer->host,
-                                       inet_ntop(AF_INET6, &p.u.prefix6, buf,
-                                                 BUFSIZ));
+                                       "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
+                                       peer->host, &p.u.prefix6);
 
                                continue;
                        }
                        if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
-                               char buf[BUFSIZ];
-
                                flog_err(
                                        EC_BGP_UPDATE_RCV,
-                                       "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
-                                       peer->host,
-                                       inet_ntop(AF_INET6, &p.u.prefix6, buf,
-                                                 BUFSIZ));
+                                       "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
+                                       peer->host, &p.u.prefix6);
 
                                continue;
                        }
@@ -6389,7 +6389,8 @@ DEFPY_YANG (bgp_network, bgp_network_cmd,
                int ret;
 
                ret = netmask_str2prefix_str(address_str, netmask_str,
-                                            addr_prefix_str);
+                                            addr_prefix_str,
+                                            sizeof(addr_prefix_str));
                if (!ret) {
                        vty_out(vty, "%% Inconsistent address and mask\n");
                        return CMD_WARNING_CONFIG_FAILED;
@@ -7550,6 +7551,21 @@ static const char *bgp_origin2str(uint8_t origin)
        return "n/a";
 }
 
+static const char *bgp_rpki_validation2str(int v_state)
+{
+       switch (v_state) {
+       case 1:
+               return "valid";
+       case 2:
+               return "not found";
+       case 3:
+               return "invalid";
+       default:
+               break;
+       }
+       return "ERROR";
+}
+
 int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
                        safi_t safi, char *errmsg, size_t errmsg_len)
 {
@@ -7780,7 +7796,8 @@ DEFPY_YANG(
        char prefix_buf[PREFIX2STR_BUFFER];
 
        if (addr_str) {
-               if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf)
+               if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
+                                          sizeof(prefix_buf))
                    == 0) {
                        vty_out(vty, "%% Inconsistent address and mask\n");
                        return CMD_WARNING_CONFIG_FAILED;
@@ -8272,7 +8289,7 @@ bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
        case bgp_path_selection_router_id:
                return "Router ID";
        case bgp_path_selection_cluster_length:
-               return "Cluser length";
+               return "Cluster length";
        case bgp_path_selection_stale:
                return "Path Staleness";
        case bgp_path_selection_local_configured:
@@ -9563,6 +9580,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
        int i;
        char *nexthop_hostname =
                bgp_nexthop_hostname(path->peer, path->nexthop);
+       int rpki_validation_state = 0;
 
        if (json_paths) {
                json_path = json_object_new_object();
@@ -10161,6 +10179,20 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                }
        }
 
+       const struct prefix *p = bgp_dest_get_prefix(bn);
+       if (p->family == AF_INET || p->family == AF_INET6)
+               rpki_validation_state = hook_call(bgp_rpki_prefix_status,
+                                                 path->peer, path->attr, p);
+       if (rpki_validation_state) {
+               if (json_paths)
+                       json_object_string_add(
+                               json_path, "rpkiValidationState",
+                               bgp_rpki_validation2str(rpki_validation_state));
+               else
+                       vty_out(vty, ", validation-state: %s",
+                               bgp_rpki_validation2str(rpki_validation_state));
+       }
+
        if (json_bestpath)
                json_object_object_add(json_path, "bestpath", json_bestpath);
 
@@ -12380,6 +12412,9 @@ static int bgp_table_stats_walker(struct thread *t)
        case AFI_IP6:
                space = IPV6_MAX_BITLEN;
                break;
+       case AFI_L2VPN:
+               space = EVPN_ROUTE_PREFIXLEN;
+               break;
        default:
                return 0;
        }
@@ -13021,51 +13056,29 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
        }
 }
 
-static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
-                          safi_t safi, enum bgp_show_adj_route_type type,
-                          const char *rmap_name, json_object *json,
-                          uint8_t show_flags)
+static void
+show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
+              afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
+              const char *rmap_name, json_object *json, json_object *json_ar,
+              json_object *json_scode, json_object *json_ocode,
+              uint8_t show_flags, int *header1, int *header2, char *rd_str,
+              unsigned long *output_count, unsigned long *filtered_count)
 {
-       struct bgp_table *table;
        struct bgp_adj_in *ain;
        struct bgp_adj_out *adj;
-       unsigned long output_count = 0;
-       unsigned long filtered_count = 0;
        struct bgp_dest *dest;
-       int header1 = 1;
        struct bgp *bgp;
-       int header2 = 1;
        struct attr attr;
        int ret;
        struct update_subgroup *subgrp;
-       json_object *json_scode = NULL;
-       json_object *json_ocode = NULL;
-       json_object *json_ar = NULL;
        struct peer_af *paf;
        bool route_filtered;
        bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
        bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
-
-       if (use_json) {
-               json_scode = json_object_new_object();
-               json_ocode = json_object_new_object();
-               json_ar = json_object_new_object();
-
-               json_object_string_add(json_scode, "suppressed", "s");
-               json_object_string_add(json_scode, "damped", "d");
-               json_object_string_add(json_scode, "history", "h");
-               json_object_string_add(json_scode, "valid", "*");
-               json_object_string_add(json_scode, "best", ">");
-               json_object_string_add(json_scode, "multipath", "=");
-               json_object_string_add(json_scode, "internal", "i");
-               json_object_string_add(json_scode, "ribFailure", "r");
-               json_object_string_add(json_scode, "stale", "S");
-               json_object_string_add(json_scode, "removed", "R");
-
-               json_object_string_add(json_ocode, "igp", "i");
-               json_object_string_add(json_ocode, "egp", "e");
-               json_object_string_add(json_ocode, "incomplete", "?");
-       }
+       bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+                       || (safi == SAFI_EVPN))
+                              ? true
+                              : false;
 
        bgp = peer->bgp;
 
@@ -13079,13 +13092,6 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                return;
        }
 
-       /* labeled-unicast routes live in the unicast table */
-       if (safi == SAFI_LABELED_UNICAST)
-               table = bgp->rib[afi][SAFI_UNICAST];
-       else
-               table = bgp->rib[afi][safi];
-
-       output_count = filtered_count = 0;
        subgrp = peer_subgroup(peer, afi, safi);
 
        if (type == bgp_show_adj_route_advertised && subgrp
@@ -13129,7 +13135,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                        vty_out(vty, "Originating default network %s\n\n",
                                (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
                }
-               header1 = 0;
+               *header1 = 0;
        }
 
        for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
@@ -13139,9 +13145,23 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                if (ain->peer != peer)
                                        continue;
 
-                               show_adj_route_header(
-                                       vty, bgp, table, &header1, &header2,
-                                       json, json_scode, json_ocode, wide);
+                               show_adj_route_header(vty, bgp, table, header1,
+                                                     header2, json, json_scode,
+                                                     json_ocode, wide);
+
+                               if ((safi == SAFI_MPLS_VPN)
+                                   || (safi == SAFI_ENCAP)
+                                   || (safi == SAFI_EVPN)) {
+                                       if (use_json)
+                                               json_object_string_add(
+                                                       json_ar, "rd", rd_str);
+                                       else if (show_rd && rd_str) {
+                                               vty_out(vty,
+                                                       "Route Distinguisher: %s\n",
+                                                       rd_str);
+                                               show_rd = false;
+                                       }
+                               }
 
                                attr = *ain->attr;
                                route_filtered = false;
@@ -13167,14 +13187,14 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                        continue;
                                }
 
-                               if (type == bgp_show_adj_route_received &&
-                                       (route_filtered || ret == RMAP_DENY))
-                                       filtered_count++;
+                               if (type == bgp_show_adj_route_received
+                                   && (route_filtered || ret == RMAP_DENY))
+                                       (*filtered_count)++;
 
                                route_vty_out_tmp(vty, rn_p, &attr, safi,
                                                  use_json, json_ar, wide);
                                bgp_attr_undup(&attr, ain->attr);
-                               output_count++;
+                               (*output_count)++;
                        }
                } else if (type == bgp_show_adj_route_advertised) {
                        RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
@@ -13182,10 +13202,10 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                        if (paf->peer != peer || !adj->attr)
                                                continue;
 
-                                       show_adj_route_header(
-                                               vty, bgp, table, &header1,
-                                               &header2, json, json_scode,
-                                               json_ocode, wide);
+                                       show_adj_route_header(vty, bgp, table,
+                                                             header1, header2,
+                                                             json, json_scode,
+                                                             json_ocode, wide);
 
                                        const struct prefix *rn_p =
                                                bgp_dest_get_prefix(dest);
@@ -13196,13 +13216,29 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                rmap_name);
 
                                        if (ret != RMAP_DENY) {
+                                               if ((safi == SAFI_MPLS_VPN)
+                                                   || (safi == SAFI_ENCAP)
+                                                   || (safi == SAFI_EVPN)) {
+                                                       if (use_json)
+                                                               json_object_string_add(
+                                                                       json_ar,
+                                                                       "rd",
+                                                                       rd_str);
+                                                       else if (show_rd
+                                                                && rd_str) {
+                                                               vty_out(vty,
+                                                                       "Route Distinguisher: %s\n",
+                                                                       rd_str);
+                                                               show_rd = false;
+                                                       }
+                                               }
                                                route_vty_out_tmp(
                                                        vty, rn_p, &attr, safi,
                                                        use_json, json_ar,
                                                        wide);
-                                               output_count++;
+                                               (*output_count)++;
                                        } else {
-                                               filtered_count++;
+                                               (*filtered_count)++;
                                        }
 
                                        bgp_attr_undup(&attr, adj->attr);
@@ -13210,9 +13246,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                } else if (type == bgp_show_adj_route_bestpath) {
                        struct bgp_path_info *pi;
 
-                       show_adj_route_header(vty, bgp, table, &header1,
-                                             &header2, json, json_scode,
-                                             json_ocode, wide);
+                       show_adj_route_header(vty, bgp, table, header1, header2,
+                                             json, json_scode, json_ocode,
+                                             wide);
 
                        for (pi = bgp_dest_get_bgp_path_info(dest); pi;
                             pi = pi->next) {
@@ -13226,46 +13262,67 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                  bgp_dest_get_prefix(dest),
                                                  pi->attr, safi, use_json,
                                                  json_ar, wide);
-                               output_count++;
+                               (*output_count)++;
                        }
                }
        }
-
-       if (use_json) {
-               json_object_object_add(json, "advertisedRoutes", json_ar);
-               json_object_int_add(json, "totalPrefixCounter", output_count);
-               json_object_int_add(json, "filteredPrefixCounter",
-                                   filtered_count);
-
-               vty_out(vty, "%s\n", json_object_to_json_string_ext(
-                                            json, JSON_C_TO_STRING_PRETTY));
-
-               if (!output_count && !filtered_count) {
-                       json_object_free(json_scode);
-                       json_object_free(json_ocode);
-               }
-
-               json_object_free(json);
-       } else if (output_count > 0) {
-               if (filtered_count > 0)
-                       vty_out(vty,
-                               "\nTotal number of prefixes %ld (%ld filtered)\n",
-                               output_count, filtered_count);
-               else
-                       vty_out(vty, "\nTotal number of prefixes %ld\n",
-                               output_count);
-       }
 }
 
 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
                           safi_t safi, enum bgp_show_adj_route_type type,
                           const char *rmap_name, uint8_t show_flags)
 {
+       struct bgp *bgp;
+       struct bgp_table *table;
        json_object *json = NULL;
+       json_object *json_scode = NULL;
+       json_object *json_ocode = NULL;
+       json_object *json_ar = NULL;
        bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
 
-       if (use_json)
+       /* Init BGP headers here so they're only displayed once
+        * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
+        */
+       int header1 = 1;
+       int header2 = 1;
+
+       /*
+        * Initialize variables for each RD
+        * All prefixes under an RD is aggregated within "json_routes"
+        */
+       char rd_str[BUFSIZ] = {0};
+       json_object *json_routes = NULL;
+
+
+       /* For 2-tier tables, prefix counts need to be
+        * maintained across multiple runs of show_adj_route()
+        */
+       unsigned long output_count_per_rd;
+       unsigned long filtered_count_per_rd;
+       unsigned long output_count = 0;
+       unsigned long filtered_count = 0;
+
+       if (use_json) {
                json = json_object_new_object();
+               json_ar = json_object_new_object();
+               json_scode = json_object_new_object();
+               json_ocode = json_object_new_object();
+
+               json_object_string_add(json_scode, "suppressed", "s");
+               json_object_string_add(json_scode, "damped", "d");
+               json_object_string_add(json_scode, "history", "h");
+               json_object_string_add(json_scode, "valid", "*");
+               json_object_string_add(json_scode, "best", ">");
+               json_object_string_add(json_scode, "multipath", "=");
+               json_object_string_add(json_scode, "internal", "i");
+               json_object_string_add(json_scode, "ribFailure", "r");
+               json_object_string_add(json_scode, "stale", "S");
+               json_object_string_add(json_scode, "removed", "R");
+
+               json_object_string_add(json_ocode, "igp", "i");
+               json_object_string_add(json_ocode, "egp", "e");
+               json_object_string_add(json_ocode, "incomplete", "?");
+       }
 
        if (!peer || !peer->afc[afi][safi]) {
                if (use_json) {
@@ -13297,7 +13354,84 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
                return CMD_WARNING;
        }
 
-       show_adj_route(vty, peer, afi, safi, type, rmap_name, json, show_flags);
+       bgp = peer->bgp;
+
+       /* labeled-unicast routes live in the unicast table */
+       if (safi == SAFI_LABELED_UNICAST)
+               table = bgp->rib[afi][SAFI_UNICAST];
+       else
+               table = bgp->rib[afi][safi];
+
+       if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+           || (safi == SAFI_EVPN)) {
+
+               struct bgp_dest *dest;
+
+               for (dest = bgp_table_top(table); dest;
+                    dest = bgp_route_next(dest)) {
+                       table = bgp_dest_get_bgp_table_info(dest);
+                       if (!table)
+                               continue;
+
+                       output_count_per_rd = 0;
+                       filtered_count_per_rd = 0;
+
+                       if (use_json)
+                               json_routes = json_object_new_object();
+
+                       const struct prefix_rd *prd;
+                       prd = (const struct prefix_rd *)bgp_dest_get_prefix(
+                               dest);
+
+                       prefix_rd2str(prd, rd_str, sizeof(rd_str));
+
+                       show_adj_route(vty, peer, table, afi, safi, type,
+                                      rmap_name, json, json_routes, json_scode,
+                                      json_ocode, show_flags, &header1,
+                                      &header2, rd_str, &output_count_per_rd,
+                                      &filtered_count_per_rd);
+
+                       /* Don't include an empty RD in the output! */
+                       if (json_routes && (output_count_per_rd > 0))
+                               json_object_object_add(json_ar, rd_str,
+                                                      json_routes);
+
+                       output_count += output_count_per_rd;
+                       filtered_count += filtered_count_per_rd;
+               }
+       } else
+               show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
+                              json, json_ar, json_scode, json_ocode,
+                              show_flags, &header1, &header2, rd_str,
+                              &output_count, &filtered_count);
+
+       if (use_json) {
+               json_object_object_add(json, "advertisedRoutes", json_ar);
+               json_object_int_add(json, "totalPrefixCounter", output_count);
+               json_object_int_add(json, "filteredPrefixCounter",
+                                   filtered_count);
+
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+
+               if (!output_count && !filtered_count) {
+                       json_object_free(json_scode);
+                       json_object_free(json_ocode);
+               }
+
+               if (json)
+                       json_object_free(json);
+
+       } else if (output_count > 0) {
+               if (filtered_count > 0)
+                       vty_out(vty,
+                               "\nTotal number of prefixes %ld (%ld filtered)\n",
+                               output_count, filtered_count);
+               else
+                       vty_out(vty, "\nTotal number of prefixes %ld\n",
+                               output_count);
+       }
 
        return CMD_SUCCESS;
 }
@@ -13690,13 +13824,14 @@ struct bgp_distance {
 
 DEFUN (show_bgp_afi_vpn_rd_route,
        show_bgp_afi_vpn_rd_route_cmd,
-       "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
+       "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> <A.B.C.D/M|X:X::X:X/M> [json]",
        SHOW_STR
        BGP_STR
        BGP_AFI_HELP_STR
        "Address Family modifier\n"
        "Display information for a route distinguisher\n"
        "Route Distinguisher\n"
+       "All Route Distinguishers\n"
        "Network in the BGP routing table to display\n"
        "Network in the BGP routing table to display\n"
        JSON_STR)
@@ -13711,6 +13846,11 @@ DEFUN (show_bgp_afi_vpn_rd_route,
                return CMD_WARNING;
        }
 
+       if (!strcmp(argv[5]->arg, "all"))
+               return bgp_show_route(vty, NULL, argv[6]->arg, afi,
+                                     SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
+                                     use_json(argc, argv));
+
        ret = str2prefix_rd(argv[5]->arg, &prd);
        if (!ret) {
                vty_out(vty, "%% Malformed Route Distinguisher\n");
@@ -14209,6 +14349,21 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                                while (pi) {
                                        if (pi->extra && pi->extra->damp_info) {
                                                pi_temp = pi->next;
+                                               struct bgp_damp_info *bdi =
+                                                       pi->extra->damp_info;
+                                               if (bdi->lastrecord
+                                                   == BGP_RECORD_UPDATE) {
+                                                       bgp_aggregate_increment(
+                                                               bgp,
+                                                               &bdi->dest->p,
+                                                               bdi->path,
+                                                               bdi->afi,
+                                                               bdi->safi);
+                                                       bgp_process(bgp,
+                                                                   bdi->dest,
+                                                                   bdi->afi,
+                                                                   bdi->safi);
+                                               }
                                                bgp_damp_info_free(
                                                        &pi->extra->damp_info,
                                                        &bgp->damp[afi][safi],
@@ -14235,7 +14390,7 @@ DEFUN (clear_ip_bgp_dampening,
        "Clear route flap dampening information\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
+       bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
                            SAFI_UNICAST);
        return CMD_SUCCESS;
 }
@@ -14284,7 +14439,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
        char prefix_str[BUFSIZ];
 
        ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
-                                    prefix_str);
+                                    prefix_str, sizeof(prefix_str));
        if (!ret) {
                vty_out(vty, "%% Inconsistent address and mask\n");
                return CMD_WARNING;