diff options
Diffstat (limited to 'bgpd/bgp_route.c')
| -rw-r--r-- | bgpd/bgp_route.c | 145 |
1 files changed, 97 insertions, 48 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f8a29821d8..8d87f2cd04 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -241,6 +241,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) if (e->bgp_orig) bgp_unlock(e->bgp_orig); + if (e->aggr_suppressors) + list_delete(&e->aggr_suppressors); + if ((*extra)->bgp_fs_iprule) list_delete(&((*extra)->bgp_fs_iprule)); if ((*extra)->bgp_fs_pbr) @@ -1439,14 +1442,15 @@ static bool bgp_community_filter(struct peer *peer, struct attr *attr) static bool bgp_cluster_filter(struct peer *peer, struct attr *attr) { struct in_addr cluster_id; + struct cluster_list *cluster = bgp_attr_get_cluster(attr); - if (attr->cluster) { + if (cluster) { if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID) cluster_id = peer->bgp->cluster_id; else cluster_id = peer->bgp->router_id; - if (cluster_loop_check(attr->cluster, cluster_id)) + if (cluster_loop_check(cluster, cluster_id)) return true; } return false; @@ -1500,7 +1504,7 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p, SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN); /* Apply BGP route map to the attribute. */ - ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path); + ret = route_map_apply(rmap, p, &rmap_path); peer->rmap_type = 0; @@ -1551,7 +1555,7 @@ static int bgp_output_modifier(struct peer *peer, const struct prefix *p, SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT); /* Apply BGP route map to the attribute. */ - ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path); + ret = route_map_apply(rmap, p, &rmap_path); peer->rmap_type = rmap_type; @@ -2047,10 +2051,10 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (bgp_path_suppressed(pi)) ret = route_map_apply(UNSUPPRESS_MAP(filter), p, - RMAP_BGP, &rmap_path); + &rmap_path); else ret = route_map_apply(ROUTE_MAP_OUT(filter), p, - RMAP_BGP, &rmap_path); + &rmap_path); peer->rmap_type = 0; @@ -2497,10 +2501,13 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, struct attr attr; afi_t afi; safi_t safi; + struct bgp *bgp; + bool advertise; p = bgp_dest_get_prefix(dest); afi = SUBGRP_AFI(subgrp); safi = SUBGRP_SAFI(subgrp); + bgp = SUBGRP_INST(subgrp); onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer : NULL); @@ -2515,13 +2522,23 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, memset(&attr, 0, sizeof(struct attr)); /* It's initialized in bgp_announce_check() */ - /* Announcement to the subgroup. If the route is filtered withdraw it. + /* Announcement to the subgroup. If the route is filtered withdraw it. + * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status + * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the + * route */ + advertise = bgp_check_advertise(bgp, dest); + if (selected) { if (subgroup_announce_check(dest, selected, subgrp, p, &attr, - false)) - bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected); - else + false)) { + /* Route is selected, if the route is already installed + * in FIB, then it is advertised + */ + if (advertise) + bgp_adj_out_set_subgroup(dest, subgrp, &attr, + selected); + } else bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id); } @@ -2620,7 +2637,7 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi, RESET_FLAG(dummy_attr.rmap_change_flags); ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map, - p, RMAP_BGP, &rmap_path); + p, &rmap_path); if (ret == RMAP_DENYMATCH) { bgp_attr_flush(&dummy_attr); @@ -3370,17 +3387,22 @@ static void overlay_index_update(struct attr *attr, if (!attr) return; if (gw_ip == NULL) { - memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr)); + struct bgp_route_evpn eo; + + memset(&eo, 0, sizeof(eo)); + bgp_attr_set_evpn_overlay(attr, &eo); } else { - memcpy(&(attr->evpn_overlay.gw_ip), gw_ip, - sizeof(union gw_addr)); + struct bgp_route_evpn eo = {.gw_ip = *gw_ip}; + + bgp_attr_set_evpn_overlay(attr, &eo); } } static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, union gw_addr *gw_ip) { - union gw_addr *path_gw_ip, *path_gw_ip_remote; + const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr); + union gw_addr path_gw_ip, *path_gw_ip_remote; union { esi_t esi; union gw_addr ip; @@ -3389,7 +3411,7 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, if (afi != AFI_L2VPN) return true; - path_gw_ip = &(path->attr->evpn_overlay.gw_ip); + path_gw_ip = eo->gw_ip; if (gw_ip == NULL) { memset(&temp, 0, sizeof(temp)); @@ -3397,7 +3419,7 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, } else path_gw_ip_remote = gw_ip; - return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)); + return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)); } /* Check if received nexthop is valid or not. */ @@ -3525,6 +3547,22 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, else has_valid_label = bgp_is_valid_label(label); + if (has_valid_label) + assert(label != NULL); + + /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following + * condition : + * Suppress fib is enabled + * BGP_OPT_NO_FIB is not enabled + * Route type is BGP_ROUTE_NORMAL (peer learnt routes) + * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set) + */ + if (BGP_SUPPRESS_FIB_ENABLED(bgp) && + (sub_type == BGP_ROUTE_NORMAL) && + (!bgp_option_check(BGP_OPT_NO_FIB)) && + (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED))) + SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); + /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ if (!soft_reconfig @@ -4480,7 +4518,8 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi, if (num_labels) label_pnt = &pi->extra->label[0]; if (pi) - memcpy(&evpn, &pi->attr->evpn_overlay, + memcpy(&evpn, + bgp_attr_get_evpn_overlay(pi->attr), sizeof(evpn)); else memset(&evpn, 0, sizeof(evpn)); @@ -5189,8 +5228,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK); - ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, - &rmap_path); + ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path); bgp->peer_self->rmap_type = 0; @@ -5509,8 +5547,7 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK); - ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, - &rmap_path); + ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path); bgp->peer_self->rmap_type = 0; @@ -6361,7 +6398,7 @@ static bool aggr_suppress_map_test(struct bgp *bgp, rmap_path.attr = &attr; SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE); - rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path); + rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path); bgp->peer_self->rmap_type = 0; bgp_attr_flush(&attr); @@ -6789,6 +6826,12 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (dest_p->prefixlen <= p->prefixlen) continue; + /* If suppress fib is enabled and route not installed + * in FIB, skip the route + */ + if (!bgp_check_advertise(bgp, dest)) + continue; + match = 0; for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { @@ -7284,6 +7327,12 @@ void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p, if (BGP_PATH_HOLDDOWN(pi)) return; + /* If suppress fib is enabled and route not installed + * in FIB, do not update the aggregate route + */ + if (!bgp_check_advertise(bgp, pi->net)) + return; + child = bgp_node_get(table, p); /* Aggregate address configuration check. */ @@ -7807,8 +7856,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE); - ret = route_map_apply(red->rmap.map, p, RMAP_BGP, - &rmap_path); + ret = route_map_apply(red->rmap.map, p, &rmap_path); bgp->peer_self->rmap_type = 0; @@ -8926,13 +8974,12 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p, } } - 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); - } + const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr); + + if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) + inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ); + else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) + inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ); if (!json_path) vty_out(vty, "/%s", buf); @@ -10018,6 +10065,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) { + struct cluster_list *cluster = + bgp_attr_get_cluster(attr); int i; if (json_paths) { @@ -10025,13 +10074,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, json_cluster_list_list = json_object_new_array(); - for (i = 0; i < attr->cluster->length / 4; - i++) { + for (i = 0; i < cluster->length / 4; i++) { json_string = json_object_new_string( - inet_ntop( - AF_INET, - &attr->cluster->list[i], - buf, sizeof(buf))); + inet_ntop(AF_INET, + &cluster->list[i], + buf, sizeof(buf))); json_object_array_add( json_cluster_list_list, json_string); @@ -10043,7 +10090,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, * do. Add this someday if someone asks * for it. * json_object_string_add(json_cluster_list, - * "string", attr->cluster->str); + * "string", cluster->str); */ json_object_object_add(json_cluster_list, "list", @@ -10053,10 +10100,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } else { vty_out(vty, ", Cluster list: "); - for (i = 0; i < attr->cluster->length / 4; - i++) { + for (i = 0; i < cluster->length / 4; i++) { vty_out(vty, "%pI4 ", - &attr->cluster->list[i]); + &cluster->list[i]); } } } @@ -10183,9 +10229,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, /* 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); + const char *str = lookup_msg(bgp_pmsi_tnltype_str, + bgp_attr_get_pmsi_tnl_type(attr), + PMSI_TNLTYPE_STR_DEFAULT); if (json_paths) { json_pmsi = json_object_new_object(); @@ -10354,8 +10400,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, path.peer = pi->peer; path.attr = &dummy_attr; - ret = route_map_apply(rmap, dest_p, RMAP_BGP, - &path); + ret = route_map_apply(rmap, dest_p, &path); if (ret == RMAP_DENYMATCH) continue; } @@ -11168,6 +11213,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, char *str; int first = 0; uint8_t show_flags = 0; + int ret; if (uj) SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); @@ -11195,10 +11241,13 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, + ret = bgp_show(vty, bgp, afi, safi, (exact ? bgp_show_type_lcommunity_exact : bgp_show_type_lcommunity), lcom, show_flags); + + lcommunity_free(&lcom); + return ret; } static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, |
