diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index ff655048a8..9f1fe64813 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1307,8 +1307,12 @@ static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock) } bt->cnt_accept++; - setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); - setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + if (setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) + flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt SO_KEEPALIVE: %s(%d)", + bmp_sock, safe_strerror(errno), errno); + if (setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) + flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt TCP_NODELAY: %s(%d)", + bmp_sock, safe_strerror(errno), errno); zlog_info("bmp[%s] connection established", buf); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index bc0b98517e..e37581c8e2 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3023,8 +3023,7 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, * SVI comes up with MAC and stored in hash, triggers * bgp_mac_rescan_all_evpn_tables. */ - if (pi->attr && - memcmp(&bgp_vrf->rmac, &pi->attr->rmac, ETH_ALEN) == 0) { + if (memcmp(&bgp_vrf->rmac, &pi->attr->rmac, ETH_ALEN) == 0) { if (bgp_debug_update(pi->peer, NULL, NULL, 1)) { char buf1[PREFIX_STRLEN]; char attr_str[BUFSIZ] = {0}; diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 2d6523ed31..80384c12c6 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -294,7 +294,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, } if (!path) return; - if (path->attr && path->attr->ecommunity) { + if (path->attr->ecommunity) { /* Print attribute */ attr = path->attr; s = ecommunity_ecom2str(attr->ecommunity, diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 2d50d1c9ea..83194e010a 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -706,7 +706,7 @@ int bgp_pbr_build_and_validate_entry(struct prefix *p, if (ret < 0) return -1; /* extract actiosn from flowspec ecom list */ - if (path && path->attr && path->attr->ecommunity) { + if (path && path->attr->ecommunity) { ecom = path->attr->ecommunity; for (i = 0; i < ecom->size; i++) { ecom_eval = (struct ecommunity_val *) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1161480548..f61d397c51 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -249,8 +249,7 @@ struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi) /* Free bgp route information. */ static void bgp_path_info_free(struct bgp_path_info *path) { - if (path->attr) - bgp_attr_unintern(&path->attr); + bgp_attr_unintern(&path->attr); bgp_unlink_nexthop(path); bgp_path_info_extra_free(&path->extra); @@ -2939,17 +2938,9 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, if (afi != AFI_L2VPN) return true; - if (!path->attr) { - memset(&temp, 0, sizeof(temp)); - path_eth_s_id = &temp.esi; - path_gw_ip = &temp.ip; - if (eth_s_id == NULL && gw_ip == NULL) - return true; - } else { - path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id); - path_gw_ip = &(path->attr->evpn_overlay.gw_ip); - } + path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id); + path_gw_ip = &(path->attr->evpn_overlay.gw_ip); if (gw_ip == NULL) { memset(&temp, 0, sizeof(temp)); @@ -3165,8 +3156,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id, goto filtered; } - if (pi && pi->attr && - pi->attr->rmap_table_id != new_attr.rmap_table_id) { + if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) /* remove from RIB previous entry */ bgp_zebra_withdraw(p, pi, bgp, safi); @@ -6719,6 +6709,10 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Make default attribute. */ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + /* + * This must not be NULL to satisfy Coverity SA + */ + assert(attr.aspath); switch (nhtype) { case NEXTHOP_TYPE_IFINDEX: @@ -7121,14 +7115,6 @@ void route_vty_out(struct vty *vty, struct prefix *p, /* Print attribute */ attr = path->attr; - if (!attr) { - if (json_paths) - json_object_array_add(json_paths, json_path); - else - vty_out(vty, "\n"); - - return; - } /* * If vrf id of nexthop is different from that of prefix, @@ -7713,64 +7699,56 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, /* Print attribute */ attr = path->attr; - if (attr) { - if (((p->family == AF_INET) - && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) - || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) - || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP - || safi == SAFI_EVPN) { - if (json) - json_object_string_add( - json_out, "mpNexthopGlobalIn", - inet_ntoa( - attr->mp_nexthop_global_in)); - else - vty_out(vty, "%-16s", - inet_ntoa( - attr->mp_nexthop_global_in)); - } else { - if (json) - json_object_string_add( - json_out, "nexthop", - inet_ntoa(attr->nexthop)); - else - vty_out(vty, "%-16s", - inet_ntoa(attr->nexthop)); - } - } else if (((p->family == AF_INET6) - && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) - || (safi == SAFI_EVPN - && BGP_ATTR_NEXTHOP_AFI_IP6(attr)) - || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - char buf_a[512]; - if (attr->mp_nexthop_len - == BGP_ATTR_NHLEN_IPV6_GLOBAL) { - if (json) - json_object_string_add( - json_out, "mpNexthopGlobalIn", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_global, - buf_a, sizeof(buf_a))); - else - vty_out(vty, "%s", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_global, - buf_a, sizeof(buf_a))); - } else if (attr->mp_nexthop_len - == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { - snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)", - &attr->mp_nexthop_global, - &attr->mp_nexthop_local); - if (json) - json_object_string_add( - json_out, - "mpNexthopGlobalLocal", buf_a); - else - vty_out(vty, "%s", buf_a); - } + if (((p->family == AF_INET) + && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) + || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP + || safi == SAFI_EVPN) { + if (json) + json_object_string_add( + json_out, "mpNexthopGlobalIn", + inet_ntoa(attr->mp_nexthop_global_in)); + else + vty_out(vty, "%-16s", + inet_ntoa(attr->mp_nexthop_global_in)); + } else { + if (json) + json_object_string_add( + json_out, "nexthop", + inet_ntoa(attr->nexthop)); + else + vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); + } + } else if (((p->family == AF_INET6) + && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) + || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + char buf_a[512]; + + if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) { + if (json) + json_object_string_add( + json_out, "mpNexthopGlobalIn", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, + buf_a, sizeof(buf_a))); + else + vty_out(vty, "%s", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, + buf_a, sizeof(buf_a))); + } else if (attr->mp_nexthop_len + == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { + snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)", + &attr->mp_nexthop_global, + &attr->mp_nexthop_local); + if (json) + json_object_string_add(json_out, + "mpNexthopGlobalLocal", + buf_a); + else + vty_out(vty, "%s", buf_a); } } @@ -7817,101 +7795,96 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p, /* Print attribute */ attr = path->attr; - if (attr) { - char buf1[BUFSIZ]; - int af = NEXTHOP_FAMILY(attr->mp_nexthop_len); - - switch (af) { - case AF_INET: - inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ); - if (!json_path) { - vty_out(vty, "%-16s", buf); - } else { - json_object_string_add(json_nexthop, "ip", buf); - - json_object_string_add(json_nexthop, "afi", - "ipv4"); - - json_object_object_add(json_path, "nexthop", - json_nexthop); - } - break; - case AF_INET6: - inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ); - inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ); - if (!json_path) { - vty_out(vty, "%s(%s)", buf, buf1); - } else { - json_object_string_add(json_nexthop, - "ipv6Global", buf); - - json_object_string_add(json_nexthop, - "ipv6LinkLocal", buf1); - - json_object_string_add(json_nexthop, "afi", - "ipv6"); - - json_object_object_add(json_path, "nexthop", - json_nexthop); - } - break; - default: - if (!json_path) { - vty_out(vty, "?"); - } else { - json_object_string_add(json_nexthop, "Error", - "Unsupported address-family"); - } - } - - char *str = esi2str(&(attr->evpn_overlay.eth_s_id)); - - if (!json_path) - vty_out(vty, "%s", str); - else - json_object_string_add(json_overlay, "esi", str); - - XFREE(MTYPE_TMP, str); - - if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) { - inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), - buf, BUFSIZ); - } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) { - inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), - buf, BUFSIZ); - } - - if (!json_path) - vty_out(vty, "/%s", buf); - else - json_object_string_add(json_overlay, "gw", buf); - - if (attr->ecommunity) { - char *mac = NULL; - struct ecommunity_val *routermac = ecommunity_lookup( - attr->ecommunity, ECOMMUNITY_ENCODE_EVPN, - ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC); - if (routermac) - mac = ecom_mac2str((char *)routermac->val); - if (mac) { - if (!json_path) { - vty_out(vty, "/%s", (char *)mac); - } else { - json_object_string_add(json_overlay, - "rmac", mac); - } - XFREE(MTYPE_TMP, mac); - } - } + char buf1[BUFSIZ]; + int af = NEXTHOP_FAMILY(attr->mp_nexthop_len); + switch (af) { + case AF_INET: + inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ); if (!json_path) { - vty_out(vty, "\n"); + vty_out(vty, "%-16s", buf); } else { - json_object_object_add(json_path, "overlay", - json_overlay); + json_object_string_add(json_nexthop, "ip", buf); - json_object_array_add(json_paths, json_path); + json_object_string_add(json_nexthop, "afi", "ipv4"); + + json_object_object_add(json_path, "nexthop", + json_nexthop); } + break; + case AF_INET6: + inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ); + inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ); + if (!json_path) { + vty_out(vty, "%s(%s)", buf, buf1); + } else { + json_object_string_add(json_nexthop, "ipv6Global", buf); + + json_object_string_add(json_nexthop, "ipv6LinkLocal", + buf1); + + json_object_string_add(json_nexthop, "afi", "ipv6"); + + json_object_object_add(json_path, "nexthop", + json_nexthop); + } + break; + default: + if (!json_path) { + vty_out(vty, "?"); + } else { + json_object_string_add(json_nexthop, "Error", + "Unsupported address-family"); + } + } + + char *str = esi2str(&(attr->evpn_overlay.eth_s_id)); + + if (!json_path) + vty_out(vty, "%s", str); + else + json_object_string_add(json_overlay, "esi", str); + + XFREE(MTYPE_TMP, str); + + if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) { + inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf, + BUFSIZ); + } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) { + inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf, + BUFSIZ); + } + + if (!json_path) + vty_out(vty, "/%s", buf); + else + json_object_string_add(json_overlay, "gw", buf); + + if (attr->ecommunity) { + char *mac = NULL; + struct ecommunity_val *routermac = ecommunity_lookup( + attr->ecommunity, ECOMMUNITY_ENCODE_EVPN, + ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC); + + if (routermac) + mac = ecom_mac2str((char *)routermac->val); + if (mac) { + if (!json_path) { + vty_out(vty, "/%s", (char *)mac); + } else { + json_object_string_add(json_overlay, "rmac", + mac); + } + XFREE(MTYPE_TMP, mac); + } + } + + if (!json_path) { + vty_out(vty, "\n"); + } else { + json_object_object_add(json_path, "overlay", json_overlay); + + json_object_array_add(json_paths, json_path); } } @@ -7958,23 +7931,23 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p, /* Print attribute */ attr = path->attr; - if (attr) { - /* Print aspath */ - if (attr->aspath) { - if (use_json) - json_object_string_add(json, "asPath", - attr->aspath->str); - else - aspath_print_vty(vty, "%s", attr->aspath, " "); - } - /* Print origin */ + /* Print aspath */ + if (attr->aspath) { if (use_json) - json_object_string_add(json, "origin", - bgp_origin_str[attr->origin]); + json_object_string_add(json, "asPath", + attr->aspath->str); else - vty_out(vty, "%s", bgp_origin_str[attr->origin]); + aspath_print_vty(vty, "%s", attr->aspath, " "); } + + /* Print origin */ + if (use_json) + json_object_string_add(json, "origin", + bgp_origin_str[attr->origin]); + else + vty_out(vty, "%s", bgp_origin_str[attr->origin]); + if (!use_json) vty_out(vty, "\n"); } @@ -8053,23 +8026,23 @@ static void flap_route_vty_out(struct vty *vty, struct prefix *p, /* Print attribute */ attr = path->attr; - if (attr) { - /* Print aspath */ - if (attr->aspath) { - if (use_json) - json_object_string_add(json, "asPath", - attr->aspath->str); - else - aspath_print_vty(vty, "%s", attr->aspath, " "); - } - /* Print origin */ + /* Print aspath */ + if (attr->aspath) { if (use_json) - json_object_string_add(json, "origin", - bgp_origin_str[attr->origin]); + json_object_string_add(json, "asPath", + attr->aspath->str); else - vty_out(vty, "%s", bgp_origin_str[attr->origin]); + aspath_print_vty(vty, "%s", attr->aspath, " "); } + + /* Print origin */ + if (use_json) + json_object_string_add(json, "origin", + bgp_origin_str[attr->origin]); + else + vty_out(vty, "%s", bgp_origin_str[attr->origin]); + if (!use_json) vty_out(vty, "\n"); } @@ -8295,819 +8268,739 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, attr = path->attr; - if (attr) { - /* Line1 display AS-path, Aggregator */ - if (attr->aspath) { - if (json_paths) { - if (!attr->aspath->json) - aspath_str_update(attr->aspath, true); - json_object_lock(attr->aspath->json); - json_object_object_add(json_path, "aspath", - attr->aspath->json); - } else { - if (attr->aspath->segments) - aspath_print_vty(vty, " %s", - attr->aspath, ""); - else - vty_out(vty, " Local"); - } - } - - if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) { - if (json_paths) - json_object_boolean_true_add(json_path, - "removed"); - else - vty_out(vty, ", (removed)"); - } - - if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) { - if (json_paths) - json_object_boolean_true_add(json_path, - "stale"); - else - vty_out(vty, ", (stale)"); - } - - if (CHECK_FLAG(attr->flag, - ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) { - if (json_paths) { - json_object_int_add(json_path, "aggregatorAs", - attr->aggregator_as); - json_object_string_add( - json_path, "aggregatorId", - inet_ntoa(attr->aggregator_addr)); - } else { - vty_out(vty, ", (aggregated by %u %s)", - attr->aggregator_as, - inet_ntoa(attr->aggregator_addr)); - } - } - - if (CHECK_FLAG(path->peer->af_flags[afi][safi], - PEER_FLAG_REFLECTOR_CLIENT)) { - if (json_paths) - json_object_boolean_true_add( - json_path, "rxedFromRrClient"); - else - vty_out(vty, ", (Received from a RR-client)"); - } - - if (CHECK_FLAG(path->peer->af_flags[afi][safi], - PEER_FLAG_RSERVER_CLIENT)) { - if (json_paths) - json_object_boolean_true_add( - json_path, "rxedFromRsClient"); - else - vty_out(vty, ", (Received from a RS-client)"); - } - - if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) { - if (json_paths) - json_object_boolean_true_add( - json_path, "dampeningHistoryEntry"); - else - vty_out(vty, ", (history entry)"); - } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) { - if (json_paths) - json_object_boolean_true_add( - json_path, "dampeningSuppressed"); - else - vty_out(vty, ", (suppressed due to dampening)"); - } - - if (!json_paths) - vty_out(vty, "\n"); - - /* Line2 display Next-hop, Neighbor, Router-id */ - /* Display the nexthop */ - if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET - || bn->p.family == AF_EVPN) - && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP - || safi == SAFI_EVPN - || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP - || safi == SAFI_EVPN) { - if (json_paths) - json_object_string_add( - json_nexthop_global, - nexthop_fqdn ? "fqdn" : "ip", - nexthop_fqdn - ? nexthop_fqdn - : inet_ntoa( - attr->mp_nexthop_global_in)); - else - vty_out(vty, " %s", - nexthop_fqdn - ? nexthop_fqdn - : inet_ntoa( - attr->mp_nexthop_global_in)); - } else { - if (json_paths) - json_object_string_add( - json_nexthop_global, - nexthop_fqdn ? "fqdn" : "ip", - nexthop_fqdn - ? nexthop_fqdn - : inet_ntoa( - attr->nexthop)); - else - vty_out(vty, " %s", - nexthop_fqdn - ? nexthop_fqdn - : inet_ntoa( - attr->nexthop)); - } - - if (json_paths) - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); + /* Line1 display AS-path, Aggregator */ + if (attr->aspath) { + if (json_paths) { + if (!attr->aspath->json) + aspath_str_update(attr->aspath, true); + json_object_lock(attr->aspath->json); + json_object_object_add(json_path, "aspath", + attr->aspath->json); } else { - if (json_paths) { + if (attr->aspath->segments) + aspath_print_vty(vty, " %s", attr->aspath, ""); + else + vty_out(vty, " Local"); + } + } + + if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) { + if (json_paths) + json_object_boolean_true_add(json_path, "removed"); + else + vty_out(vty, ", (removed)"); + } + + if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) { + if (json_paths) + json_object_boolean_true_add(json_path, "stale"); + else + vty_out(vty, ", (stale)"); + } + + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) { + if (json_paths) { + json_object_int_add(json_path, "aggregatorAs", + attr->aggregator_as); + json_object_string_add( + json_path, "aggregatorId", + inet_ntoa(attr->aggregator_addr)); + } else { + vty_out(vty, ", (aggregated by %u %s)", + attr->aggregator_as, + inet_ntoa(attr->aggregator_addr)); + } + } + + if (CHECK_FLAG(path->peer->af_flags[afi][safi], + PEER_FLAG_REFLECTOR_CLIENT)) { + if (json_paths) + json_object_boolean_true_add(json_path, + "rxedFromRrClient"); + else + vty_out(vty, ", (Received from a RR-client)"); + } + + if (CHECK_FLAG(path->peer->af_flags[afi][safi], + PEER_FLAG_RSERVER_CLIENT)) { + if (json_paths) + json_object_boolean_true_add(json_path, + "rxedFromRsClient"); + else + vty_out(vty, ", (Received from a RS-client)"); + } + + if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) { + if (json_paths) + json_object_boolean_true_add(json_path, + "dampeningHistoryEntry"); + else + vty_out(vty, ", (history entry)"); + } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) { + if (json_paths) + json_object_boolean_true_add(json_path, + "dampeningSuppressed"); + else + vty_out(vty, ", (suppressed due to dampening)"); + } + + if (!json_paths) + vty_out(vty, "\n"); + + /* Line2 display Next-hop, Neighbor, Router-id */ + /* Display the nexthop */ + if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET + || bn->p.family == AF_EVPN) + && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN + || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP + || safi == SAFI_EVPN) { + if (json_paths) json_object_string_add( json_nexthop_global, nexthop_fqdn ? "fqdn" : "ip", nexthop_fqdn ? nexthop_fqdn - : inet_ntop( - AF_INET6, - &attr->mp_nexthop_global, - buf, - INET6_ADDRSTRLEN)); - json_object_string_add(json_nexthop_global, - "afi", "ipv6"); - json_object_string_add(json_nexthop_global, - "scope", "global"); - } else { + : inet_ntoa( + attr->mp_nexthop_global_in)); + else vty_out(vty, " %s", nexthop_fqdn ? nexthop_fqdn - : inet_ntop( - AF_INET6, - &attr->mp_nexthop_global, - buf, - INET6_ADDRSTRLEN)); - } - } - - /* Display the IGP cost or 'inaccessible' */ - if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) { - if (json_paths) - json_object_boolean_false_add( - json_nexthop_global, "accessible"); - else - vty_out(vty, " (inaccessible)"); + : inet_ntoa( + attr->mp_nexthop_global_in)); } else { - if (path->extra && path->extra->igpmetric) { - if (json_paths) - json_object_int_add( - json_nexthop_global, "metric", - path->extra->igpmetric); - else - vty_out(vty, " (metric %u)", - path->extra->igpmetric); - } - - /* IGP cost is 0, display this only for json */ - else { - if (json_paths) - json_object_int_add(json_nexthop_global, - "metric", 0); - } - - if (json_paths) - json_object_boolean_true_add( - json_nexthop_global, "accessible"); - } - - /* Display peer "from" output */ - /* This path was originated locally */ - if (path->peer == bgp->peer_self) { - - if (safi == SAFI_EVPN - || (bn->p.family == AF_INET - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - if (json_paths) - json_object_string_add( - json_peer, "peerId", "0.0.0.0"); - else - vty_out(vty, " from 0.0.0.0 "); - } else { - if (json_paths) - json_object_string_add(json_peer, - "peerId", "::"); - else - vty_out(vty, " from :: "); - } - if (json_paths) json_object_string_add( - json_peer, "routerId", - inet_ntoa(bgp->router_id)); - else - vty_out(vty, "(%s)", inet_ntoa(bgp->router_id)); - } - - /* We RXed this path from one of our peers */ - else { - - if (json_paths) { - json_object_string_add( - json_peer, "peerId", - sockunion2str(&path->peer->su, buf, - SU_ADDRSTRLEN)); - json_object_string_add( - json_peer, "routerId", - inet_ntop(AF_INET, - &path->peer->remote_id, buf1, - sizeof(buf1))); - - if (path->peer->hostname) - json_object_string_add( - json_peer, "hostname", - path->peer->hostname); - - if (path->peer->domainname) - json_object_string_add( - json_peer, "domainname", - path->peer->domainname); - - if (path->peer->conf_if) - json_object_string_add( - json_peer, "interface", - path->peer->conf_if); - } else { - if (path->peer->conf_if) { - if (path->peer->hostname - && bgp_flag_check( - path->peer->bgp, - BGP_FLAG_SHOW_HOSTNAME)) - vty_out(vty, " from %s(%s)", - path->peer->hostname, - path->peer->conf_if); - else - vty_out(vty, " from %s", - path->peer->conf_if); - } else { - if (path->peer->hostname - && bgp_flag_check( - path->peer->bgp, - BGP_FLAG_SHOW_HOSTNAME)) - vty_out(vty, " from %s(%s)", - path->peer->hostname, - path->peer->host); - else - vty_out(vty, " from %s", - sockunion2str( - &path->peer->su, - buf, - SU_ADDRSTRLEN)); - } - - if (attr->flag - & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) - vty_out(vty, " (%s)", - inet_ntoa(attr->originator_id)); - else - vty_out(vty, " (%s)", - inet_ntop( - AF_INET, - &path->peer->remote_id, - buf1, sizeof(buf1))); - } - } - - /* - * Note when vrfid of nexthop is different from that of prefix - */ - if (path->extra && path->extra->bgp_orig) { - vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id; - - if (json_paths) { - const char *vn; - - if (path->extra->bgp_orig->inst_type - == BGP_INSTANCE_TYPE_DEFAULT) - - vn = VRF_DEFAULT_NAME; - else - vn = path->extra->bgp_orig->name; - - json_object_string_add(json_path, "nhVrfName", - vn); - - if (nexthop_vrfid == VRF_UNKNOWN) { - json_object_int_add(json_path, - "nhVrfId", -1); - } else { - json_object_int_add(json_path, - "nhVrfId", (int)nexthop_vrfid); - } - } else { - if (nexthop_vrfid == VRF_UNKNOWN) - vty_out(vty, " vrf ?"); - else - vty_out(vty, " vrf %u", nexthop_vrfid); - } - } - - if (nexthop_self) { - if (json_paths) { - json_object_boolean_true_add(json_path, - "announceNexthopSelf"); - } else { - vty_out(vty, " announce-nh-self"); - } - } - - if (!json_paths) - vty_out(vty, "\n"); - - /* display the link-local nexthop */ - if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { - if (json_paths) { - json_nexthop_ll = json_object_new_object(); - json_object_string_add( - json_nexthop_ll, + json_nexthop_global, nexthop_fqdn ? "fqdn" : "ip", nexthop_fqdn ? nexthop_fqdn - : inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf, - INET6_ADDRSTRLEN)); - json_object_string_add(json_nexthop_ll, "afi", - "ipv6"); - json_object_string_add(json_nexthop_ll, "scope", - "link-local"); - - json_object_boolean_true_add(json_nexthop_ll, - "accessible"); - - if (!attr->mp_nexthop_prefer_global) - json_object_boolean_true_add( - json_nexthop_ll, "used"); - else - json_object_boolean_true_add( - json_nexthop_global, "used"); - } else { - vty_out(vty, " (%s) %s\n", - inet_ntop(AF_INET6, - &attr->mp_nexthop_local, buf, - INET6_ADDRSTRLEN), - attr->mp_nexthop_prefer_global - ? "(prefer-global)" - : "(used)"); - } + : inet_ntoa(attr->nexthop)); + else + vty_out(vty, " %s", + nexthop_fqdn + ? nexthop_fqdn + : inet_ntoa(attr->nexthop)); } - /* If we do not have a link-local nexthop then we must flag the - global as "used" */ + + if (json_paths) + json_object_string_add(json_nexthop_global, "afi", + "ipv4"); + } else { + if (json_paths) { + json_object_string_add( + json_nexthop_global, + nexthop_fqdn ? "fqdn" : "ip", + nexthop_fqdn + ? nexthop_fqdn + : inet_ntop(AF_INET6, + &attr->mp_nexthop_global, + buf, INET6_ADDRSTRLEN)); + json_object_string_add(json_nexthop_global, "afi", + "ipv6"); + json_object_string_add(json_nexthop_global, "scope", + "global"); + } else { + vty_out(vty, " %s", + nexthop_fqdn + ? nexthop_fqdn + : inet_ntop(AF_INET6, + &attr->mp_nexthop_global, + buf, INET6_ADDRSTRLEN)); + } + } + + /* Display the IGP cost or 'inaccessible' */ + if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) { + if (json_paths) + json_object_boolean_false_add(json_nexthop_global, + "accessible"); + else + vty_out(vty, " (inaccessible)"); + } else { + if (path->extra && path->extra->igpmetric) { + if (json_paths) + json_object_int_add(json_nexthop_global, + "metric", + path->extra->igpmetric); + else + vty_out(vty, " (metric %u)", + path->extra->igpmetric); + } + + /* IGP cost is 0, display this only for json */ else { if (json_paths) + json_object_int_add(json_nexthop_global, + "metric", 0); + } + + if (json_paths) + json_object_boolean_true_add(json_nexthop_global, + "accessible"); + } + + /* Display peer "from" output */ + /* This path was originated locally */ + if (path->peer == bgp->peer_self) { + + if (safi == SAFI_EVPN + || (bn->p.family == AF_INET + && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + if (json_paths) + json_object_string_add(json_peer, "peerId", + "0.0.0.0"); + else + vty_out(vty, " from 0.0.0.0 "); + } else { + if (json_paths) + json_object_string_add(json_peer, "peerId", + "::"); + else + vty_out(vty, " from :: "); + } + + if (json_paths) + json_object_string_add(json_peer, "routerId", + inet_ntoa(bgp->router_id)); + else + vty_out(vty, "(%s)", inet_ntoa(bgp->router_id)); + } + + /* We RXed this path from one of our peers */ + else { + + if (json_paths) { + json_object_string_add(json_peer, "peerId", + sockunion2str(&path->peer->su, + buf, + SU_ADDRSTRLEN)); + json_object_string_add(json_peer, "routerId", + inet_ntop(AF_INET, + &path->peer->remote_id, + buf1, sizeof(buf1))); + + if (path->peer->hostname) + json_object_string_add(json_peer, "hostname", + path->peer->hostname); + + if (path->peer->domainname) + json_object_string_add(json_peer, "domainname", + path->peer->domainname); + + if (path->peer->conf_if) + json_object_string_add(json_peer, "interface", + path->peer->conf_if); + } else { + if (path->peer->conf_if) { + if (path->peer->hostname + && bgp_flag_check(path->peer->bgp, + BGP_FLAG_SHOW_HOSTNAME)) + vty_out(vty, " from %s(%s)", + path->peer->hostname, + path->peer->conf_if); + else + vty_out(vty, " from %s", + path->peer->conf_if); + } else { + if (path->peer->hostname + && bgp_flag_check(path->peer->bgp, + BGP_FLAG_SHOW_HOSTNAME)) + vty_out(vty, " from %s(%s)", + path->peer->hostname, + path->peer->host); + else + vty_out(vty, " from %s", + sockunion2str(&path->peer->su, + buf, + SU_ADDRSTRLEN)); + } + + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) + vty_out(vty, " (%s)", + inet_ntoa(attr->originator_id)); + else + vty_out(vty, " (%s)", + inet_ntop(AF_INET, + &path->peer->remote_id, buf1, + sizeof(buf1))); + } + } + + /* + * Note when vrfid of nexthop is different from that of prefix + */ + if (path->extra && path->extra->bgp_orig) { + vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id; + + if (json_paths) { + const char *vn; + + if (path->extra->bgp_orig->inst_type + == BGP_INSTANCE_TYPE_DEFAULT) + vn = VRF_DEFAULT_NAME; + else + vn = path->extra->bgp_orig->name; + + json_object_string_add(json_path, "nhVrfName", vn); + + if (nexthop_vrfid == VRF_UNKNOWN) { + json_object_int_add(json_path, "nhVrfId", -1); + } else { + json_object_int_add(json_path, "nhVrfId", + (int)nexthop_vrfid); + } + } else { + if (nexthop_vrfid == VRF_UNKNOWN) + vty_out(vty, " vrf ?"); + else + vty_out(vty, " vrf %u", nexthop_vrfid); + } + } + + if (nexthop_self) { + if (json_paths) { + json_object_boolean_true_add(json_path, + "announceNexthopSelf"); + } else { + vty_out(vty, " announce-nh-self"); + } + } + + if (!json_paths) + vty_out(vty, "\n"); + + /* display the link-local nexthop */ + if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { + if (json_paths) { + json_nexthop_ll = json_object_new_object(); + json_object_string_add( + json_nexthop_ll, nexthop_fqdn ? "fqdn" : "ip", + nexthop_fqdn + ? nexthop_fqdn + : inet_ntop(AF_INET6, + &attr->mp_nexthop_local, + buf, INET6_ADDRSTRLEN)); + json_object_string_add(json_nexthop_ll, "afi", "ipv6"); + json_object_string_add(json_nexthop_ll, "scope", + "link-local"); + + json_object_boolean_true_add(json_nexthop_ll, + "accessible"); + + if (!attr->mp_nexthop_prefer_global) + json_object_boolean_true_add(json_nexthop_ll, + "used"); + else json_object_boolean_true_add( json_nexthop_global, "used"); + } else { + vty_out(vty, " (%s) %s\n", + inet_ntop(AF_INET6, &attr->mp_nexthop_local, + buf, INET6_ADDRSTRLEN), + attr->mp_nexthop_prefer_global + ? "(prefer-global)" + : "(used)"); + } + } + /* If we do not have a link-local nexthop then we must flag the + global as "used" */ + else { + if (json_paths) + json_object_boolean_true_add(json_nexthop_global, + "used"); + } + + /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, + * Int/Ext/Local, Atomic, best */ + if (json_paths) + json_object_string_add(json_path, "origin", + bgp_origin_long_str[attr->origin]); + else + vty_out(vty, " Origin %s", + bgp_origin_long_str[attr->origin]); + + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { + if (json_paths) { + /* + * Adding "metric" field to match with + * corresponding CLI. "med" will be + * deprecated in future. + */ + json_object_int_add(json_path, "med", attr->med); + json_object_int_add(json_path, "metric", attr->med); + } else + vty_out(vty, ", metric %u", attr->med); + } + + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + if (json_paths) + json_object_int_add(json_path, "localpref", + attr->local_pref); + else + vty_out(vty, ", localpref %u", attr->local_pref); + } + + if (attr->weight != 0) { + if (json_paths) + json_object_int_add(json_path, "weight", attr->weight); + else + vty_out(vty, ", weight %u", attr->weight); + } + + if (attr->tag != 0) { + if (json_paths) + json_object_int_add(json_path, "tag", attr->tag); + else + vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag); + } + + if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) { + if (json_paths) + json_object_boolean_false_add(json_path, "valid"); + else + vty_out(vty, ", invalid"); + } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) { + if (json_paths) + json_object_boolean_true_add(json_path, "valid"); + else + vty_out(vty, ", valid"); + } + + if (path->peer != bgp->peer_self) { + if (path->peer->as == path->peer->local_as) { + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) { + if (json_paths) + json_object_string_add( + json_peer, "type", + "confed-internal"); + else + vty_out(vty, ", confed-internal"); + } else { + if (json_paths) + json_object_string_add( + json_peer, "type", "internal"); + else + vty_out(vty, ", internal"); + } + } else { + if (bgp_confederation_peers_check(bgp, + path->peer->as)) { + if (json_paths) + json_object_string_add( + json_peer, "type", + "confed-external"); + else + vty_out(vty, ", confed-external"); + } else { + if (json_paths) + json_object_string_add( + json_peer, "type", "external"); + else + vty_out(vty, ", external"); + } + } + } else if (path->sub_type == BGP_ROUTE_AGGREGATE) { + if (json_paths) { + json_object_boolean_true_add(json_path, "aggregated"); + json_object_boolean_true_add(json_path, "local"); + } else { + vty_out(vty, ", aggregated, local"); + } + } else if (path->type != ZEBRA_ROUTE_BGP) { + if (json_paths) + json_object_boolean_true_add(json_path, "sourced"); + else + vty_out(vty, ", sourced"); + } else { + if (json_paths) { + json_object_boolean_true_add(json_path, "sourced"); + json_object_boolean_true_add(json_path, "local"); + } else { + vty_out(vty, ", sourced, local"); + } + } + + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) { + if (json_paths) + json_object_boolean_true_add(json_path, + "atomicAggregate"); + else + vty_out(vty, ", atomic-aggregate"); + } + + if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH) + || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED) + && bgp_path_info_mpath_count(path))) { + if (json_paths) + json_object_boolean_true_add(json_path, "multipath"); + else + vty_out(vty, ", multipath"); + } + + // Mark the bestpath(s) + if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) { + first_as = aspath_get_first_as(attr->aspath); + + if (json_paths) { + if (!json_bestpath) + json_bestpath = json_object_new_object(); + json_object_int_add(json_bestpath, "bestpathFromAs", + first_as); + } else { + if (first_as) + vty_out(vty, ", bestpath-from-AS %u", first_as); + else + vty_out(vty, ", bestpath-from-AS Local"); + } + } + + if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) { + if (json_paths) { + if (!json_bestpath) + json_bestpath = json_object_new_object(); + json_object_boolean_true_add(json_bestpath, "overall"); + json_object_string_add( + json_bestpath, "selectionReason", + bgp_path_selection_reason2str(bn->reason)); + } else { + vty_out(vty, ", best"); + vty_out(vty, " (%s)", + bgp_path_selection_reason2str(bn->reason)); + } + } + + if (json_bestpath) + json_object_object_add(json_path, "bestpath", json_bestpath); + + if (!json_paths) + vty_out(vty, "\n"); + + /* Line 4 display Community */ + if (attr->community) { + if (json_paths) { + if (!attr->community->json) + community_str(attr->community, true); + json_object_lock(attr->community->json); + json_object_object_add(json_path, "community", + attr->community->json); + } else { + vty_out(vty, " Community: %s\n", + attr->community->str); + } + } + + /* Line 5 display Extended-community */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) { + if (json_paths) { + json_ext_community = json_object_new_object(); + json_object_string_add(json_ext_community, "string", + attr->ecommunity->str); + json_object_object_add(json_path, "extendedCommunity", + json_ext_community); + } else { + vty_out(vty, " Extended Community: %s\n", + attr->ecommunity->str); + } + } + + /* Line 6 display Large community */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) { + if (json_paths) { + if (!attr->lcommunity->json) + lcommunity_str(attr->lcommunity, true); + json_object_lock(attr->lcommunity->json); + json_object_object_add(json_path, "largeCommunity", + attr->lcommunity->json); + } else { + vty_out(vty, " Large Community: %s\n", + attr->lcommunity->str); + } + } + + /* Line 7 display Originator, Cluster-id */ + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) + || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) { + if (json_paths) + json_object_string_add( + json_path, "originatorId", + inet_ntoa(attr->originator_id)); + else + vty_out(vty, " Originator: %s", + inet_ntoa(attr->originator_id)); } - /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, - * Int/Ext/Local, Atomic, best */ - if (json_paths) - json_object_string_add( - json_path, "origin", - bgp_origin_long_str[attr->origin]); - else - vty_out(vty, " Origin %s", - bgp_origin_long_str[attr->origin]); + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) { + int i; - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { if (json_paths) { + json_cluster_list = json_object_new_object(); + json_cluster_list_list = + json_object_new_array(); + + for (i = 0; i < attr->cluster->length / 4; + i++) { + json_string = json_object_new_string( + inet_ntoa(attr->cluster + ->list[i])); + json_object_array_add( + json_cluster_list_list, + json_string); + } /* - * Adding "metric" field to match with - * corresponding CLI. "med" will be - * deprecated in future. + * struct cluster_list does not have + * "str" variable like aspath and community + * do. Add this someday if someone asks + * for it. + * json_object_string_add(json_cluster_list, + * "string", attr->cluster->str); */ - json_object_int_add(json_path, "med", - attr->med); - json_object_int_add(json_path, "metric", - attr->med); - } else - vty_out(vty, ", metric %u", attr->med); - } - - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { - if (json_paths) - json_object_int_add(json_path, "localpref", - attr->local_pref); - else - vty_out(vty, ", localpref %u", - attr->local_pref); - } - - if (attr->weight != 0) { - if (json_paths) - json_object_int_add(json_path, "weight", - attr->weight); - else - vty_out(vty, ", weight %u", attr->weight); - } - - if (attr->tag != 0) { - if (json_paths) - json_object_int_add(json_path, "tag", - attr->tag); - else - vty_out(vty, ", tag %" ROUTE_TAG_PRI, - attr->tag); - } - - if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) { - if (json_paths) - json_object_boolean_false_add(json_path, - "valid"); - else - vty_out(vty, ", invalid"); - } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) { - if (json_paths) - json_object_boolean_true_add(json_path, - "valid"); - else - vty_out(vty, ", valid"); - } - - if (path->peer != bgp->peer_self) { - if (path->peer->as == path->peer->local_as) { - if (CHECK_FLAG(bgp->config, - BGP_CONFIG_CONFEDERATION)) { - if (json_paths) - json_object_string_add( - json_peer, "type", - "confed-internal"); - else - vty_out(vty, - ", confed-internal"); - } else { - if (json_paths) - json_object_string_add( - json_peer, "type", - "internal"); - else - vty_out(vty, ", internal"); - } + json_object_object_add(json_cluster_list, + "list", + json_cluster_list_list); + json_object_object_add(json_path, "clusterList", + json_cluster_list); } else { - if (bgp_confederation_peers_check( - bgp, path->peer->as)) { - if (json_paths) - json_object_string_add( - json_peer, "type", - "confed-external"); - else - vty_out(vty, - ", confed-external"); - } else { - if (json_paths) - json_object_string_add( - json_peer, "type", - "external"); - else - vty_out(vty, ", external"); + vty_out(vty, ", Cluster list: "); + + for (i = 0; i < attr->cluster->length / 4; + i++) { + vty_out(vty, "%s ", + inet_ntoa(attr->cluster + ->list[i])); } } - } else if (path->sub_type == BGP_ROUTE_AGGREGATE) { - if (json_paths) { - json_object_boolean_true_add(json_path, - "aggregated"); - json_object_boolean_true_add(json_path, - "local"); - } else { - vty_out(vty, ", aggregated, local"); - } - } else if (path->type != ZEBRA_ROUTE_BGP) { - if (json_paths) - json_object_boolean_true_add(json_path, - "sourced"); - else - vty_out(vty, ", sourced"); - } else { - if (json_paths) { - json_object_boolean_true_add(json_path, - "sourced"); - json_object_boolean_true_add(json_path, - "local"); - } else { - vty_out(vty, ", sourced, local"); - } } - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) { - if (json_paths) - json_object_boolean_true_add(json_path, - "atomicAggregate"); - else - vty_out(vty, ", atomic-aggregate"); - } - - if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH) - || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED) - && bgp_path_info_mpath_count(path))) { - if (json_paths) - json_object_boolean_true_add(json_path, - "multipath"); - else - vty_out(vty, ", multipath"); - } - - // Mark the bestpath(s) - if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) { - first_as = aspath_get_first_as(attr->aspath); - - if (json_paths) { - if (!json_bestpath) - json_bestpath = - json_object_new_object(); - json_object_int_add(json_bestpath, - "bestpathFromAs", first_as); - } else { - if (first_as) - vty_out(vty, ", bestpath-from-AS %u", - first_as); - else - vty_out(vty, - ", bestpath-from-AS Local"); - } - } - - if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) { - if (json_paths) { - if (!json_bestpath) - json_bestpath = - json_object_new_object(); - json_object_boolean_true_add(json_bestpath, - "overall"); - json_object_string_add(json_bestpath, - "selectionReason", - bgp_path_selection_reason2str(bn->reason)); - } else { - vty_out(vty, ", best"); - vty_out(vty, " (%s)", - bgp_path_selection_reason2str(bn->reason)); - } - } - - if (json_bestpath) - json_object_object_add(json_path, "bestpath", - json_bestpath); - if (!json_paths) vty_out(vty, "\n"); + } - /* Line 4 display Community */ - if (attr->community) { - if (json_paths) { - if (!attr->community->json) - community_str(attr->community, true); - json_object_lock(attr->community->json); - json_object_object_add(json_path, "community", - attr->community->json); - } else { - vty_out(vty, " Community: %s\n", - attr->community->str); - } - } + if (path->extra && path->extra->damp_info) + bgp_damp_info_vty(vty, path, json_path); - /* Line 5 display Extended-community */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) { - if (json_paths) { - json_ext_community = json_object_new_object(); - json_object_string_add(json_ext_community, - "string", - attr->ecommunity->str); - json_object_object_add(json_path, - "extendedCommunity", - json_ext_community); - } else { - vty_out(vty, " Extended Community: %s\n", - attr->ecommunity->str); - } - } + /* Remote Label */ + if (path->extra && bgp_is_valid_label(&path->extra->label[0]) + && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { + mpls_label_t label = label_pton(&path->extra->label[0]); - /* Line 6 display Large community */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) { - if (json_paths) { - if (!attr->lcommunity->json) - lcommunity_str(attr->lcommunity, true); - json_object_lock(attr->lcommunity->json); - json_object_object_add(json_path, - "largeCommunity", - attr->lcommunity->json); - } else { - vty_out(vty, " Large Community: %s\n", - attr->lcommunity->str); - } - } + if (json_paths) + json_object_int_add(json_path, "remoteLabel", label); + else + vty_out(vty, " Remote label: %d\n", label); + } - /* Line 7 display Originator, Cluster-id */ - if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) - || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { - if (attr->flag - & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) { - if (json_paths) - json_object_string_add( - json_path, "originatorId", - inet_ntoa(attr->originator_id)); - else - vty_out(vty, " Originator: %s", - inet_ntoa(attr->originator_id)); - } + /* Label Index */ + if (attr->label_index != BGP_INVALID_LABEL_INDEX) { + if (json_paths) + json_object_int_add(json_path, "labelIndex", + attr->label_index); + else + vty_out(vty, " Label Index: %d\n", + attr->label_index); + } - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) { - int i; - - if (json_paths) { - json_cluster_list = - json_object_new_object(); - json_cluster_list_list = - json_object_new_array(); - - for (i = 0; - i < attr->cluster->length / 4; - i++) { - json_string = json_object_new_string( - inet_ntoa( - attr->cluster->list - [i])); - json_object_array_add( - json_cluster_list_list, - json_string); - } - - /* struct cluster_list does not have - "str" variable like - * aspath and community do. Add this - someday if someone - * asks for it. - json_object_string_add(json_cluster_list, - "string", attr->cluster->str); - */ - json_object_object_add( - json_cluster_list, "list", - json_cluster_list_list); - json_object_object_add( - json_path, "clusterList", - json_cluster_list); - } else { - vty_out(vty, ", Cluster list: "); - - for (i = 0; - i < attr->cluster->length / 4; - i++) { - vty_out(vty, "%s ", - inet_ntoa( - attr->cluster->list - [i])); - } - } - } - - if (!json_paths) - vty_out(vty, "\n"); - } - - if (path->extra && path->extra->damp_info) - bgp_damp_info_vty(vty, path, json_path); - - /* Remote Label */ - if (path->extra && bgp_is_valid_label(&path->extra->label[0]) - && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { - mpls_label_t label = label_pton(&path->extra->label[0]); - - if (json_paths) - json_object_int_add(json_path, "remoteLabel", - label); - else - vty_out(vty, " Remote label: %d\n", label); - } - - /* Label Index */ - if (attr->label_index != BGP_INVALID_LABEL_INDEX) { - if (json_paths) - json_object_int_add(json_path, "labelIndex", - attr->label_index); - else - vty_out(vty, " Label Index: %d\n", - attr->label_index); - } - - /* Line 8 display Addpath IDs */ - if (path->addpath_rx_id - || bgp_addpath_info_has_ids(&path->tx_addpath)) { - if (json_paths) { - json_object_int_add(json_path, "addpathRxId", - path->addpath_rx_id); - - /* Keep backwards compatibility with the old API - * by putting TX All's ID in the old field - */ - json_object_int_add( - json_path, "addpathTxId", - path->tx_addpath.addpath_tx_id - [BGP_ADDPATH_ALL]); - - /* ... but create a specific field for each - * strategy - */ - for (i = 0; i < BGP_ADDPATH_MAX; i++) { - json_object_int_add( - json_path, - bgp_addpath_names(i) - ->id_json_name, - path->tx_addpath - .addpath_tx_id[i]); - } - } else { - vty_out(vty, " AddPath ID: RX %u, ", - path->addpath_rx_id); - - route_vty_out_tx_ids(vty, &path->tx_addpath); - } - } - - /* If we used addpath to TX a non-bestpath we need to display - * "Advertised to" on a path-by-path basis - */ - if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { - first = 1; - - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - addpath_capable = - bgp_addpath_encode_tx(peer, afi, safi); - has_adj = bgp_adj_out_lookup( - peer, path->net, - bgp_addpath_id_for_peer( - peer, afi, safi, - &path->tx_addpath)); - - if ((addpath_capable && has_adj) - || (!addpath_capable && has_adj - && CHECK_FLAG(path->flags, - BGP_PATH_SELECTED))) { - if (json_path && !json_adv_to) - json_adv_to = - json_object_new_object(); - - route_vty_out_advertised_to( - vty, peer, &first, - " Advertised to:", - json_adv_to); - } - } - - if (json_path) { - if (json_adv_to) { - json_object_object_add(json_path, - "advertisedTo", - json_adv_to); - } - } else { - if (!first) { - vty_out(vty, "\n"); - } - } - } - - /* Line 9 display Uptime */ - tbuf = time(NULL) - (bgp_clock() - path->uptime); + /* Line 8 display Addpath IDs */ + if (path->addpath_rx_id + || bgp_addpath_info_has_ids(&path->tx_addpath)) { if (json_paths) { - json_last_update = json_object_new_object(); - json_object_int_add(json_last_update, "epoch", tbuf); - json_object_string_add(json_last_update, "string", - ctime(&tbuf)); - json_object_object_add(json_path, "lastUpdate", - json_last_update); - } else - vty_out(vty, " Last update: %s", ctime(&tbuf)); + json_object_int_add(json_path, "addpathRxId", + path->addpath_rx_id); - /* Line 10 display PMSI tunnel attribute, if present */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) { - const char *str = lookup_msg(bgp_pmsi_tnltype_str, - attr->pmsi_tnl_type, - PMSI_TNLTYPE_STR_DEFAULT); + /* Keep backwards compatibility with the old API + * by putting TX All's ID in the old field + */ + json_object_int_add( + json_path, "addpathTxId", + path->tx_addpath + .addpath_tx_id[BGP_ADDPATH_ALL]); - if (json_paths) { - json_pmsi = json_object_new_object(); - json_object_string_add(json_pmsi, - "tunnelType", str); - json_object_int_add(json_pmsi, - "label", - label2vni(&attr->label)); - json_object_object_add(json_path, "pmsi", - json_pmsi); - } else - vty_out(vty, - " PMSI Tunnel Type: %s, label: %d\n", - str, label2vni(&attr->label)); + /* ... but create a specific field for each + * strategy + */ + for (i = 0; i < BGP_ADDPATH_MAX; i++) { + json_object_int_add( + json_path, + bgp_addpath_names(i)->id_json_name, + path->tx_addpath.addpath_tx_id[i]); + } + } else { + vty_out(vty, " AddPath ID: RX %u, ", + path->addpath_rx_id); + + route_vty_out_tx_ids(vty, &path->tx_addpath); + } + } + + /* If we used addpath to TX a non-bestpath we need to display + * "Advertised to" on a path-by-path basis + */ + if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { + first = 1; + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + addpath_capable = + bgp_addpath_encode_tx(peer, afi, safi); + has_adj = bgp_adj_out_lookup( + peer, path->net, + bgp_addpath_id_for_peer(peer, afi, safi, + &path->tx_addpath)); + + if ((addpath_capable && has_adj) + || (!addpath_capable && has_adj + && CHECK_FLAG(path->flags, + BGP_PATH_SELECTED))) { + if (json_path && !json_adv_to) + json_adv_to = json_object_new_object(); + + route_vty_out_advertised_to( + vty, peer, &first, + " Advertised to:", json_adv_to); + } } + if (json_path) { + if (json_adv_to) { + json_object_object_add( + json_path, "advertisedTo", json_adv_to); + } + } else { + if (!first) { + vty_out(vty, "\n"); + } + } + } + + /* Line 9 display Uptime */ + tbuf = time(NULL) - (bgp_clock() - path->uptime); + if (json_paths) { + json_last_update = json_object_new_object(); + json_object_int_add(json_last_update, "epoch", tbuf); + json_object_string_add(json_last_update, "string", + ctime(&tbuf)); + json_object_object_add(json_path, "lastUpdate", + json_last_update); + } else + vty_out(vty, " Last update: %s", ctime(&tbuf)); + + /* Line 10 display PMSI tunnel attribute, if present */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) { + const char *str = + lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type, + PMSI_TNLTYPE_STR_DEFAULT); + + if (json_paths) { + json_pmsi = json_object_new_object(); + json_object_string_add(json_pmsi, "tunnelType", str); + json_object_int_add(json_pmsi, "label", + label2vni(&attr->label)); + json_object_object_add(json_path, "pmsi", json_pmsi); + } else + vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n", + str, label2vni(&attr->label)); } /* We've constructed the json object for this path, add it to the json @@ -9131,8 +9024,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, json_object_object_add(json_path, "peer", json_peer); json_object_array_add(json_paths, json_path); - } else - vty_out(vty, "\n"); + } } #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path" @@ -10693,13 +10585,12 @@ static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top, for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) { ts->counts[BGP_STATS_RIB]++; - if (pi->attr - && (CHECK_FLAG(pi->attr->flag, - ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))) + if (CHECK_FLAG(pi->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) ts->counts[BGP_STATS_AGGREGATES]++; /* as-path stats */ - if (pi->attr && pi->attr->aspath) { + if (pi->attr->aspath) { unsigned int hops = aspath_count_hops(pi->attr->aspath); unsigned int size = aspath_size(pi->attr->aspath); as_t highest = aspath_highest(pi->attr->aspath); @@ -11270,7 +11161,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, if (type == bgp_show_adj_route_received || type == bgp_show_adj_route_filtered) { for (ain = rn->adj_in; ain; ain = ain->next) { - if (ain->peer != peer || !ain->attr) + if (ain->peer != peer) continue; if (header1) { diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index a038b0e7a9..d0cea547ec 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -700,7 +700,7 @@ route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, if (type == RMAP_BGP && prefix->family == AF_INET) { path = (struct bgp_path_info *)object; - if (!path || !path->attr) + if (!path) return RMAP_NOMATCH; /* If nexthop interface's index can't be resolved and nexthop is @@ -868,8 +868,7 @@ route_match_vni(void *rule, const struct prefix *prefix, * For any other tunnel type, return noop to ignore * this check. */ - if (path->attr && path->attr->encap_tunneltype != - BGP_ENCAP_TYPE_VXLAN) + if (path->attr->encap_tunneltype != BGP_ENCAP_TYPE_VXLAN) return RMAP_NOOP; /* @@ -1470,7 +1469,7 @@ route_match_interface(void *rule, const struct prefix *prefix, if (type == RMAP_BGP) { path = object; - if (!path || !path->attr) + if (!path) return RMAP_NOMATCH; ifp = if_lookup_by_name_all_vrf((char *)rule); @@ -2690,7 +2689,7 @@ route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, if (type == RMAP_BGP && prefix->family == AF_INET6) { path = (struct bgp_path_info *)object; - if (!path || !path->attr) + if (!path) return RMAP_NOMATCH; if (IPV6_ADDR_SAME(&path->attr->mp_nexthop_global, addr) diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 0aa102feab..83b05ce536 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -388,15 +388,13 @@ void del_vnc_route(struct rfapi_descriptor *rfd, bpi = bpi->next) { vnc_zlog_debug_verbose( - "%s: trying bpi=%p, bpi->peer=%p, bpi->type=%d, bpi->sub_type=%d, bpi->extra->vnc.export.rfapi_handle=%p, local_pref=%u", + "%s: trying bpi=%p, bpi->peer=%p, bpi->type=%d, bpi->sub_type=%d, bpi->extra->vnc.export.rfapi_handle=%p, local_pref=%" PRIu64, __func__, bpi, bpi->peer, bpi->type, bpi->sub_type, (bpi->extra ? bpi->extra->vnc.export.rfapi_handle : NULL), - ((bpi->attr - && CHECK_FLAG(bpi->attr->flag, - ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) - ? bpi->attr->local_pref - : 0)); + CHECK_FLAG(bpi->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) + ? bpi->attr->local_pref : 0)); if (bpi->peer == peer && bpi->type == type && bpi->sub_type == sub_type && bpi->extra diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 655cf747de..fe8e874440 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -484,8 +484,7 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, new = info_make(type, sub_type, 0, peer, attr, NULL); - if (attr) - new->attr = bgp_attr_intern(attr); + new->attr = bgp_attr_intern(attr); bgp_path_info_extra_get(new); if (prd) { @@ -516,9 +515,8 @@ static void rfapiBgpInfoFree(struct bgp_path_info *goner) peer_unlock(goner->peer); } - if (goner->attr) { - bgp_attr_unintern(&goner->attr); - } + bgp_attr_unintern(&goner->attr); + if (goner->extra) bgp_path_info_extra_free(&goner->extra); XFREE(MTYPE_BGP_ROUTE, goner); @@ -1113,9 +1111,6 @@ static int rfapiVpnBiSamePtUn(struct bgp_path_info *bpi1, if (!bpi1 || !bpi2) return 0; - if (!bpi1->attr || !bpi2->attr) - return 0; - /* * VN address comparisons */ @@ -1299,13 +1294,10 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, memcpy(&vo->v.l2addr.macaddr, &rn->p.u.prefix_eth.octet, ETH_ALEN); /* only low 3 bytes of this are significant */ - if (bpi->attr) { - (void)rfapiEcommunityGetLNI( - bpi->attr->ecommunity, - &vo->v.l2addr.logical_net_id); - (void)rfapiEcommunityGetEthernetTag( - bpi->attr->ecommunity, &vo->v.l2addr.tag_id); - } + (void)rfapiEcommunityGetLNI(bpi->attr->ecommunity, + &vo->v.l2addr.logical_net_id); + (void)rfapiEcommunityGetEthernetTag(bpi->attr->ecommunity, + &vo->v.l2addr.tag_id); /* local_nve_id comes from lower byte of RD type */ vo->v.l2addr.local_nve_id = bpi->extra->vnc.import.rd.val[1]; @@ -1325,129 +1317,117 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, } } - if (bpi->attr) { - bgp_encap_types tun_type = BGP_ENCAP_TYPE_MPLS; /*Default*/ - new->prefix.cost = rfapiRfpCost(bpi->attr); + bgp_encap_types tun_type = BGP_ENCAP_TYPE_MPLS; /*Default*/ + new->prefix.cost = rfapiRfpCost(bpi->attr); - struct bgp_attr_encap_subtlv *pEncap; + struct bgp_attr_encap_subtlv *pEncap; - switch (BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len)) { - case AF_INET: - new->vn_address.addr_family = AF_INET; - new->vn_address.addr.v4 = - bpi->attr->mp_nexthop_global_in; - break; + switch (BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len)) { + case AF_INET: + new->vn_address.addr_family = AF_INET; + new->vn_address.addr.v4 = bpi->attr->mp_nexthop_global_in; + break; - case AF_INET6: - new->vn_address.addr_family = AF_INET6; - new->vn_address.addr.v6 = bpi->attr->mp_nexthop_global; + case AF_INET6: + new->vn_address.addr_family = AF_INET6; + new->vn_address.addr.v6 = bpi->attr->mp_nexthop_global; + break; + + default: + zlog_warn("%s: invalid vpn nexthop length: %d", __func__, + bpi->attr->mp_nexthop_len); + rfapi_free_next_hop_list(new); + return NULL; + } + + for (pEncap = bpi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) { + switch (pEncap->type) { + case BGP_VNC_SUBTLV_TYPE_LIFETIME: + /* use configured lifetime, not attr lifetime */ break; default: - zlog_warn("%s: invalid vpn nexthop length: %d", - __func__, bpi->attr->mp_nexthop_len); - rfapi_free_next_hop_list(new); - return NULL; + zlog_warn("%s: unknown VNC option type %d", __func__, + pEncap->type); + + break; } + } - for (pEncap = bpi->attr->vnc_subtlvs; pEncap; - pEncap = pEncap->next) { - switch (pEncap->type) { - case BGP_VNC_SUBTLV_TYPE_LIFETIME: - /* use configured lifetime, not attr lifetime */ - break; - - default: - zlog_warn("%s: unknown VNC option type %d", - __func__, pEncap->type); - - - break; - } + bgp_attr_extcom_tunnel_type(bpi->attr, &tun_type); + if (tun_type == BGP_ENCAP_TYPE_MPLS) { + struct prefix p; + /* MPLS carries UN address in next hop */ + rfapiNexthop2Prefix(bpi->attr, &p); + if (p.family != 0) { + rfapiQprefix2Raddr(&p, &new->un_address); + have_vnc_tunnel_un = 1; } + } - bgp_attr_extcom_tunnel_type(bpi->attr, &tun_type); - if (tun_type == BGP_ENCAP_TYPE_MPLS) { - struct prefix p; - /* MPLS carries UN address in next hop */ - rfapiNexthop2Prefix(bpi->attr, &p); - if (p.family != 0) { - rfapiQprefix2Raddr(&p, &new->un_address); + for (pEncap = bpi->attr->encap_subtlvs; pEncap; pEncap = pEncap->next) { + switch (pEncap->type) { + case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: + /* + * Overrides ENCAP UN address, if any + */ + switch (pEncap->length) { + + case 8: + new->un_address.addr_family = AF_INET; + memcpy(&new->un_address.addr.v4, pEncap->value, + 4); have_vnc_tunnel_un = 1; - } - } + break; - for (pEncap = bpi->attr->encap_subtlvs; pEncap; - pEncap = pEncap->next) { - switch (pEncap->type) { - case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: - /* - * Overrides ENCAP UN address, if any - */ - switch (pEncap->length) { - - case 8: - new->un_address.addr_family = AF_INET; - memcpy(&new->un_address.addr.v4, - pEncap->value, 4); - have_vnc_tunnel_un = 1; - break; - - case 20: - new->un_address.addr_family = AF_INET6; - memcpy(&new->un_address.addr.v6, - pEncap->value, 16); - have_vnc_tunnel_un = 1; - break; - - default: - zlog_warn( - "%s: invalid tunnel subtlv UN addr length (%d) for bpi %p", - __func__, pEncap->length, bpi); - } + case 20: + new->un_address.addr_family = AF_INET6; + memcpy(&new->un_address.addr.v6, pEncap->value, + 16); + have_vnc_tunnel_un = 1; break; default: zlog_warn( - "%s: unknown Encap Attribute option type %d", - __func__, pEncap->type); - - - break; + "%s: invalid tunnel subtlv UN addr length (%d) for bpi %p", + __func__, pEncap->length, bpi); } - } + break; - new->un_options = rfapi_encap_tlv_to_un_option(bpi->attr); + default: + zlog_warn("%s: unknown Encap Attribute option type %d", + __func__, pEncap->type); + break; + } + } + + new->un_options = rfapi_encap_tlv_to_un_option(bpi->attr); #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose("%s: line %d: have_vnc_tunnel_un=%d", - __func__, __LINE__, have_vnc_tunnel_un); + vnc_zlog_debug_verbose("%s: line %d: have_vnc_tunnel_un=%d", __func__, + __LINE__, have_vnc_tunnel_un); #endif - if (!have_vnc_tunnel_un && bpi->extra) { - /* - * use cached UN address from ENCAP route - */ - new->un_address.addr_family = - bpi->extra->vnc.import.un_family; - switch (new->un_address.addr_family) { - case AF_INET: - new->un_address.addr.v4 = - bpi->extra->vnc.import.un.addr4; - break; - case AF_INET6: - new->un_address.addr.v6 = - bpi->extra->vnc.import.un.addr6; - break; - default: - zlog_warn( - "%s: invalid UN addr family (%d) for bpi %p", - __func__, new->un_address.addr_family, - bpi); - rfapi_free_next_hop_list(new); - return NULL; - break; - } + if (!have_vnc_tunnel_un && bpi->extra) { + /* + * use cached UN address from ENCAP route + */ + new->un_address.addr_family = bpi->extra->vnc.import.un_family; + switch (new->un_address.addr_family) { + case AF_INET: + new->un_address.addr.v4 = + bpi->extra->vnc.import.un.addr4; + break; + case AF_INET6: + new->un_address.addr.v6 = + bpi->extra->vnc.import.un.addr6; + break; + default: + zlog_warn("%s: invalid UN addr family (%d) for bpi %p", + __func__, new->un_address.addr_family, bpi); + rfapi_free_next_hop_list(new); + return NULL; + break; } } @@ -2607,12 +2587,6 @@ static int rfapiAttrNexthopAddrDifferent(struct prefix *p1, struct prefix *p2) static void rfapiCopyUnEncap2VPN(struct bgp_path_info *encap_bpi, struct bgp_path_info *vpn_bpi) { - if (!encap_bpi->attr) { - zlog_warn("%s: no encap bpi attr/extra, can't copy UN address", - __func__); - return; - } - if (!vpn_bpi || !vpn_bpi->extra) { zlog_warn("%s: no vpn bpi attr/extra, can't copy UN address", __func__); @@ -4510,10 +4484,9 @@ static void rfapiDeleteRemotePrefixesIt( vnc_zlog_debug_verbose("%s: examining bpi %p", __func__, bpi); - if (bpi->attr) { - if (!rfapiGetNexthop(bpi->attr, &qpt)) - qpt_valid = 1; - } + if (!rfapiGetNexthop(bpi->attr, &qpt)) + qpt_valid = 1; + if (vn) { if (!qpt_valid || !prefix_match(vn, &qpt)) { diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 8e8acbfb91..39d4b3ee29 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -1647,11 +1647,6 @@ void rfapiRibUpdatePendingNode( struct rfapi_info *ri; struct prefix pfx_nh; - if (!bpi->attr) { - /* shouldn't happen */ - /* TBD increment error stats counter */ - continue; - } if (!bpi->extra) { /* shouldn't happen */ /* TBD increment error stats counter */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 46161b4f38..dc4a02e8b2 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -418,7 +418,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p, } } - if (bpi->attr && bpi->attr->ecommunity) { + if (bpi->attr->ecommunity) { s = ecommunity_ecom2str(bpi->attr->ecommunity, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); vty_out(vty, " EC{%s}", s); @@ -538,82 +538,78 @@ void rfapiPrintBi(void *stream, struct bgp_path_info *bpi) * RFP option sizes (they are opaque values) * extended communities (RTs) */ - if (bpi->attr) { - uint32_t lifetime; - int printed_1st_gol = 0; - struct bgp_attr_encap_subtlv *pEncap; - struct prefix pfx_un; - int af = BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len); + uint32_t lifetime; + int printed_1st_gol = 0; + struct bgp_attr_encap_subtlv *pEncap; + struct prefix pfx_un; + int af = BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len); - /* Nexthop */ - if (af == AF_INET) { - r = snprintf(p, REMAIN, "%s", - inet_ntop(AF_INET, - &bpi->attr->mp_nexthop_global_in, - buf, BUFSIZ)); - INCP; - } else if (af == AF_INET6) { - r = snprintf(p, REMAIN, "%s", - inet_ntop(AF_INET6, - &bpi->attr->mp_nexthop_global, - buf, BUFSIZ)); - INCP; - } else { - r = snprintf(p, REMAIN, "?"); - INCP; - } + /* Nexthop */ + if (af == AF_INET) { + r = snprintf(p, REMAIN, "%s", + inet_ntop(AF_INET, + &bpi->attr->mp_nexthop_global_in, buf, + BUFSIZ)); + INCP; + } else if (af == AF_INET6) { + r = snprintf(p, REMAIN, "%s", + inet_ntop(AF_INET6, &bpi->attr->mp_nexthop_global, + buf, BUFSIZ)); + INCP; + } else { + r = snprintf(p, REMAIN, "?"); + INCP; + } - /* - * VNC tunnel subtlv, if present, contains UN address - */ - if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) { - r = snprintf(p, REMAIN, " un=%s", - inet_ntop(pfx_un.family, pfx_un.u.val, buf, - BUFSIZ)); - INCP; - } + /* + * VNC tunnel subtlv, if present, contains UN address + */ + if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) { + r = snprintf( + p, REMAIN, " un=%s", + inet_ntop(pfx_un.family, pfx_un.u.val, buf, BUFSIZ)); + INCP; + } - /* Lifetime */ - if (rfapiGetVncLifetime(bpi->attr, &lifetime)) { - r = snprintf(p, REMAIN, " nolife"); - INCP; - } else { - if (lifetime == 0xffffffff) - r = snprintf(p, REMAIN, " %6s", "infini"); - else - r = snprintf(p, REMAIN, " %6u", lifetime); - INCP; - } + /* Lifetime */ + if (rfapiGetVncLifetime(bpi->attr, &lifetime)) { + r = snprintf(p, REMAIN, " nolife"); + INCP; + } else { + if (lifetime == 0xffffffff) + r = snprintf(p, REMAIN, " %6s", "infini"); + else + r = snprintf(p, REMAIN, " %6u", lifetime); + INCP; + } - /* RFP option lengths */ - for (pEncap = bpi->attr->vnc_subtlvs; pEncap; - pEncap = pEncap->next) { + /* RFP option lengths */ + for (pEncap = bpi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) { - if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { - if (printed_1st_gol) { - r = snprintf(p, REMAIN, ","); - INCP; - } else { - r = snprintf(p, REMAIN, - " "); /* leading space */ - INCP; - } - r = snprintf(p, REMAIN, "%d", pEncap->length); + if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { + if (printed_1st_gol) { + r = snprintf(p, REMAIN, ","); + INCP; + } else { + r = snprintf(p, REMAIN, + " "); /* leading space */ INCP; - printed_1st_gol = 1; } - } - - /* RT list */ - if (bpi->attr->ecommunity) { - s = ecommunity_ecom2str(bpi->attr->ecommunity, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - r = snprintf(p, REMAIN, " %s", s); + r = snprintf(p, REMAIN, "%d", pEncap->length); INCP; - XFREE(MTYPE_ECOMMUNITY_STR, s); + printed_1st_gol = 1; } } + /* RT list */ + if (bpi->attr->ecommunity) { + s = ecommunity_ecom2str(bpi->attr->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + r = snprintf(p, REMAIN, " %s", s); + INCP; + XFREE(MTYPE_ECOMMUNITY_STR, s); + } + r = snprintf(p, REMAIN, " bpi@%p", bpi); INCP; @@ -628,21 +624,17 @@ void rfapiPrintBi(void *stream, struct bgp_path_info *bpi) INCP; } - if (bpi->attr) { + if (bpi->attr->weight) { + r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight); + INCP; + } - if (bpi->attr->weight) { - r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight); - INCP; - } - - if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { - r = snprintf(p, REMAIN, " LP=%d", - bpi->attr->local_pref); - INCP; - } else { - r = snprintf(p, REMAIN, " LP=unset"); - INCP; - } + if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + r = snprintf(p, REMAIN, " LP=%d", bpi->attr->local_pref); + INCP; + } else { + r = snprintf(p, REMAIN, " LP=unset"); + INCP; } r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bpi->type), @@ -1087,16 +1079,13 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion * back to cost. */ - if (bpi->attr) { - uint32_t local_pref; - if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) - local_pref = bpi->attr->local_pref; - else - local_pref = 0; - cost = (local_pref > 255) ? 0 : 255 - local_pref; - } else { - cost = 0; - } + uint32_t local_pref; + + if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) + local_pref = bpi->attr->local_pref; + else + local_pref = 0; + cost = (local_pref > 255) ? 0 : 255 - local_pref; fp(out, "%-20s ", buf_pfx); fp(out, "%-15s ", buf_vn); diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index eb2d0fd889..51ec999764 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -476,25 +476,21 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( plifetime = &lifetime; } - if (bpi->attr) { - encaptlvs = bpi->attr->vnc_subtlvs; - if (bpi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED - && bpi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) { - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - memset(opt, 0, sizeof(struct rfapi_un_option)); - opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; - opt->v.tunnel.type = bpi->attr->encap_tunneltype; - /* TBD parse bpi->attr->extra->encap_subtlvs */ - } - } else { - encaptlvs = NULL; + encaptlvs = bpi->attr->vnc_subtlvs; + if (bpi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED + && bpi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) { + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + memset(opt, 0, sizeof(struct rfapi_un_option)); + opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; + opt->v.tunnel.type = bpi->attr->encap_tunneltype; + /* TBD parse bpi->attr->extra->encap_subtlvs */ } struct ecommunity *new_ecom = ecommunity_dup(ecom); - if (bpi->attr && bpi->attr->ecommunity) + if (bpi->attr->ecommunity) ecommunity_merge(new_ecom, bpi->attr->ecommunity); if (bpi->extra) @@ -635,12 +631,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( } local_pref = calc_local_pref(info->attr, info->peer); - if (info->attr - && (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { - + if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) med = &info->attr->med; - } - /* * At this point, we have allocated: @@ -1103,7 +1095,7 @@ static void vnc_import_bgp_del_route_mode_plain(struct bgp *bgp, * Compute VN address */ - if (info && info->attr) { + if (info) { rfapiUnicastNexthop2Prefix(afi, info->attr, &vn_pfx_space); } else { vnc_zlog_debug_verbose("%s: no attr, can't delete route", @@ -1489,12 +1481,9 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( } local_pref = calc_local_pref(pb->ubpi->attr, pb->ubpi->peer); - if (pb->ubpi->attr - && (pb->ubpi->attr->flag - & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { - + if (pb->ubpi->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) med = &pb->ubpi->attr->med; - } /* * Sanity check @@ -1729,11 +1718,6 @@ static void vnc_import_bgp_exterior_add_route_it( return; } - if (!info->attr) { - vnc_zlog_debug_verbose("%s: no info, skipping", __func__); - return; - } - /* * Extract nexthop from exterior route * @@ -1920,11 +1904,6 @@ void vnc_import_bgp_exterior_del_route( return; } - if (!info->attr) { - vnc_zlog_debug_verbose("%s: no info, skipping", __func__); - return; - } - /* * Extract nexthop from exterior route * diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index b5a474b8bb..b8c216ff82 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1063,6 +1063,13 @@ Configuring Peers on by default or not. This command defaults to on and is not displayed. The `no bgp default ipv4-unicast` form of the command is displayed. +.. index:: [no] neighbor PEER advertisement-interval (0-600) +.. clicmd:: [no] neighbor PEER advertisement-interval (0-600) + + Setup the minimum route advertisement interval(mrai) for the + peer in question. This number is between 0 and 600 seconds, + with the default advertisement interval being 0. + .. _bgp-peer-filtering: Peer Filtering diff --git a/lib/filter.c b/lib/filter.c index fe62ca1c13..8c210bd7ad 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -1915,6 +1915,7 @@ DEFUN (mac_access_list, argv_find(argv, argc, "X:X:X:X:X:X", &idx); if (idx) mac = argv[idx]->arg; + assert(mac); return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN, mac, 0, 1); @@ -1952,6 +1953,7 @@ DEFUN (no_mac_access_list, argv_find(argv, argc, "X:X:X:X:X:X", &idx); if (idx) mac = argv[idx]->arg; + assert(mac); return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN, mac, 0, 0); @@ -2050,6 +2052,7 @@ DEFUN (access_list_exact, argv_find(argv, argc, "A.B.C.D/M", &idx); if (idx) prefix = argv[idx]->arg; + assert(prefix); idx = 0; if (argv_find(argv, argc, "exact-match", &idx)) @@ -2122,6 +2125,7 @@ DEFUN (no_access_list_exact, argv_find(argv, argc, "A.B.C.D/M", &idx); if (idx) prefix = argv[idx]->arg; + assert(prefix); idx = 0; if (argv_find(argv, argc, "exact-match", &idx)) @@ -2367,6 +2371,7 @@ DEFUN (no_ipv6_access_list_exact, argv_find(argv, argc, "X:X::X:X/M", &idx); if (idx) prefix = argv[idx]->arg; + assert(prefix); idx = 0; if (argv_find(argv, argc, "exact-match", &idx)) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 5ce9d3f293..92f8dd1ecc 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1025,10 +1025,9 @@ DEFPY (show_route_all_table_vrf, continue; if (zrt->afi != afi || zrt->safi != SAFI_UNICAST) continue; - if (zrt->table) - do_show_route_helper(vty, info->zvrf, zrt->table, afi, - false, 0, false, false, - 0, 0, !!json, zrt->tableid); + + do_show_route_helper(vty, info->zvrf, zrt->table, afi, false, 0, + false, false, 0, 0, !!json, zrt->tableid); } return CMD_SUCCESS; }