]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
Merge pull request #3113 from donaldsharp/uninited_value
[mirror_frr.git] / bgpd / bgp_route.c
index e38257d564cc5a2350914d37f3d95a0affa3392d..715393b91db62ffdc6cc2fb265a78e5606aaecd5 100644 (file)
@@ -38,6 +38,7 @@
 #include "queue.h"
 #include "memory.h"
 #include "lib/json.h"
+#include "lib_errors.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -214,7 +215,7 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra)
                bgp_unlock(e->bgp_orig);
 
        if ((*extra)->bgp_fs_pbr)
-               list_delete_and_null(&((*extra)->bgp_fs_pbr));
+               list_delete(&((*extra)->bgp_fs_pbr));
        XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
 
        *extra = NULL;
@@ -353,14 +354,9 @@ static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri)
                /* slight hack, but more robust against errors. */
                if (ri->peer->pcount[table->afi][table->safi])
                        ri->peer->pcount[table->afi][table->safi]--;
-               else {
-                       zlog_warn(
-                               "%s: Asked to decrement 0 prefix count for peer %s",
-                               __func__, ri->peer->host);
-                       zlog_backtrace(LOG_WARNING);
-                       zlog_warn("%s: Please report to Quagga bugzilla",
-                                 __func__);
-               }
+               else
+                       flog_err(EC_LIB_DEVELOPMENT,
+                                "Asked to decrement 0 prefix count for peer");
        } else if (BGP_INFO_COUNTABLE(ri)
                   && !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
                SET_FLAG(ri->flags, BGP_INFO_COUNTED);
@@ -1054,8 +1050,8 @@ static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p,
 
 #define FILTER_EXIST_WARN(F, f, filter)                                        \
        if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter)))                 \
-               zlog_warn("%s: Could not find configured input %s-list %s!",   \
-                         peer->host, #f, F##_IN_NAME(filter));
+               zlog_debug("%s: Could not find configured input %s-list %s!",  \
+                          peer->host, #f, F##_IN_NAME(filter));
 
        if (DISTRIBUTE_IN_NAME(filter)) {
                FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
@@ -1093,8 +1089,8 @@ static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p,
 
 #define FILTER_EXIST_WARN(F, f, filter)                                        \
        if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter)))               \
-               zlog_warn("%s: Could not find configured output %s-list %s!",  \
-                         peer->host, #f, F##_OUT_NAME(filter));
+               zlog_debug("%s: Could not find configured output %s-list %s!", \
+                          peer->host, #f, F##_OUT_NAME(filter));
 
        if (DISTRIBUTE_OUT_NAME(filter)) {
                FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
@@ -2779,30 +2775,40 @@ static bool overlay_index_equal(afi_t afi, struct bgp_info *info,
 {
        struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
        union gw_addr *info_gw_ip, *info_gw_ip_remote;
-       char temp[16];
+       union {
+               struct eth_segment_id esi;
+               union gw_addr ip;
+       } temp;
 
        if (afi != AFI_L2VPN)
                return true;
        if (!info->attr) {
-               memset(&temp, 0, 16);
-               info_eth_s_id = (struct eth_segment_id *)&temp;
-               info_gw_ip = (union gw_addr *)&temp;
+               memset(&temp, 0, sizeof(temp));
+               info_eth_s_id = &temp.esi;
+               info_gw_ip = &temp.ip;
+
                if (eth_s_id == NULL && gw_ip == NULL)
                        return true;
        } else {
                info_eth_s_id = &(info->attr->evpn_overlay.eth_s_id);
                info_gw_ip = &(info->attr->evpn_overlay.gw_ip);
        }
-       if (gw_ip == NULL)
-               info_gw_ip_remote = (union gw_addr *)&temp;
-       else
+
+       if (gw_ip == NULL) {
+               memset(&temp, 0, sizeof(temp));
+               info_gw_ip_remote = &temp.ip;
+       } else
                info_gw_ip_remote = gw_ip;
-       if (eth_s_id == NULL)
-               info_eth_s_id_remote = (struct eth_segment_id *)&temp;
-       else
+
+       if (eth_s_id == NULL) {
+               memset(&temp, 0, sizeof(temp));
+               info_eth_s_id_remote = &temp.esi;
+       } else
                info_eth_s_id_remote = eth_s_id;
+
        if (!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
                return false;
+
        return !memcmp(info_eth_s_id, info_eth_s_id_remote,
                       sizeof(struct eth_segment_id));
 }
@@ -4044,7 +4050,6 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
                for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
                        struct bgp_node *rm;
-                       struct bgp_info *ri;
 
                        /* look for neighbor in tables */
                        if ((table = rn->info) == NULL)
@@ -4221,7 +4226,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                /* Prefix length check. */
                if (p.prefixlen > prefix_blen(&p) * 8) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
                                peer->host, p.prefixlen, packet->afi);
                        return -1;
@@ -4233,7 +4238,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d overflows packet)",
                                peer->host, p.prefixlen);
                        return -1;
@@ -4243,7 +4248,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                 * prefix */
                if (psize > (ssize_t)sizeof(p.u)) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
                                peer->host, p.prefixlen, sizeof(p.u));
                        return -1;
@@ -4265,7 +4270,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                 * ignored.
                                 */
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
                                        peer->host, inet_ntoa(p.u.prefix4));
                                continue;
