diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index 89ee71df89..07b3b4143b 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -26,25 +26,31 @@ static route_map_result_t bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table, struct route_map *rmap) { + struct attr dummy_attr = {0}; struct bgp_dest *dest; - struct attr dummy_attr; - struct bgp_path_info path; - const struct prefix *dest_p; struct bgp_path_info *pi; - route_map_result_t ret = RMAP_PERMITMATCH; + struct bgp_path_info path = {0}; + struct bgp_path_info_extra path_extra = {0}; + const struct prefix *dest_p; + route_map_result_t ret = RMAP_DENYMATCH; for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { dest_p = bgp_dest_get_prefix(dest); - if (!dest_p) - continue; + assert(dest_p); for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { dummy_attr = *pi->attr; - path.peer = pi->peer; - path.attr = &dummy_attr; + + /* Fill temp path_info */ + prep_for_rmap_apply(&path, &path_extra, dest, pi, + pi->peer, &dummy_attr); + + RESET_FLAG(dummy_attr.rmap_change_flags); ret = route_map_apply(rmap, dest_p, RMAP_BGP, &path); - if (ret == RMAP_PERMITMATCH) + if (ret != RMAP_PERMITMATCH) + bgp_attr_flush(&dummy_attr); + else return ret; } } @@ -57,13 +63,14 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, enum update_type advertise) { int addpath_capable; - const struct prefix *dest_p; - struct attr dummy_attr, attr; - struct bgp_path_info path; + struct bgp_dest *dest; struct bgp_path_info *pi; - struct peer_af *paf = NULL; - struct bgp_dest *dest = NULL; - struct update_subgroup *subgrp = NULL; + struct bgp_path_info path; + struct peer_af *paf; + const struct prefix *dest_p; + struct update_subgroup *subgrp; + struct attr dummy_attr = {0}, attr = {0}; + struct bgp_path_info_extra path_extra = {0}; paf = peer_af_find(peer, afi, safi); if (!paf) @@ -78,17 +85,22 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { dest_p = bgp_dest_get_prefix(dest); - if (!dest_p) - continue; + assert(dest_p); for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { dummy_attr = *pi->attr; - path.peer = pi->peer; - path.attr = &dummy_attr; + + /* Fill temp path_info */ + prep_for_rmap_apply(&path, &path_extra, dest, pi, + pi->peer, &dummy_attr); + + RESET_FLAG(dummy_attr.rmap_change_flags); if (route_map_apply(rmap, dest_p, RMAP_BGP, &path) - != RMAP_PERMITMATCH) + != RMAP_PERMITMATCH) { + bgp_attr_flush(&dummy_attr); continue; + } if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) || (addpath_capable @@ -166,12 +178,15 @@ static int bgp_conditional_adv_timer(struct thread *t) if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; + if (peer->status != Established) + continue; + FOREACH_AFI_SAFI (afi, safi) { if (strmatch(get_afi_safi_str(afi, safi, true), "Unknown")) continue; - if (!peer->afc[afi][safi]) + if (!peer->afc_nego[afi][safi]) continue; /* labeled-unicast routes are installed in the unicast diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 765d27c243..17a4411c82 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7076,47 +7076,34 @@ static int peer_advertise_map_set_vty(struct vty *vty, const char *ip_str, DEFPY (neighbor_advertise_map, neighbor_advertise_map_cmd, - "[no$no] neighbor advertise-map WORD ", + "[no$no] neighbor $neighbor advertise-map WORD$advertise_str $exist WORD$condition_str", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Route-map to conditionally advertise routes\n" "Name of advertise map\n" "Advertise routes only if prefixes in exist-map are installed in BGP table\n" - "Name of the exist map\n" "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n" - "Name of the non exist map\n") + "Name of the exist or non exist map\n") { - int idx = 0; - int idx_peer = 1; - int idx_advertise_word = 3; - int idx_condition_word = 5; bool condition = CONDITION_EXIST; - if (no) { - idx_peer++; - idx_advertise_word++; - idx_condition_word++; - } - - if (argv_find(argv, argc, "non-exist-map", &idx)) + if (!strcmp(exist, "non-exist-map")) condition = CONDITION_NON_EXIST; - return peer_advertise_map_set_vty( - vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty), - argv[idx_advertise_word]->arg, argv[idx_condition_word]->arg, - condition, !no); + return peer_advertise_map_set_vty(vty, neighbor, bgp_node_afi(vty), + bgp_node_safi(vty), advertise_str, + condition_str, condition, !no); } ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd, - "[no$no] neighbor advertise-map WORD ", + "[no$no] neighbor $neighbor advertise-map WORD$advertise_str $exist WORD$condition_str", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Route-map to conditionally advertise routes\n" "Name of advertise map\n" "Advertise routes only if prefixes in exist-map are installed in BGP table\n" - "Name of the exist map\n" "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n" - "Name of the non exist map\n") + "Name of the exist or non exist map\n") /* Set route-map to the peer. */ static int peer_route_map_set_vty(struct vty *vty, const char *ip_str, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index fd4595274d..0e8970d685 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6611,8 +6611,9 @@ static void peer_update_rmap_filter_data(struct peer *peer, afi_t afi, if (!CHECK_FLAG(config_flags, BGP_PEER_RMAP_SET)) { memset(filter, 0, sizeof(struct bgp_filter)); - /* decrement condition_filter_count delete timer if last - * one */ + /* decrement condition_filter_count delete timer if + * this is the last advertise-map to be removed. + */ if (filter_exists) bgp_conditional_adv_disable(peer, afi, safi);