@@ -4278,7 +4283,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                char buf[BUFSIZ];
 
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
                                        peer->host,
                                        inet_ntop(AF_INET6, &p.u.prefix6, buf,
@@ -4290,7 +4295,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                char buf[BUFSIZ];
 
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
                                        peer->host,
                                        inet_ntop(AF_INET6, &p.u.prefix6, buf,
@@ -4320,7 +4325,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
        /* Packet length consistency check. */
        if (pnt != lim) {
                flog_err(
-                       BGP_ERR_UPDATE_RCV,
+                       EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error (prefix length mismatch with total length)",
                        peer->host);
                return -1;
@@ -4732,7 +4737,6 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
                        break;
 
        if (ri) {
-               union gw_addr add;
                memset(&add, 0, sizeof(union gw_addr));
                if (attrhash_cmp(ri->attr, attr_new)
                    && overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
@@ -4851,7 +4855,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                        return CMD_WARNING_CONFIG_FAILED;
                }
 
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
 
                if ((label_index != BGP_INVALID_LABEL_INDEX)
                    && (label_index != bgp_static->label_index)) {
@@ -4873,7 +4877,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
 
                /* Clear configuration. */
                bgp_static_free(bgp_static);
-               rn->info = NULL;
+               bgp_static_set_node_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else {
@@ -4881,10 +4885,9 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                /* Set BGP static route configuration. */
                rn = bgp_node_get(bgp->route[afi][safi], &p);
 
-               if (rn->info) {
+               bgp_static = bgp_static_get_node_info(rn);
+               if (bgp_static) {
                        /* Configuration change. */
-                       bgp_static = rn->info;
-
                        /* Label index cannot be changed. */
                        if (bgp_static->label_index != label_index) {
                                vty_out(vty, "%% cannot change label-index\n");
@@ -4933,7 +4936,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                                bgp_static->rmap.map =
                                        route_map_lookup_by_name(rmap);
                        }
-                       rn->info = bgp_static;
+                       bgp_static_set_node_info(rn, bgp_static);
                }
 
                bgp_static->valid = 1;
@@ -4968,14 +4971,16 @@ void bgp_static_add(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static_update(bgp, &rn->p, rn->info, afi,
-                                                 safi);
+                               bgp_static_update(bgp, &rn->p,
+                                                 bgp_static_get_node_info(rn),
+                                                 afi, safi);
                        }
                }
 }
@@ -5003,19 +5008,20 @@ void bgp_static_delete(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_withdraw_safi(
                                                bgp, &rm->p, AFI_IP, safi,
                                                (struct prefix_rd *)&rn->p);
                                        bgp_static_free(bgp_static);
-                                       rn->info = NULL;
+                                       bgp_static_set_node_info(rn, NULL);
                                        bgp_unlock_node(rn);
                                }
                        } else {
-                               bgp_static = rn->info;
+                               bgp_static = bgp_static_get_node_info(rn);
                                bgp_static_withdraw(bgp, &rn->p, afi, safi);
                                bgp_static_free(bgp_static);
-                               rn->info = NULL;
+                               bgp_static_set_node_info(rn, NULL);
                                bgp_unlock_node(rn);
                        }
                }
@@ -5044,13 +5050,14 @@ void bgp_static_redo_import_check(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static = rn->info;
+                               bgp_static = bgp_static_get_node_info(rn);
                                bgp_static_update(bgp, &rn->p, bgp_static, afi,
                                                  safi);
                        }
@@ -5222,7 +5229,7 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
                        if (gwip)
                                prefix_copy(&bgp_static->gatewayIp, &gw_ip);
                }
-               rn->info = bgp_static;
+               bgp_static_set_node_info(rn, bgp_static);
 
                bgp_static->valid = 1;
                bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
@@ -5284,9 +5291,9 @@ int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
        if (rn) {
                bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
 
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
                bgp_static_free(bgp_static);
-               rn->info = NULL;
+               bgp_static_set_node_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else
@@ -5460,7 +5467,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
        XFREE(MTYPE_BGP_AGGREGATE, aggregate);
 }
 
-static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
+static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin,
+                                  struct aspath *aspath,
                                   struct community *comm)
 {
        static struct aspath *ae = NULL;
@@ -5471,12 +5479,18 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
        if (!ri)
                return 0;
 
+       if (origin != ri->attr->origin)
+               return 0;
+
        if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae))
                return 0;
 
        if (!community_cmp(ri->attr->community, comm))
                return 0;
 
+       if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID))
+               return 0;
+
        return 1;
 }
 
@@ -5505,7 +5519,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                 * If the aggregate information has not changed
                 * no need to re-install it again.
                 */
-               if (bgp_aggregate_info_same(rn->info, aspath, community)) {
+               if (bgp_aggregate_info_same(rn->info, origin, aspath,
+                                           community)) {
                        bgp_unlock_node(rn);
 
                        if (aspath)
@@ -5770,13 +5785,14 @@ void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
        child = bgp_node_get(table, p);
 
        /* Aggregate address configuration check. */
-       for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
-               if ((aggregate = rn->info) != NULL
-                   && rn->p.prefixlen < p->prefixlen) {
+       for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+               aggregate = bgp_aggregate_get_node_info(rn);
+               if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
                                            aggregate);
                }
+       }
        bgp_unlock_node(child);
 }
 
@@ -5800,13 +5816,14 @@ void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
        child = bgp_node_get(table, p);
 
        /* Aggregate address configuration check. */
-       for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
-               if ((aggregate = rn->info) != NULL
-                   && rn->p.prefixlen < p->prefixlen) {
+       for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+               aggregate = bgp_aggregate_get_node_info(rn);
+               if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
                                            aggregate);
                }
+       }
        bgp_unlock_node(child);
 }
 
@@ -5839,12 +5856,12 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       aggregate = rn->info;
+       aggregate = bgp_aggregate_get_node_info(rn);
        bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
        bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
 
        /* Unlock aggregate address configuration. */
-       rn->info = NULL;
+       bgp_aggregate_set_node_info(rn, NULL);
        bgp_aggregate_free(aggregate);
        bgp_unlock_node(rn);
        bgp_unlock_node(rn);
@@ -5895,7 +5912,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
        aggregate->summary_only = summary_only;
        aggregate->as_set = as_set;
        aggregate->safi = safi;
-       rn->info = aggregate;
+       bgp_aggregate_set_node_info(rn, aggregate);
 
        /* Aggregate address insert into BGP routing table. */
        bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
@@ -6759,7 +6776,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
 
 /* called from terminal list command */
 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
-                      safi_t safi, uint8_t use_json, json_object *json_ar)
+                      safi_t safi, bool use_json, json_object *json_ar)
 {
        json_object *json_status = NULL;
        json_object *json_net = NULL;
@@ -7088,7 +7105,7 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
 /* dampening route */
 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
                               struct bgp_info *binfo, int display, safi_t safi,
-                              uint8_t use_json, json_object *json)
+                              bool use_json, json_object *json)
 {
        struct attr *attr;
        int len;
@@ -7151,7 +7168,7 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p,
 /* flap route */
 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
                               struct bgp_info *binfo, int display, safi_t safi,
-                              uint8_t use_json, json_object *json)
+                              bool use_json, json_object *json)
 {
        struct attr *attr;
        struct bgp_damp_info *bdi;
@@ -8164,12 +8181,12 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
                           afi_t afi, safi_t safi, enum bgp_show_type type);
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi, uint8_t use_json);
+                             safi_t safi, bool use_json);
 
 
 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                          struct bgp_table *table, enum bgp_show_type type,
-                         void *output_arg, uint8_t use_json, char *rd,
+                         void *output_arg, bool use_json, char *rd,
                          int is_last, unsigned long *output_cum,
                          unsigned long *total_cum,
                          unsigned long *json_header_depth)
@@ -8290,8 +8307,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                        continue;
                        }
                        if (type == bgp_show_type_prefix_longer) {
-                               struct prefix *p = output_arg;
-
+                               p = output_arg;
                                if (!prefix_match(p, &rn->p))
                                        continue;
                        }
@@ -8456,8 +8472,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
 
 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
                      struct bgp_table *table, struct prefix_rd *prd_match,
-                     enum bgp_show_type type, void *output_arg,
-                     uint8_t use_json)
+                     enum bgp_show_type type, void *output_arg, bool use_json)
 {
        struct bgp_node *rn, *next;
        unsigned long output_cum = 0;
@@ -8497,7 +8512,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
        return CMD_SUCCESS;
 }
 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
-                   enum bgp_show_type type, void *output_arg, uint8_t use_json)
+                   enum bgp_show_type type, void *output_arg, bool use_json)
 {
        struct bgp_table *table;
        unsigned long json_header_depth = 0;
@@ -8535,16 +8550,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
 }
 
 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
-                                             safi_t safi, uint8_t use_json)
+                                             safi_t safi, bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        int is_first = 1;
+       bool route_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               route_output = true;
                if (use_json) {
                        if (!is_first)
                                vty_out(vty, ",\n");
@@ -8567,6 +8584,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!route_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 /* Header of detailed BGP route information */
@@ -8585,9 +8604,19 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
        int count = 0;
        int best = 0;
        int suppress = 0;
+       int accept_own = 0;
+       int route_filter_translated_v4 = 0;
+       int route_filter_v4 = 0;
+       int route_filter_translated_v6 = 0;
+       int route_filter_v6 = 0;
+       int llgr_stale = 0;
+       int no_llgr = 0;
+       int accept_own_nexthop = 0;
+       int blackhole = 0;
        int no_export = 0;
        int no_advertise = 0;
        int local_as = 0;
+       int no_peer = 0;
        int first = 1;
        int has_valid_label = 0;
        mpls_label_t label = 0;
@@ -8664,12 +8693,41 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
                } else
                        vty_out(vty, ", no best path");
 
-               if (no_advertise)
-                       vty_out(vty, ", not advertised to any peer");
+               if (accept_own)
+                       vty_out(vty,
+                       ", accept own local route exported and imported in different VRF");
+               else if (route_filter_translated_v4)
+                       vty_out(vty,
+                       ", mark translated RTs for VPNv4 route filtering");
+               else if (route_filter_v4)
+                       vty_out(vty,
+                       ", attach RT as-is for VPNv4 route filtering");
+               else if (route_filter_translated_v6)
+                       vty_out(vty,
+                       ", mark translated RTs for VPNv6 route filtering");
+               else if (route_filter_v6)
+                       vty_out(vty,
+                       ", attach RT as-is for VPNv6 route filtering");
+               else if (llgr_stale)
+                       vty_out(vty,
+                       ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
+               else if (no_llgr)
+                       vty_out(vty,
+                       ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
+               else if (accept_own_nexthop)
+                       vty_out(vty,
+                       ", accept local nexthop");
+               else if (blackhole)
+                       vty_out(vty, ", inform peer to blackhole prefix");
                else if (no_export)
                        vty_out(vty, ", not advertised to EBGP peer");
+               else if (no_advertise)
+                       vty_out(vty, ", not advertised to any peer");
                else if (local_as)
                        vty_out(vty, ", not advertised outside local AS");
+               else if (no_peer)
+                       vty_out(vty,
+                       ", inform EBGP peer not to advertise to their EBGP peers");
 
                if (suppress)
                        vty_out(vty,
@@ -8713,8 +8771,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                                   struct bgp_table *rib, const char *ip_str,
                                   afi_t afi, safi_t safi,
                                   struct prefix_rd *prd, int prefix_check,
-                                  enum bgp_path_type pathtype,
-                                  uint8_t use_json)
+                                  enum bgp_path_type pathtype, bool use_json)
 {
        int ret;
        int header;
@@ -8850,7 +8907,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
                          afi_t afi, safi_t safi, struct prefix_rd *prd,
                          int prefix_check, enum bgp_path_type pathtype,
-                         uint8_t use_json)
+                         bool use_json)
 {
        if (!bgp) {
                bgp = bgp_get_default();
@@ -8874,7 +8931,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
 
 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
                               struct cmd_token **argv, afi_t afi, safi_t safi,
-                              uint8_t uj)
+                              bool uj)
 {
        struct lcommunity *lcom;
        struct buffer *b;
@@ -8911,7 +8968,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
 
 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
                                    const char *lcom, afi_t afi, safi_t safi,
-                                   uint8_t uj)
+                                   bool uj)
 {
        struct community_list *list;
 
@@ -8959,7 +9016,7 @@ DEFUN (show_ip_bgp_large_community_list,
                        safi = bgp_vty_safi_from_str(argv[idx]->text);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        struct bgp *bgp = bgp_lookup_by_name(vrf);
        if (bgp == NULL) {
@@ -9002,7 +9059,7 @@ DEFUN (show_ip_bgp_large_community,
                        safi = bgp_vty_safi_from_str(argv[idx]->text);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        struct bgp *bgp = bgp_lookup_by_name(vrf);
        if (bgp == NULL) {
@@ -9030,6 +9087,10 @@ DEFUN (show_ip_bgp,
            |prefix-list WORD\
            |filter-list WORD\
            |statistics\
+           |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown\
+           no-peer|blackhole|llgr-stale|no-llgr|accept-own|accept-own-nexthop\
+           route-filter-v6|route-filter-v4|route-filter-translated-v6|\
+           route-filter-translated-v4> [exact-match]\
            |community-list <(1-500)|WORD> [exact-match]\
            |A.B.C.D/M longer-prefixes\
            |X:X::X:X/M longer-prefixes\
@@ -9049,6 +9110,23 @@ DEFUN (show_ip_bgp,
        "Display routes conforming to the filter-list\n"
        "Regular expression access list name\n"
        "BGP RIB advertisement statistics\n"
+       "Display routes matching the communities\n"
+       COMMUNITY_AANN_STR
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "Graceful shutdown (well-known community)\n"
+       "Do not export to any peer (well-known community)\n"
+       "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
+       "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
+       "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
+       "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
+       "Should accept VPN route with local nexthop (well-known community)\n"
+       "RT VPNv6 route filtering (well-known community)\n"
+       "RT VPNv4 route filtering (well-known community)\n"
+       "RT translated VPNv6 route filtering (well-known community)\n"
+       "RT translated VPNv4 route filtering (well-known community)\n"
+       "Exact match of the communities\n"
        "Display routes matching the community-list\n"
        "community-list number\n"
        "community-list name\n"
@@ -9065,7 +9143,7 @@ DEFUN (show_ip_bgp,
        int idx = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, false);
        if (!idx)
                return CMD_WARNING;
 
@@ -9141,16 +9219,16 @@ DEFUN (show_ip_bgp_json,
        int idx = 0;
        int idx_community_type = 0;
        int exact_match = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        if (argv_find(argv, argc, "cidr-only", &idx))
                return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
                                NULL, uj);
@@ -9219,12 +9297,12 @@ DEFUN (show_ip_bgp_route,
        char *prefix = NULL;
        struct bgp *bgp = NULL;
        enum bgp_path_type path_type;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        int idx = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
@@ -9287,7 +9365,7 @@ DEFUN (show_ip_bgp_regexp,
 
        int idx = 0;
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, false);
        if (!idx)
                return CMD_WARNING;
 
@@ -9316,17 +9394,17 @@ DEFUN (show_ip_bgp_instance_all,
        afi_t afi = AFI_IP;
        safi_t safi = SAFI_UNICAST;
        struct bgp *bgp = NULL;
-
        int idx = 0;
-       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
-       if (!idx)
-               return CMD_WARNING;
+       bool uj = use_json(argc, argv);
 
-       int uj = use_json(argc, argv);
        if (uj)
                argc--;
 
+       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+                                           &bgp, uj);
+       if (!idx)
+               return CMD_WARNING;
+
        bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
        return CMD_SUCCESS;
 }
@@ -9397,7 +9475,7 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
 
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi, uint8_t use_json)
+                             safi_t safi, bool use_json)
 {
        struct community *com;
        int ret = 0;
@@ -9456,7 +9534,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
 }
 
 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
-                                       const char *ip_str, uint8_t use_json)
+                                       const char *ip_str, bool use_json)
 {
        int ret;
        struct peer *peer;
@@ -9809,8 +9887,6 @@ static int bgp_peer_count_walker(struct thread *t)
                                pc->count[PCOUNT_ADJ_IN]++;
 
                for (ri = rn->info; ri; ri = ri->next) {
-                       char buf[SU_ADDRSTRLEN];
-
                        if (ri->peer != peer)
                                continue;
 
@@ -9832,22 +9908,14 @@ static int bgp_peer_count_walker(struct thread *t)
                        if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
                                pc->count[PCOUNT_COUNTED]++;
                                if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
-                                       zlog_warn(
-                                               "%s [pcount] %s/%d is counted but flags 0x%x",
-                                               peer->host,
-                                               inet_ntop(rn->p.family,
-                                                         &rn->p.u.prefix, buf,
-                                                         SU_ADDRSTRLEN),
-                                               rn->p.prefixlen, ri->flags);
+                                       flog_err(
+                                               EC_LIB_DEVELOPMENT,
+                                               "Attempting to count but flags say it is unusable");
                        } else {
                                if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
-                                       zlog_warn(
-                                               "%s [pcount] %s/%d not counted but flags 0x%x",
-                                               peer->host,
-                                               inet_ntop(rn->p.family,
-                                                         &rn->p.u.prefix, buf,
-                                                         SU_ADDRSTRLEN),
-                                               rn->p.prefixlen, ri->flags);
+                                       flog_err(
+                                               EC_LIB_DEVELOPMENT,
+                                               "Not counted but flags say we should");
                        }
                }
        }
@@ -9855,7 +9923,7 @@ static int bgp_peer_count_walker(struct thread *t)
 }
 
 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
-                          safi_t safi, uint8_t use_json)
+                          safi_t safi, bool use_json)
 {
        struct peer_pcounts pcounts = {.peer = peer};
        unsigned int i;
@@ -9965,16 +10033,16 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
        struct peer *peer;
        int idx = 0;
        struct bgp *bgp = NULL;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        argv_find(argv, argc, "neighbors", &idx);
        peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
        if (!peer)
@@ -10001,7 +10069,7 @@ DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
 {
        int idx_peer = 6;
        struct peer *peer;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
        if (!peer)
@@ -10074,7 +10142,7 @@ DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
 
 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, uint8_t use_json,
+                          const char *rmap_name, bool use_json,
                           json_object *json)
 {
        struct bgp_table *table;
@@ -10345,7 +10413,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
 
 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 use_json)
+                          const char *rmap_name, bool use_json)
 {
        json_object *json = NULL;
 
@@ -10419,18 +10487,17 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
        struct bgp *bgp = NULL;
        struct peer *peer;
        enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
-
        int idx = 0;
-       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
-       if (!idx)
-               return CMD_WARNING;
-
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (uj)
                argc--;
 
+       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+                                           &bgp, uj);
+       if (!idx)
+               return CMD_WARNING;
+
        /* neighbors <A.B.C.D|X:X::X:X|WORD> */
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
@@ -10492,7 +10559,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
 
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        ret = str2sockunion(peerstr, &su);
        if (ret < 0) {
@@ -10536,7 +10603,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
 
 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
                                   afi_t afi, safi_t safi,
-                                  enum bgp_show_type type, uint8_t use_json)
+                                  enum bgp_show_type type, bool use_json)
 {
        /* labeled-unicast routes live in the unicast table */
        if (safi == SAFI_LABELED_UNICAST)
@@ -10576,14 +10643,17 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed,
        safi_t safi = SAFI_UNICAST;
        struct bgp *bgp = NULL;
        int idx = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       return bgp_show(vty, bgp, afi, safi,
-                       bgp_show_type_detail, NULL, use_json(argc, argv));
+       return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
 }
 
 DEFUN (show_ip_bgp_neighbor_routes,
@@ -10611,18 +10681,17 @@ DEFUN (show_ip_bgp_neighbor_routes,
        safi_t safi = SAFI_UNICAST;
        struct peer *peer;
        enum bgp_show_type sh_type = bgp_show_type_neighbor;
-
        int idx = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        /* neighbors <A.B.C.D|X:X::X:X|WORD> */
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
@@ -10718,12 +10787,12 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str,
 
        /* Get BGP distance node. */
        rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
-       if (rn->info) {
-               bdistance = rn->info;
+       bdistance = bgp_distance_get_node(rn);
+       if (bdistance)
                bgp_unlock_node(rn);
-       else {
+       else {
                bdistance = bgp_distance_new();
-               rn->info = bdistance;
+               bgp_distance_set_node_info(rn, bdistance);
        }
 
        /* Set distance value. */
@@ -10768,7 +10837,7 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       bdistance = rn->info;
+       bdistance = bgp_distance_get_node(rn);
        distance = atoi(distance_str);
 
        if (bdistance->distance != distance) {
@@ -10807,7 +10876,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
        sockunion2hostprefix(&peer->su, &q);
        rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
        if (rn) {
-               bdistance = rn->info;
+               bdistance = bgp_distance_get_node(rn);
                bgp_unlock_node(rn);
 
                if (bdistance->access_list) {
@@ -10822,7 +10891,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
        /* Backdoor check. */
        rn = bgp_node_lookup(bgp->route[afi][safi], p);
        if (rn) {
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
                bgp_unlock_node(rn);
 
                if (bgp_static->backdoor) {
@@ -11237,7 +11306,8 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       if ((bgp_static = rn->info) == NULL)
+                       bgp_static = bgp_static_get_node_info(rn);
+                       if (bgp_static == NULL)
                                continue;
 
                        p = &rn->p;
@@ -11286,7 +11356,8 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       if ((bgp_static = rn->info) == NULL)
+                       bgp_static = bgp_static_get_node_info(rn);
+                       if (bgp_static == NULL)
                                continue;
 
                        char *macrouter = NULL;
@@ -11361,7 +11432,8 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Network configuration. */
        for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               if ((bgp_static = rn->info) == NULL)
+               bgp_static = bgp_static_get_node_info(rn);
+               if (bgp_static == NULL)
                        continue;
 
                p = &rn->p;
@@ -11407,7 +11479,8 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Aggregate-address configuration. */
        for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               if ((bgp_aggregate = rn->info) == NULL)
+               bgp_aggregate = bgp_aggregate_get_node_info(rn);
+               if (bgp_aggregate == NULL)
                        continue;
 
                p = &rn->p;
@@ -11457,8 +11530,9 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
        }
 
        for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
-            rn = bgp_route_next(rn))
-               if ((bdistance = rn->info) != NULL) {
+            rn = bgp_route_next(rn)) {
+               bdistance = bgp_distance_get_node(rn);
+               if (bdistance != NULL) {
                        char buf[PREFIX_STRLEN];
 
                        vty_out(vty, "  distance %d %s %s\n",
@@ -11467,6 +11541,7 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
                                bdistance->access_list ? bdistance->access_list
                                                       : "");
                }
+       }
 }
 
 /* Allocate routing table structure and install commands. */