diff options
42 files changed, 6542 insertions, 1563 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 7e1d64056..11e9344d1 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -598,6 +598,7 @@ static int bgp_bfd_peer_param_type_set(struct peer *peer, return 0; } +#if HAVE_BFDD > 0 /** * Set peer BFD profile configuration. */ @@ -652,6 +653,7 @@ static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile) return 0; } +#endif /* * bgp_bfd_peer_config_write - Write the peer BFD configuration. diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c new file mode 100644 index 000000000..0731adcb8 --- /dev/null +++ b/bgpd/bgp_conditional_adv.c @@ -0,0 +1,343 @@ +/* + * BGP Conditional advertisement + * Copyright (C) 2020 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "bgpd/bgp_conditional_adv.h" + +const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json); + +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 bgp_path_info *pi; + 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); + assert(dest_p); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + dummy_attr = *pi->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) + bgp_attr_flush(&dummy_attr); + else { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug( + "%s: Condition map routes present in BGP table", + __func__); + + return ret; + } + } + } + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Condition map routes not present in BGP table", + __func__); + + return ret; +} + +static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, + safi_t safi, struct bgp_table *table, + struct route_map *rmap, + enum update_type update_type) +{ + int addpath_capable; + struct bgp_dest *dest; + struct bgp_path_info *pi; + 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) + return; + + subgrp = PAF_SUBGRP(paf); + /* Ignore if subgroup doesn't exist (implies AF is not negotiated) */ + if (!subgrp) + return; + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: %s routes to/from %s for %s", __func__, + update_type == ADVERTISE ? "Advertise" : "Withdraw", + peer->host, get_afi_safi_str(afi, safi, false)); + + addpath_capable = bgp_addpath_encode_tx(peer, afi, safi); + + for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { + dest_p = bgp_dest_get_prefix(dest); + assert(dest_p); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + dummy_attr = *pi->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) { + bgp_attr_flush(&dummy_attr); + continue; + } + + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) + || (addpath_capable + && bgp_addpath_tx_path( + peer->addpath_type[afi][safi], + pi))) { + + /* Skip route-map checks in + * subgroup_announce_check while executing from + * the conditional advertise scanner process. + * otherwise when route-map is also configured + * on same peer, routes in advertise-map may not + * be advertised as expected. + */ + if ((update_type == ADVERTISE) + && subgroup_announce_check(dest, pi, subgrp, + dest_p, &attr, + true)) + bgp_adj_out_set_subgroup(dest, subgrp, + &attr, pi); + else { + /* If default originate is enabled for + * the peer, do not send explicit + * withdraw. This will prevent deletion + * of default route advertised through + * default originate. + */ + if (CHECK_FLAG( + peer->af_flags[afi][safi], + PEER_FLAG_DEFAULT_ORIGINATE) + && is_default_prefix(dest_p)) + break; + + bgp_adj_out_unset_subgroup( + dest, subgrp, 1, + bgp_addpath_id_for_peer( + peer, afi, safi, + &pi->tx_addpath)); + } + } + } + } +} + +/* Handler of conditional advertisement timer event. + * Each route in the condition-map is evaluated. + */ +static int bgp_conditional_adv_timer(struct thread *t) +{ + afi_t afi; + safi_t safi; + int pfx_rcd_safi; + struct bgp *bgp = NULL; + struct peer *peer = NULL; + struct peer_af *paf = NULL; + struct bgp_table *table = NULL; + struct bgp_filter *filter = NULL; + struct listnode *node, *nnode = NULL; + struct update_subgroup *subgrp = NULL; + route_map_result_t ret; + + bgp = THREAD_ARG(t); + assert(bgp); + + thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp, + CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check); + + /* loop through each peer and advertise or withdraw routes if + * advertise-map is configured and prefix(es) in condition-map + * does exist(exist-map)/not exist(non-exist-map) in BGP table + * based on condition(exist-map or non-exist map) + */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + 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_nego[afi][safi]) + continue; + + /* labeled-unicast routes are installed in the unicast + * table so in order to display the correct PfxRcd value + * we must look at SAFI_UNICAST + */ + pfx_rcd_safi = (safi == SAFI_LABELED_UNICAST) + ? SAFI_UNICAST + : safi; + + table = bgp->rib[afi][pfx_rcd_safi]; + if (!table) + continue; + + filter = &peer->filter[afi][safi]; + + if (!filter->advmap.aname || !filter->advmap.cname + || !filter->advmap.amap || !filter->advmap.cmap) + continue; + + if (!peer->advmap_config_change[afi][safi] + && !peer->advmap_table_change) + continue; + + if (BGP_DEBUG(update, UPDATE_OUT)) { + if (peer->advmap_table_change) + zlog_debug( + "%s: %s - routes changed in BGP table.", + __func__, peer->host); + if (peer->advmap_config_change[afi][safi]) + zlog_debug( + "%s: %s for %s - advertise/condition map configuration is changed.", + __func__, peer->host, + get_afi_safi_str(afi, safi, + false)); + } + + /* cmap (route-map attached to exist-map or + * non-exist-map) map validation + */ + ret = bgp_check_rmap_prefixes_in_bgp_table( + table, filter->advmap.cmap); + + /* Derive conditional advertisement status from + * condition and return value of condition-map + * validation. + */ + if (filter->advmap.condition == CONDITION_EXIST) + filter->advmap.update_type = + (ret == RMAP_PERMITMATCH) ? ADVERTISE + : WITHDRAW; + else + filter->advmap.update_type = + (ret == RMAP_PERMITMATCH) ? WITHDRAW + : ADVERTISE; + + /* Send regular update as per the existing policy. + * There is a change in route-map, match-rule, ACLs, + * or route-map filter configuration on the same peer. + */ + if (peer->advmap_config_change[afi][safi]) { + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug( + "%s: Configuration is changed on peer %s for %s, send the normal update first.", + __func__, peer->host, + get_afi_safi_str(afi, safi, + false)); + + paf = peer_af_find(peer, afi, safi); + if (paf) { + update_subgroup_split_peer(paf, NULL); + subgrp = paf->subgroup; + if (subgrp && subgrp->update_group) + subgroup_announce_table( + paf->subgroup, NULL); + } + peer->advmap_config_change[afi][safi] = false; + } + + /* Send update as per the conditional advertisement */ + bgp_conditional_adv_routes(peer, afi, safi, table, + filter->advmap.amap, + filter->advmap.update_type); + } + peer->advmap_table_change = false; + } + return 0; +} + +void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp *bgp = peer->bgp; + + assert(bgp); + + /* This flag is used to monitor conditional routes status in BGP table, + * and advertise/withdraw routes only when there is a change in BGP + * table w.r.t conditional routes + */ + peer->advmap_config_change[afi][safi] = true; + + /* advertise-map is already configured on atleast one of its + * neighbors (AFI/SAFI). So just increment the counter. + */ + if (++bgp->condition_filter_count > 1) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: condition_filter_count %d", __func__, + bgp->condition_filter_count); + + return; + } + + /* Register for conditional routes polling timer */ + thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp, + CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check); +} + +void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp *bgp = peer->bgp; + + assert(bgp); + + /* advertise-map is not configured on any of its neighbors or + * it is configured on more than one neighbor(AFI/SAFI). + * So there's nothing to do except decrementing the counter. + */ + if (--bgp->condition_filter_count != 0) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: condition_filter_count %d", __func__, + bgp->condition_filter_count); + + return; + } + + /* Last filter removed. So cancel conditional routes polling thread. */ + THREAD_OFF(bgp->t_condition_check); +} diff --git a/bgpd/bgp_conditional_adv.h b/bgpd/bgp_conditional_adv.h new file mode 100644 index 000000000..7b5053de7 --- /dev/null +++ b/bgpd/bgp_conditional_adv.h @@ -0,0 +1,47 @@ +/* + * BGP Conditional advertisement + * Copyright (C) 2020 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_BGP_CONDITION_ADV_H +#define _FRR_BGP_CONDITION_ADV_H +#include <zebra.h> +#include "prefix.h" +#include "bgpd/bgp_addpath.h" +#include "bgpd/bgp_attr.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_debug.h" +#include "bgpd/bgp_route.h" +#include "bgpd/bgp_updgrp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Polling time for monitoring condition-map routes in route table */ +#define CONDITIONAL_ROUTES_POLL_TIME 60 + +extern void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, + safi_t safi); +extern void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, + safi_t safi); +#ifdef __cplusplus +} +#endif + +#endif /* _FRR_BGP_CONDITION_ADV_H */ diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index f1aeafced..0c527efb8 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2687,8 +2687,7 @@ void bgp_vpn_leak_export(struct bgp *from_bgp) idir = BGP_VPN_POLICY_DIR_FROMVPN; edir = BGP_VPN_POLICY_DIR_TOVPN; - export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name) - : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME)); + export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME; for (afi = 0; afi < AFI_MAX; ++afi) { /* vrf leak is for IPv4 and IPv6 Unicast only */ diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c index 551bdb0c2..333ca3cce 100644 --- a/bgpd/bgp_nb.c +++ b/bgpd/bgp_nb.c @@ -458,6 +458,8 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .create = bgp_global_afi_safis_afi_safi_create, .destroy = bgp_global_afi_safis_afi_safi_destroy, + .cli_show = cli_show_bgp_global_afi_safi_header, + .cli_show_end = cli_show_bgp_global_afi_safi_header_end, } }, { @@ -1279,8 +1281,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config", .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, } }, { @@ -1306,8 +1310,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route", .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route, } }, { @@ -1330,10 +1336,31 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route", .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, } }, { @@ -1350,6 +1377,13 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify, @@ -1387,6 +1421,14 @@ const struct frr_yang_module_info frr_bgp_info = { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, } }, { @@ -1405,8 +1447,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list", .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list, } }, { @@ -1424,24 +1468,28 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy, } }, { @@ -1456,6 +1504,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd, } }, { @@ -1477,18 +1526,21 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-vpn", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn, } }, { @@ -1496,6 +1548,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs, } }, { @@ -1503,6 +1556,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import, } }, { @@ -1510,6 +1564,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export, } }, { @@ -1543,8 +1598,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config", .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, } }, { @@ -1570,8 +1627,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route", .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route, } }, { @@ -1594,10 +1653,31 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route", .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, } }, { @@ -1614,9 +1694,58 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, } }, { @@ -1635,8 +1764,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list", .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list, } }, { @@ -1654,24 +1785,28 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy, } }, { @@ -1733,6 +1868,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import, } }, { @@ -1740,6 +1876,7 @@ const struct frr_yang_module_info frr_bgp_info = { .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify, .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export, } }, { @@ -1774,6 +1911,14 @@ const struct frr_yang_module_info frr_bgp_info = { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ebgp/maximum-paths", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, } }, { @@ -1790,9 +1935,58 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, } }, { @@ -1809,10 +2003,53 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config", .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, } }, { @@ -1838,6 +2075,7 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route", .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy, } @@ -1862,31 +2100,75 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route", .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, } }, { @@ -1933,8 +2215,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config", .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, } }, { @@ -1960,6 +2244,7 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route", .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy, } @@ -1984,31 +2269,109 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route", .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create, .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local", .cbs = { .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify, - .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy, } }, { @@ -2021,8 +2384,10 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config", .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create, .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, } }, { diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h index 341666c7e..532021425 100644 --- a/bgpd/bgp_nb.h +++ b/bgpd/bgp_nb.h @@ -568,6 +568,14 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create( struct nb_cb_create_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy( @@ -618,16 +626,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( @@ -706,6 +708,14 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_expor struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create( struct nb_cb_create_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy( @@ -716,6 +726,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_ struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify( @@ -738,16 +766,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( @@ -808,6 +830,26 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_c struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( @@ -816,6 +858,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_c struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( struct nb_cb_create_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( @@ -842,22 +902,30 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_exp struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create( struct nb_cb_create_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy( struct nb_cb_destroy_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy( - struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify( @@ -906,22 +974,48 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_exp struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( struct nb_cb_create_args *args); int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( struct nb_cb_destroy_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy( struct nb_cb_destroy_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy( struct nb_cb_destroy_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify( struct nb_cb_modify_args *args); -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy( struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify( struct nb_cb_modify_args *args); int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy( @@ -3421,10 +3515,68 @@ void cli_show_router_bgp_graceful_shutdown(struct vty *vty, bool show_defaults); void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_header(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_header_end(struct vty *vty, + struct lyd_node *dnode); +void cli_show_bgp_global_afi_safi_network_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_aggregate_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_admin_distance_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); void bgp_global_route_selection_options_apply_finish( struct nb_cb_apply_finish_args *args); void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_network_config_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_aggregate_route_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_admin_distance_route_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish( + struct nb_cb_apply_finish_args *args); /* xpath macros */ /* route-list */ @@ -3437,5 +3589,8 @@ void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args); "/frr-routing:routing/control-plane-protocols/" \ "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ "frr-bgp:bgp/local-as" +#define FRR_BGP_AFI_SAFI_REDIST_XPATH \ + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/" \ + "redistribution-list[route-type='%s'][route-instance='%s']" #endif diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index 3f0325eac..66dfa2aea 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -30,6 +30,7 @@ #include "bgpd/bgp_addpath.h" #include "bgpd/bgp_updgrp.h" #include "bgpd/bgp_io.h" +#include "bgpd/bgp_damp.h" FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, { .val_ulong = 10, .match_profile = "datacenter", }, @@ -244,7 +245,6 @@ int bgp_global_local_as_modify(struct nb_cb_modify_args *args) bgp->as); return NB_ERR_INCONSISTENCY; } - break; } @@ -2042,8 +2042,30 @@ int bgp_global_bmp_config_mirror_buffer_limit_destroy( */ int bgp_global_afi_safis_afi_safi_create(struct nb_cb_create_args *args) { + const struct lyd_node *vrf_dnode; + const char *vrf_name; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + af_name = yang_dnode_get_string(args->dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if ((!strmatch(vrf_name, VRF_DEFAULT_NAME)) + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST + && safi != SAFI_EVPN) { + snprintf( + args->errmsg, args->errmsg_len, + "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances."); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: @@ -5483,6 +5505,81 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify( return NB_OK; } +void bgp_global_afi_safis_afi_safi_network_config_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + bool is_backdoor = false; + uint32_t label_index = BGP_INVALID_LABEL_INDEX; + const char *rmap_name = NULL; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor"); + + if (yang_dnode_exists(args->dnode, "./label-index")) + label_index = + yang_dnode_get_uint32(args->dnode, "./label-index"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + bgp_static_set(bgp, NULL, &prefix, afi, safi, rmap_name, is_backdoor, + label_index, args->errmsg, args->errmsg_len); +} + +static int bgp_global_afi_safis_afi_safi_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + uint32_t label_index = BGP_INVALID_LABEL_INDEX; + const char *rmap_name = NULL; + bool is_backdoor = false; + afi_t afi; + safi_t safi; + int ret; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + if (yang_dnode_exists(args->dnode, "./label-index")) + label_index = + yang_dnode_get_uint32(args->dnode, "./label-index"); + + if (yang_dnode_exists(args->dnode, "./backdoor")) + is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor"); + + ret = bgp_static_set(bgp, "no", &prefix, afi, safi, rmap_name, + is_backdoor, label_index, args->errmsg, + args->errmsg_len); + if (ret < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config @@ -5490,40 +5587,120 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify( int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create( struct nb_cb_create_args *args) { + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + break; } return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) { + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + uint32_t label_index; + afi_t afi; + safi_t safi; + struct bgp_dest *dest; + struct bgp_static *bgp_static; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + yang_dnode_get_prefix(&prefix, args->dnode, "../prefix"); + apply_mask(&prefix); + + label_index = yang_dnode_get_uint32(args->dnode, NULL); + + dest = bgp_node_get(bgp->route[afi][safi], &prefix); + bgp_static = bgp_dest_get_bgp_static_info(dest); + if (bgp_static) { + if (bgp_static->label_index != label_index) { + snprintf( + args->errmsg, args->errmsg_len, + "Cannot change label-index: curr %u input %u\n", + bgp_static->label_index, label_index); + return NB_ERR_VALIDATION; + } + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } return NB_OK; } +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify( struct nb_cb_modify_args *args) { + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + /* rmap destory alone is not supported by backend, the entire network + * config needs to be destroyed. + */ switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: @@ -5536,12 +5713,82 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify( return NB_OK; } +void bgp_global_afi_safi_aggregate_route_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + const char *rmap_name = NULL; + afi_t afi; + safi_t safi; + uint8_t as_set = 0; + int summary_only = 0; + uint8_t origin = BGP_ORIGIN_UNSPECIFIED; + bool match_med = false; + const char *suppress_map = NULL; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + if (yang_dnode_exists(args->dnode, "./as-set")) + as_set = yang_dnode_get_bool(args->dnode, "./as-set"); + + summary_only = yang_dnode_get_bool(args->dnode, "./summary-only"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + origin = yang_dnode_get_enum(args->dnode, "./origin"); + match_med = yang_dnode_get_bool(args->dnode, "./match-med"); + if (yang_dnode_exists(args->dnode, "./suppress-map")) + suppress_map = + yang_dnode_get_string(args->dnode, "./suppress-map"); + + bgp_aggregate_set(bgp, &prefix, afi, safi, rmap_name, summary_only, + as_set, origin, match_med, suppress_map, args->errmsg, + args->errmsg_len); +} + +static int +bgp_global_afi_safi_aggregate_route_destroy(struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + afi_t afi; + safi_t safi; + int ret; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + ret = bgp_aggregate_unset(bgp, &prefix, afi, safi, args->errmsg, + args->errmsg_len); + + if (ret < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify( - struct nb_cb_modify_args *args) +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create( + struct nb_cb_create_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -5555,16 +5802,16 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_aggregate_route_destroy(args); } return NB_OK; @@ -5572,9 +5819,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destro /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -5589,8 +5836,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -5606,10 +5857,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create( - struct nb_cb_create_args *args) +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -5623,7 +5874,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -5640,9 +5891,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -5659,9 +5910,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -5678,9 +5929,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modi /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -5695,7 +5946,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -5710,6 +5961,60 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor return NB_OK; } +void bgp_global_afi_safi_admin_distance_route_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + const char *af_name; + const char *prefix_str = NULL; + const char *access_list_str = NULL; + uint8_t distance; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + prefix_str = yang_dnode_get_string(args->dnode, "./prefix"); + distance = yang_dnode_get_uint8(args->dnode, "./distance"); + if (yang_dnode_exists(args->dnode, "./access-list-policy-export")) + access_list_str = yang_dnode_get_string( + args->dnode, "./access-list-policy-export"); + + bgp_distance_set(distance, prefix_str, access_list_str, afi, safi, + args->errmsg, args->errmsg_len); +} + +static int bgp_global_afi_safi_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + const char *af_name; + const char *prefix_str = NULL; + const char *access_list_str = NULL; + uint8_t distance; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + prefix_str = yang_dnode_get_string(args->dnode, "./prefix"); + distance = yang_dnode_get_uint8(args->dnode, "./distance"); + if (yang_dnode_exists(args->dnode, "./access-list-policy-export")) + access_list_str = yang_dnode_get_string( + args->dnode, "./access-list-policy-export"); + + if (bgp_distance_unset(distance, prefix_str, access_list_str, afi, safi, + args->errmsg, args->errmsg_len) + != CMD_SUCCESS) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route @@ -5736,9 +6041,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_admin_distance_route_destroy(args); } return NB_OK; @@ -5797,6 +6102,68 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_ return NB_OK; } +void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int half = DEFAULT_HALF_LIFE * 60; + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + int max; + char ab_xpath[XPATH_MAXLEN]; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!yang_dnode_get_bool(args->dnode, "./enable")) { + bgp_damp_disable(bgp, afi, safi); + } else { + half = yang_dnode_get_uint8(args->dnode, "./reach-decay"); + half *= 60; + reuse = yang_dnode_get_uint16(args->dnode, "./reuse-above"); + + suppress = + yang_dnode_get_uint16(args->dnode, "./suppress-above"); + + max = yang_dnode_get_uint8(args->dnode, "./unreach-decay"); + yang_dnode_get_path(args->dnode, ab_xpath, sizeof(ab_xpath)); + strlcat(ab_xpath, "/unreach-decay", sizeof(ab_xpath)); + if (yang_get_default_uint8(ab_xpath) == max) + max = half * 4; + else + max *= 60; + + bgp_damp_enable(bgp, afi, safi, half, reuse, suppress, max); + } +} + +static int +bgp_global_afi_safi_route_flap_validation(struct nb_cb_modify_args *args) +{ + int reuse; + int suppress; + + if (yang_dnode_exists(args->dnode, "../supress-above") + && yang_dnode_exists(args->dnode, "../reuse-above")) { + suppress = + yang_dnode_get_uint16(args->dnode, "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + } + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable @@ -5806,10 +6173,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modif { switch (args->event) { case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } @@ -5857,8 +6224,22 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify( struct nb_cb_modify_args *args) { + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + switch (args->event) { case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../suppress-above")) + suppress = yang_dnode_get_uint16(args->dnode, + "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: @@ -5952,6 +6333,45 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_deca return NB_OK; } +static int +bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + uint16_t maxpaths, default_maxpaths; + int ret; + char xpath[XPATH_MAXLEN]; + char afi_xpath[XPATH_MAXLEN]; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + + snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp", + "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME); + snprintf( + afi_xpath, sizeof(afi_xpath), + "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + strlcat(xpath, afi_xpath, sizeof(xpath)); + default_maxpaths = yang_get_default_uint16(xpath); + + ret = bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_EBGP, maxpaths, + 0, maxpaths != default_maxpaths ? 1 : 0, + args->errmsg, args->errmsg_len); + if (ret != CMD_SUCCESS) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths @@ -5959,13 +6379,24 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_deca int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify( struct nb_cb_modify_args *args) { + uint16_t maxpaths; + switch (args->event) { case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); } return NB_OK; @@ -5973,17 +6404,68 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_p /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp + */ +void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + uint16_t maxpaths, default_maxpaths; + char xpath[XPATH_MAXLEN]; + char afi_xpath[XPATH_MAXLEN]; + uint16_t options = 0; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + maxpaths = yang_dnode_get_uint16(args->dnode, "./maximum-paths"); + if (yang_dnode_get_bool(args->dnode, "./cluster-length-list")) + options = BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN; + + snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp", + "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME); + snprintf( + afi_xpath, sizeof(afi_xpath), + "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + strlcat(xpath, afi_xpath, sizeof(xpath)); + default_maxpaths = yang_get_default_uint16(xpath); + + bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_IBGP, maxpaths, + options, maxpaths != default_maxpaths ? 1 : 0, + args->errmsg, args->errmsg_len); +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/maximum-paths */ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify( struct nb_cb_modify_args *args) { + uint16_t maxpaths; + switch (args->event) { case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ break; } @@ -6024,6 +6506,49 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_l return NB_OK; } +void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + struct bgp_redist *red; + bool changed = false; + struct route_map *route_map = NULL; + const char *rmap_name = NULL; + uint32_t metric = 0; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = yang_dnode_get_uint16(args->dnode, "./route-instance"); + + red = bgp_redist_add(bgp, afi, route_type, route_instance); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-import")) { + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-import"); + route_map = route_map_lookup_by_name(rmap_name); + + changed = bgp_redistribute_rmap_set(red, rmap_name, route_map); + } + + if (yang_dnode_exists(args->dnode, "./metric")) { + metric = yang_dnode_get_uint32(args->dnode, "./metric"); + changed |= bgp_redistribute_metric_set(bgp, red, afi, + route_type, metric); + } + + bgp_redistribute_set(bgp, afi, route_type, route_instance, changed); +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list @@ -6046,12 +6571,31 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create( int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy( struct nb_cb_destroy_args *args) { + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = + yang_dnode_get_uint16(args->dnode, "./route-instance"); + + bgp_redistribute_unset(bgp, afi, route_type, route_instance); + break; } @@ -6126,36 +6670,52 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i return NB_OK; } +static int +bgp_global_afi_safis_admin_distance_modify(struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + uint8_t distance_ebgp, distance_ibgp, distance_local; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + distance_ebgp = yang_dnode_get_uint8(args->dnode, "./external"); + distance_ibgp = yang_dnode_get_uint8(args->dnode, "./internal"); + distance_local = yang_dnode_get_uint8(args->dnode, "./local"); + + bgp->distance_ebgp[afi][safi] = distance_ebgp; + bgp->distance_ibgp[afi][safi] = distance_ibgp; + bgp->distance_local[afi][safi] = distance_local; + + bgp_announce_routes_distance_update(bgp, afi, safi); + + return NB_OK; +} + /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify( - struct nb_cb_modify_args *args) +void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + bgp_global_afi_safis_admin_distance_modify(args); } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in admin_distance_apply_finish callback */ return NB_OK; } @@ -6167,38 +6727,28 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy( int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in admin_distance_apply_finish callback */ return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in admin_distance_apply_finish callback */ return NB_OK; } /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -6213,7 +6763,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -6228,37 +6778,80 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy( return NB_OK; } -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export - */ -int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( +static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rd_str = NULL; + struct prefix_rd prd; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + rd_str = yang_dnode_get_string(args->dnode, NULL); + if (!str2prefix_rd(rd_str, &prd)) { + snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s\n", + rd_str); + return NB_ERR_INCONSISTENCY; } + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + bgp->vpn_policy[afi].tovpn_rd = prd; + SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( +static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( struct nb_cb_destroy_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rd_str = NULL; + struct prefix_rd prd; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + rd_str = yang_dnode_get_string(args->dnode, NULL); + if (str2prefix_rd(rd_str, &prd)) { + snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s \n", + rd_str); + return NB_ERR_INCONSISTENCY; } + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); return NB_OK; } @@ -6269,12 +6862,34 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( + args); + break; } @@ -6288,9 +6903,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( + args); } return NB_OK; @@ -6364,6 +6980,69 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy( return NB_OK; } +static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + struct prefix p; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&p, args->dnode, NULL); + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + bgp->vpn_policy[afi].tovpn_nexthop = p; + SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + struct prefix p; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&p, args->dnode, NULL); + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop @@ -6371,13 +7050,32 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy( int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + args); } return NB_OK; @@ -6390,9 +7088,59 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + args); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + struct nb_cb_modify_args *args, const char *direction_str, + bool is_enable) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int previous_state; + int flag; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(direction_str, "import")) { + flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT; + dir = BGP_VPN_POLICY_DIR_FROMVPN; + } else if (!strcmp(direction_str, "export")) { + flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT; + dir = BGP_VPN_POLICY_DIR_TOVPN; + } else { + snprintf(args->errmsg, args->errmsg_len, + "unknown direction %s\n", direction_str); + return NB_ERR_INCONSISTENCY; + } + + previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag); + + if (is_enable) { + SET_FLAG(bgp->af_flags[afi][safi], flag); + if (!previous_state) { + /* trigger export current vrf */ + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + } + } else { + if (previous_state) { + /* trigger un-export current vrf */ + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + } + UNSET_FLAG(bgp->af_flags[afi][safi], flag); } return NB_OK; @@ -6405,13 +7153,33 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy( int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify( struct nb_cb_modify_args *args) { + bool is_enable = false; + struct bgp *bgp; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type + && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { + snprintf( + args->errmsg, args->errmsg_len, + "import|export vpn valid only for bgp vrf or default instance"); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + if (yang_dnode_get_bool(args->dnode, NULL)) + is_enable = true; + + return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + args, "import", is_enable); } return NB_OK; @@ -6424,18 +7192,184 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify( int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify( struct nb_cb_modify_args *args) { + bool is_enable = false; + struct bgp *bgp; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type + && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { + snprintf( + args->errmsg, args->errmsg_len, + "import|export vpn valid only for bgp vrf or default instance"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + if (yang_dnode_get_bool(args->dnode, NULL)) + is_enable = true; + + return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + args, "export", is_enable); } return NB_OK; } + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + struct nb_cb_create_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret = 0; + as_t as; + struct bgp *vrf_bgp, *bgp_default; + const char *import_name; + char *vname; + enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + struct listnode *node; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + as = bgp->as; + import_name = yang_dnode_get_string(args->dnode, "./vrf"); + + if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) + && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) + || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { + snprintf(args->errmsg, args->errmsg_len, + "Cannot %s vrf %s into itself\n", "import", + import_name); + return NB_ERR_INCONSISTENCY; + } + + bgp_default = bgp_get_default(); + if (!bgp_default) { + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); + + if (ret) { + snprintf( + args->errmsg, args->errmsg_len, + "VRF default is not configured as a bgp instance"); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_bgp = bgp_lookup_by_name(import_name); + if (!vrf_bgp) { + if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) + vrf_bgp = bgp_default; + else + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); + + if (ret) { + snprintf(args->errmsg, args->errmsg_len, + "VRF %s is not configured as a bgp instance\n", + import_name); + return NB_ERR_INCONSISTENCY; + } + } + + /* Already importing from "import_vrf"? */ + for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node, + vname)) { + if (strcmp(vname, import_name) == 0) { + snprintf(args->errmsg, args->errmsg_len, + "already importing from vrf %s", import_name); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_import_from_vrf(bgp, vrf_bgp, afi, safi); + + return NB_OK; +} + + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret = 0; + as_t as; + struct bgp *vrf_bgp, *bgp_default; + const char *import_name; + enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + as = bgp->as; + import_name = yang_dnode_get_string(args->dnode, "./vrf"); + + if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) + && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) + || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { + snprintf(args->errmsg, args->errmsg_len, + "Cannot %s vrf %s into itself\n", "unimport", + import_name); + return NB_ERR_INCONSISTENCY; + } + + bgp_default = bgp_get_default(); + if (!bgp_default) { + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); + + if (ret) { + snprintf( + args->errmsg, args->errmsg_len, "%s", + "VRF default is not configured as a bgp instance"); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_bgp = bgp_lookup_by_name(import_name); + if (!vrf_bgp) { + if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) + vrf_bgp = bgp_default; + else + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); + + if (ret) { + snprintf(args->errmsg, args->errmsg_len, + "VRF %s is not configured as a bgp instance\n", + import_name); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi); + + return NB_OK; +} + + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vrf-list @@ -6443,13 +7377,32 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify( int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create( struct nb_cb_create_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg, + args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + args); } return NB_OK; @@ -6462,9 +7415,104 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destro case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + args); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args, const char *dstr) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rmap_str = NULL; + int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(dstr, "import")) { + rmap_str = yang_dnode_get_string(args->dnode, NULL); + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + } else if (!strcmp(dstr, "export")) { + rmap_str = yang_dnode_get_string(args->dnode, NULL); + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else if (!strcmp(dstr, "both")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } + + for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { + if (!dodir[dir]) + continue; + + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str); + bgp->vpn_policy[afi].rmap[dir] = + route_map_lookup_by_name(rmap_str); + if (!bgp->vpn_policy[afi].rmap[dir]) + return NB_OK; + + + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args, const char *dstr) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(dstr, "import")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + } else if (!strcmp(dstr, "export")) { + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else if (!strcmp(dstr, "both")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } + + for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { + if (!dodir[dir]) + continue; + + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = NULL; + bgp->vpn_policy[afi].rmap[dir] = NULL; + + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); } return NB_OK; @@ -6477,13 +7525,31 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destro int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "import"); } return NB_OK; @@ -6492,13 +7558,31 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify( int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy( struct nb_cb_destroy_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "import"); } return NB_OK; @@ -6515,9 +7599,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "export"); } return NB_OK; @@ -6530,8 +7615,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "export"); break; } @@ -6681,19 +7768,53 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy( int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create( struct nb_cb_create_args *args) { + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); break; } return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy( +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -6710,11 +7831,19 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify( struct nb_cb_modify_args *args) { + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: @@ -6729,10 +7858,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify( - struct nb_cb_modify_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create( + struct nb_cb_create_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -6746,16 +7875,16 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_aggregate_route_destroy(args); } return NB_OK; @@ -6763,9 +7892,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destro /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -6780,8 +7909,12 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -6797,10 +7930,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create( - struct nb_cb_create_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -6814,7 +7947,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -6831,9 +7964,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -6850,9 +7983,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -6869,9 +8002,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modi /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -6886,7 +8019,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_expor return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -6927,9 +8060,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_admin_distance_route_destroy(args); } return NB_OK; @@ -6990,17 +8123,17 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_ /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify( struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } @@ -7009,9 +8142,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_p /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7026,15 +8159,44 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_p return NB_OK; } +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify( struct nb_cb_modify_args *args) { + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + switch (args->event) { case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../suppress-above")) + suppress = yang_dnode_get_uint16(args->dnode, + "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: @@ -7045,7 +8207,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_l return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7062,10 +8224,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_l /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create( - struct nb_cb_create_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -7079,7 +8241,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7096,9 +8258,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7113,7 +8275,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7130,9 +8292,39 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destro /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7147,7 +8339,26 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy( +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7164,10 +8375,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( - struct nb_cb_modify_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create( + struct nb_cb_create_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -7181,15 +8392,34 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy( struct nb_cb_destroy_args *args) { + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = + yang_dnode_get_uint16(args->dnode, "./route-instance"); + + bgp_redistribute_unset(bgp, afi, route_type, route_instance); + break; } @@ -7198,9 +8428,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7215,7 +8445,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7232,9 +8462,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import */ -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7249,7 +8479,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7266,6 +8496,52 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy( /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export */ int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( @@ -7305,13 +8581,33 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( + args); } return NB_OK; @@ -7324,9 +8620,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( + args); } return NB_OK; @@ -7407,13 +8704,33 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy( int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + args); } return NB_OK; @@ -7426,9 +8743,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + args); } return NB_OK; @@ -7479,13 +8797,32 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify( int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create( struct nb_cb_create_args *args) { + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg, + args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + args); } return NB_OK; @@ -7498,9 +8835,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destro case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + args); } return NB_OK; @@ -7517,9 +8855,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "import"); } return NB_OK; @@ -7532,9 +8871,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "import"); } return NB_OK; @@ -7551,9 +8891,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "export"); } return NB_OK; @@ -7566,9 +8907,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "export"); } return NB_OK; @@ -7717,13 +9059,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy( int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( struct nb_cb_modify_args *args) { + uint16_t maxpaths; + switch (args->event) { case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); } return NB_OK; @@ -7784,9 +9137,130 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_c /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable */ -int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -7801,6 +9275,51 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_m return NB_OK; } +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/maximum-paths @@ -7808,8 +9327,18 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_m int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( struct nb_cb_modify_args *args) { + uint16_t maxpaths; + switch (args->event) { case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: @@ -7856,10 +9385,29 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_c /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable */ -int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( - struct nb_cb_create_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -7873,7 +9421,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -7890,6 +9438,137 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( + struct nb_cb_create_args *args) +{ + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor */ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify( @@ -8083,6 +9762,78 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_exp /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route */ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create( @@ -8107,6 +9858,25 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_admin_distance_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: case NB_EV_APPLY: /* TODO: implement me. */ break; @@ -8117,9 +9887,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export */ -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -8134,7 +9904,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy( +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -8151,9 +9921,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance */ -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -8168,7 +9938,26 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy( +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -8185,9 +9974,28 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable */ -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -8202,7 +10010,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -8219,6 +10027,154 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy( /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable */ int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify( @@ -8226,10 +10182,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_mod { switch (args->event) { case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } @@ -8413,14 +10369,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destr int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create( struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in network_config_apply_finish callback */ return NB_OK; } @@ -8432,8 +10381,11 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy( case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + break; } @@ -8635,10 +10587,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_exp /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin */ -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( - struct nb_cb_create_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -8652,8 +10604,12 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -8669,9 +10625,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map */ -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify( struct nb_cb_modify_args *args) { switch (args->event) { @@ -8686,7 +10642,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { @@ -8703,10 +10659,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route */ -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( - struct nb_cb_modify_args *args) +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( + struct nb_cb_create_args *args) { switch (args->event) { case NB_EV_VALIDATE: @@ -8720,16 +10676,16 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy( +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( struct nb_cb_destroy_args *args) { switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_global_afi_safi_admin_distance_route_destroy(args); } return NB_OK; @@ -8737,34 +10693,46 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance */ -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( +void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in admin_distance_apply_finish callback */ return NB_OK; } -int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ return NB_OK; } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 2ebac5667..a23acda0a 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -403,12 +403,13 @@ int bgp_generate_updgrp_packets(struct thread *thread) /* * The code beyond this part deals with update packets, proceed only * if peer is Established and updates are not on hold (as part of - * update-delay post processing). + * update-delay processing). */ if (peer->status != Established) return 0; - if (peer->bgp->main_peers_update_hold) + if ((peer->bgp->main_peers_update_hold) + || bgp_update_delay_active(peer->bgp)) return 0; if (peer->t_routeadv) @@ -1782,6 +1783,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) peer->update_time = bgp_clock(); + /* Notify BGP Conditional advertisement scanner process */ + peer->advmap_table_change = true; + return Receive_UPDATE_message; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b637191d1..52e90f5c6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -85,6 +85,9 @@ #include "bgpd/bgp_flowspec.h" #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_pbr.h" +#include "northbound.h" +#include "northbound_cli.h" +#include "bgpd/bgp_nb.h" #ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_route_clippy.c" @@ -1657,6 +1660,33 @@ void bgp_attr_add_gshut_community(struct attr *attr) } +/* Notify BGP Conditional advertisement scanner process. */ +void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp) +{ + struct peer *temp_peer; + struct peer *peer = SUBGRP_PEER(subgrp); + struct listnode *temp_node, *temp_nnode = NULL; + afi_t afi = SUBGRP_AFI(subgrp); + safi_t safi = SUBGRP_SAFI(subgrp); + struct bgp *bgp = SUBGRP_INST(subgrp); + struct bgp_filter *filter = &peer->filter[afi][safi]; + + if (!ADVERTISE_MAP_NAME(filter)) + return; + + for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + continue; + + if (peer != temp_peer) + continue; + + temp_peer->advmap_table_change = true; + break; + } +} + + static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) { if (family == AF_INET) { @@ -1671,7 +1701,8 @@ static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, - const struct prefix *p, struct attr *attr) + const struct prefix *p, struct attr *attr, + bool skip_rmap_check) { struct bgp_filter *filter; struct peer *from; @@ -1986,7 +2017,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_peer_as_override(bgp, afi, safi, peer, attr); /* Route map & unsuppress-map apply. */ - if (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi)) { + if (!skip_rmap_check + && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) { struct bgp_path_info rmap_path = {0}; struct bgp_path_info_extra dummy_rmap_path_extra = {0}; struct attr dummy_attr = {0}; @@ -2484,7 +2516,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, /* Announcement to the subgroup. If the route is filtered withdraw it. */ if (selected) { - if (subgroup_announce_check(dest, selected, subgrp, p, &attr)) + if (subgroup_announce_check(dest, selected, subgrp, p, &attr, + false)) bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected); else bgp_adj_out_unset_subgroup(dest, subgrp, 1, @@ -4357,6 +4390,10 @@ static int bgp_announce_route_timer_expired(struct thread *t) return 0; peer_af_announce_route(paf, 1); + + /* Notify BGP conditional advertisement scanner percess */ + peer->advmap_config_change[paf->afi][paf->safi] = true; + return 0; } @@ -5584,28 +5621,16 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, /* Configure static BGP network. When user don't run zebra, static route should be installed as valid. */ -static int bgp_static_set(struct vty *vty, const char *negate, - const char *ip_str, afi_t afi, safi_t safi, - const char *rmap, int backdoor, uint32_t label_index) +int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx, + afi_t afi, safi_t safi, const char *rmap, int backdoor, + uint32_t label_index, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; struct prefix p; struct bgp_static *bgp_static; struct bgp_dest *dest; uint8_t need_update = 0; - /* Convert IP prefix string to struct prefix. */ - ret = str2prefix(ip_str, &p); - if (!ret) { - vty_out(vty, "%% Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) { - vty_out(vty, "%% Malformed prefix (link-local address)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - + prefix_copy(&p, pfx); apply_mask(&p); if (negate) { @@ -5614,24 +5639,25 @@ static int bgp_static_set(struct vty *vty, const char *negate, dest = bgp_node_lookup(bgp->route[afi][safi], &p); if (!dest) { - vty_out(vty, "%% Can't find static route specified\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "Can't find static route specified\n"); + return -1; } bgp_static = bgp_dest_get_bgp_static_info(dest); if ((label_index != BGP_INVALID_LABEL_INDEX) && (label_index != bgp_static->label_index)) { - vty_out(vty, - "%% label-index doesn't match static route\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "label-index doesn't match static route\n"); + return -1; } if ((rmap && bgp_static->rmap.name) && strcmp(rmap, bgp_static->rmap.name)) { - vty_out(vty, - "%% route-map name doesn't match static route\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "route-map name doesn't match static route\n"); + return -1; } /* Update BGP RIB. */ @@ -5652,8 +5678,9 @@ static int bgp_static_set(struct vty *vty, const char *negate, /* Configuration change. */ /* Label index cannot be changed. */ if (bgp_static->label_index != label_index) { - vty_out(vty, "%% cannot change label-index\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "cannot change label-index\n"); + return -1; } /* Check previous routes are installed into BGP. */ @@ -5715,7 +5742,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, bgp_static_update(bgp, &p, bgp_static, afi, safi); } - return CMD_SUCCESS; + return 0; } void bgp_static_add(struct bgp *bgp) @@ -6165,25 +6192,27 @@ DEFUN (no_bgp_table_map, argv[idx_word]->arg); } -DEFPY(bgp_network, - bgp_network_cmd, - "[no] network \ - <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \ - [{route-map WORD$map_name|label-index (0-1048560)$label_index| \ - backdoor$backdoor}]", - NO_STR - "Specify a network to announce via BGP\n" - "IPv4 prefix\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "Route-map to modify the attributes\n" - "Name of the route map\n" - "Label index to associate with the prefix\n" - "Label index value\n" - "Specify a BGP backdoor route\n") -{ - char addr_prefix_str[BUFSIZ]; +DEFPY_YANG (bgp_network, bgp_network_cmd, + "[no] network \ + <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \ + [{route-map WORD$map_name|label-index (0-1048560)$label_index| \ + backdoor$backdoor}]", + NO_STR + "Specify a network to announce via BGP\n" + "IPv4 prefix\n" + "Network number\n" + "Network mask\n" + "Network mask\n" + "Route-map to modify the attributes\n" + "Name of the route map\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Specify a BGP backdoor route\n") +{ + char addr_prefix_str[PREFIX_STRLEN]; + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; if (address_str) { int ret; @@ -6196,27 +6225,102 @@ DEFPY(bgp_network, } } - return bgp_static_set( - vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP, - bgp_node_safi(vty), map_name, backdoor ? 1 : 0, - label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + if (map_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_CREATE, map_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); + + if (label_index_str) + nb_cli_enqueue_change(vty, "./label-index", + NB_OP_MODIFY, label_index_str); + + nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY, + backdoor ? "true" : "false"); + } + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), + address_str ? addr_prefix_str : prefix_str); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFPY(ipv6_bgp_network, - ipv6_bgp_network_cmd, - "[no] network X:X::X:X/M$prefix \ - [{route-map WORD$map_name|label-index (0-1048560)$label_index}]", - NO_STR - "Specify a network to announce via BGP\n" - "IPv6 prefix\n" - "Route-map to modify the attributes\n" - "Name of the route map\n" - "Label index to associate with the prefix\n" - "Label index value\n") +DEFPY_YANG (ipv6_bgp_network, + ipv6_bgp_network_cmd, + "[no] network X:X::X:X/M$prefix \ + [{route-map WORD$map_name|label-index (0-1048560)$label_index}]", + NO_STR + "Specify a network to announce via BGP\n" + "IPv6 prefix\n" + "Route-map to modify the attributes\n" + "Name of the route map\n" + "Label index to associate with the prefix\n" + "Label index value\n") +{ + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + if (map_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_MODIFY, map_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); + + if (label_index_str) + nb_cli_enqueue_change(vty, "./label-index", + NB_OP_MODIFY, label_index_str); + } + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), prefix_str); + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_bgp_global_afi_safi_network_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - return bgp_static_set( - vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0, - label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix")); + + if (yang_dnode_exists(dnode, "./label-index")) + vty_out(vty, " label-index %s", + yang_dnode_get_string(dnode, "./label-index")); + + if (yang_dnode_exists(dnode, "./rmap-policy-export")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-export")); + + if (yang_dnode_get_bool(dnode, "./backdoor")) + vty_out(vty, " backdoor"); + + vty_out(vty, "\n"); } static struct bgp_aggregate *bgp_aggregate_new(void) @@ -7246,35 +7350,25 @@ static const char *bgp_origin2str(uint8_t origin) return "n/a"; } -static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str, - afi_t afi, safi_t safi) +int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - struct prefix p; struct bgp_dest *dest; struct bgp_aggregate *aggregate; - /* Convert string to prefix structure. */ - ret = str2prefix(prefix_str, &p); - if (!ret) { - vty_out(vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask(&p); - + apply_mask(prefix); /* Old configuration check. */ - dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p); + dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix); if (!dest) { - vty_out(vty, - "%% There is no aggregate-address configuration.\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "There is no aggregate-address configuration.\n"); + return -1; } aggregate = bgp_dest_get_bgp_aggregate_info(dest); - bgp_aggregate_delete(bgp, &p, afi, safi, aggregate); - bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, - NULL, NULL, 0, aggregate); + bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate); + bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL, + 0, aggregate); /* Unlock aggregate address configuration. */ bgp_dest_set_bgp_aggregate_info(dest, NULL); @@ -7335,55 +7429,53 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str, bgp_dest_unlock_node(dest); bgp_dest_unlock_node(dest); - return CMD_SUCCESS; + return 0; } -static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, - safi_t safi, const char *rmap, - uint8_t summary_only, uint8_t as_set, - uint8_t origin, bool match_med, - const char *suppress_map) +int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, const char *rmap, uint8_t summary_only, + uint8_t as_set, uint8_t origin, bool match_med, + const char *suppress_map, + char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; - struct prefix p; struct bgp_dest *dest; struct bgp_aggregate *aggregate; uint8_t as_set_new = as_set; + char buf[PREFIX2STR_BUFFER]; if (suppress_map && summary_only) { - vty_out(vty, + snprintf(errmsg, errmsg_len, "'summary-only' and 'suppress-map' can't be used at the same time\n"); - return CMD_WARNING_CONFIG_FAILED; + return -1; } - /* Convert string to prefix structure. */ - ret = str2prefix(prefix_str, &p); - if (!ret) { - vty_out(vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask(&p); + apply_mask(prefix); - if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) || - (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) { - vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n", - prefix_str); - return CMD_WARNING_CONFIG_FAILED; + if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN) + || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) { + snprintf( + errmsg, errmsg_len, + "Specified prefix: %s will not result in any useful aggregation, disallowing\n", + prefix2str(prefix, buf, PREFIX_STRLEN)); + return -1; } /* Old configuration check. */ - dest = bgp_node_get(bgp->aggregate[afi][safi], &p); + dest = bgp_node_get(bgp->aggregate[afi][safi], prefix); aggregate = bgp_dest_get_bgp_aggregate_info(dest); if (aggregate) { - vty_out(vty, "There is already same aggregate network.\n"); + snprintf(errmsg, errmsg_len, + "There is already same aggregate network.\n"); /* try to remove the old entry */ - ret = bgp_aggregate_unset(vty, prefix_str, afi, safi); + ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg, + errmsg_len); if (ret) { - vty_out(vty, "Error deleting aggregate.\n"); + snprintf(errmsg, errmsg_len, + "Error deleting aggregate.\n"); bgp_dest_unlock_node(dest); - return CMD_WARNING_CONFIG_FAILED; + return -1; } } @@ -7406,7 +7498,8 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, zlog_warn( "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.", __func__); - vty_out(vty, + snprintf( + errmsg, errmsg_len, "Ignoring as-set because `bgp reject-as-sets` is enabled.\n"); } } @@ -7443,39 +7536,40 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, bgp_dest_set_bgp_aggregate_info(dest, aggregate); /* Aggregate address insert into BGP routing table. */ - bgp_aggregate_route(bgp, &p, afi, safi, aggregate); + bgp_aggregate_route(bgp, prefix, afi, safi, aggregate); - return CMD_SUCCESS; + return 0; } -DEFPY(aggregate_addressv4, aggregate_addressv4_cmd, - "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {" - "as-set$as_set_s" - "|summary-only$summary_only" - "|route-map WORD$rmap_name" - "|origin <egp|igp|incomplete>$origin_s" - "|matching-MED-only$match_med" - "|suppress-map WORD$suppress_map" - "}", - NO_STR - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Apply route map to aggregate network\n" - "Route map name\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n" - "Only aggregate routes with matching MED\n" - "Suppress the selected more specific routes\n" - "Route map with the route selectors\n") -{ - const char *prefix_s = NULL; +DEFPY_YANG( + aggregate_addressv4, aggregate_addressv4_cmd, + "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {" + "as-set$as_set_s" + "|summary-only$summary_only" + "|route-map WORD$rmap_name" + "|origin <egp|igp|incomplete>$origin_s" + "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" + "}", + NO_STR + "Configure BGP aggregate entries\n" + "Aggregate prefix\n" + "Aggregate address\n" + "Aggregate mask\n" + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Apply route map to aggregate network\n" + "Route map name\n" + "BGP origin code\n" + "Remote EGP\n" + "Local IGP\n" + "Unknown heritage\n" + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") +{ + char base_xpath[XPATH_MAXLEN]; safi_t safi = bgp_node_safi(vty); - uint8_t origin = BGP_ORIGIN_UNSPECIFIED; - int as_set = AGGREGATE_AS_UNSET; char prefix_buf[PREFIX2STR_BUFFER]; if (addr_str) { @@ -7484,78 +7578,158 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd, vty_out(vty, "%% Inconsistent address and mask\n"); return CMD_WARNING_CONFIG_FAILED; } - prefix_s = prefix_buf; - } else - prefix_s = prefix_str; - - if (origin_s) { - if (strcmp(origin_s, "egp") == 0) - origin = BGP_ORIGIN_EGP; - else if (strcmp(origin_s, "igp") == 0) - origin = BGP_ORIGIN_IGP; - else if (strcmp(origin_s, "incomplete") == 0) - origin = BGP_ORIGIN_INCOMPLETE; + } else { + strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf)); } - if (as_set_s) - as_set = AGGREGATE_AS_SET; + if (!no && origin_s) + nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s); + + if (!no && as_set_s) + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false"); + + if (!no && summary_only) + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "true"); + else + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "false"); + + if (!no && match_med) + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, + "false"); + + if (rmap_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY, + rmap_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); + + if (suppress_map) + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY, + suppress_map); + else + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY, + NULL); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']", + yang_afi_safi_value2identity(AFI_IP, safi), + bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf); - /* Handle configuration removal, otherwise installation. */ if (no) - return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi); - - return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name, - summary_only != NULL, as_set, origin, - match_med != NULL, suppress_map); -} - -DEFPY(aggregate_addressv6, aggregate_addressv6_cmd, - "[no] aggregate-address X:X::X:X/M$prefix {" - "as-set$as_set_s" - "|summary-only$summary_only" - "|route-map WORD$rmap_name" - "|origin <egp|igp|incomplete>$origin_s" - "|matching-MED-only$match_med" - "|suppress-map WORD$suppress_map" - "}", - NO_STR - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Apply route map to aggregate network\n" - "Route map name\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n" - "Only aggregate routes with matching MED\n" - "Suppress the selected more specific routes\n" - "Route map with the route selectors\n") -{ - uint8_t origin = BGP_ORIGIN_UNSPECIFIED; - int as_set = AGGREGATE_AS_UNSET; - - if (origin_s) { - if (strcmp(origin_s, "egp") == 0) - origin = BGP_ORIGIN_EGP; - else if (strcmp(origin_s, "igp") == 0) - origin = BGP_ORIGIN_IGP; - else if (strcmp(origin_s, "incomplete") == 0) - origin = BGP_ORIGIN_INCOMPLETE; - } - - if (as_set_s) - as_set = AGGREGATE_AS_SET; - - /* Handle configuration removal, otherwise installation. */ + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); +} + +DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd, + "[no] aggregate-address X:X::X:X/M$prefix {" + "as-set$as_set_s" + "|summary-only$summary_only" + "|route-map WORD$rmap_name" + "|origin <egp|igp|incomplete>$origin_s" + "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" + "}", + NO_STR + "Configure BGP aggregate entries\n" + "Aggregate prefix\n" + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Apply route map to aggregate network\n" + "Route map name\n" + "BGP origin code\n" + "Remote EGP\n" + "Local IGP\n" + "Unknown heritage\n" + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") +{ + char base_xpath[XPATH_MAXLEN]; + safi_t safi = bgp_node_safi(vty); + + if (!no && origin_s) + nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s); + + if (!no && as_set_s) + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false"); + + if (!no && summary_only) + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "true"); + else + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "false"); + + if (!no && match_med) + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, + "false"); + + if (rmap_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY, + rmap_name); + + if (suppress_map) + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY, + suppress_map); + else + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY, + NULL); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']", + yang_afi_safi_value2identity(AFI_IP6, safi), + bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str); + if (no) - return bgp_aggregate_unset(vty, prefix_str, AFI_IP6, - SAFI_UNICAST); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_bgp_global_afi_safi_unicast_aggregate_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + uint8_t origin; + + vty_out(vty, " aggregate-address %s", + yang_dnode_get_string(dnode, "./prefix")); + + if (yang_dnode_get_bool(dnode, "./as-set")) + vty_out(vty, " as-set"); + + if (yang_dnode_get_bool(dnode, "./summary-only")) + vty_out(vty, " summary-only"); - return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST, - rmap_name, summary_only != NULL, as_set, - origin, match_med != NULL, suppress_map); + if (yang_dnode_exists(dnode, "./rmap-policy-export")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-export")); + + origin = yang_dnode_get_enum(dnode, "./origin"); + if (origin != BGP_ORIGIN_UNSPECIFIED) + vty_out(vty, " origin %s", bgp_origin2str(origin)); + + if (yang_dnode_get_bool(dnode, "./match-med")) + vty_out(vty, " matching-MED-only"); + + vty_out(vty, "\n"); } /* Redistribute route treatment. */ @@ -13385,28 +13559,21 @@ static void bgp_distance_free(struct bgp_distance *bdistance) XFREE(MTYPE_BGP_DISTANCE, bdistance); } -static int bgp_distance_set(struct vty *vty, const char *distance_str, - const char *ip_str, const char *access_list_str) +int bgp_distance_set(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len) { int ret; - afi_t afi; - safi_t safi; struct prefix p; - uint8_t distance; struct bgp_dest *dest; struct bgp_distance *bdistance; - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - ret = str2prefix(ip_str, &p); if (ret == 0) { - vty_out(vty, "Malformed prefix\n"); + snprintf(errmsg, errmsg_len, "Malformed prefix\n"); return CMD_WARNING_CONFIG_FAILED; } - distance = atoi(distance_str); - /* Get BGP distance node. */ dest = bgp_node_get(bgp_distance_table[afi][safi], &p); bdistance = bgp_dest_get_bgp_distance_info(dest); @@ -13429,37 +13596,32 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str, return CMD_SUCCESS; } -static int bgp_distance_unset(struct vty *vty, const char *distance_str, - const char *ip_str, const char *access_list_str) +int bgp_distance_unset(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len) { int ret; - afi_t afi; - safi_t safi; struct prefix p; - int distance; struct bgp_dest *dest; struct bgp_distance *bdistance; - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - ret = str2prefix(ip_str, &p); if (ret == 0) { - vty_out(vty, "Malformed prefix\n"); + snprintf(errmsg, errmsg_len, "Malformed prefix\n"); return CMD_WARNING_CONFIG_FAILED; } dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p); if (!dest) { - vty_out(vty, "Can't find specified prefix\n"); + snprintf(errmsg, errmsg_len, "Can't find specified prefix\n"); return CMD_WARNING_CONFIG_FAILED; } bdistance = bgp_dest_get_bgp_distance_info(dest); - distance = atoi(distance_str); if (bdistance->distance != distance) { - vty_out(vty, "Distance does not match configured\n"); + snprintf(errmsg, errmsg_len, + "Distance does not match configured\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -13537,9 +13699,8 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, * we should tell ZEBRA update the routes for a specific * AFI/SAFI to reflect changes in RIB. */ -static void bgp_announce_routes_distance_update(struct bgp *bgp, - afi_t update_afi, - safi_t update_safi) +void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi, + safi_t update_safi) { afi_t afi; safi_t safi; @@ -13559,237 +13720,227 @@ static void bgp_announce_routes_distance_update(struct bgp *bgp, } } -DEFUN (bgp_distance, - bgp_distance_cmd, - "distance bgp (1-255) (1-255) (1-255)", - "Define an administrative distance\n" - "BGP distance\n" - "Distance for routes external to the AS\n" - "Distance for routes internal to the AS\n" - "Distance for local routes\n") +DEFUN_YANG(bgp_distance, bgp_distance_cmd, + "distance bgp (1-255) (1-255) (1-255)", + "Define an administrative distance\n" + "BGP distance\n" + "Distance for routes external to the AS\n" + "Distance for routes internal to the AS\n" + "Distance for local routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 2; int idx_number_2 = 3; int idx_number_3 = 4; - int distance_ebgp = atoi(argv[idx_number]->arg); - int distance_ibgp = atoi(argv[idx_number_2]->arg); - int distance_local = atoi(argv[idx_number_3]->arg); afi_t afi; safi_t safi; + char xpath[XPATH_MAXLEN]; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (bgp->distance_ebgp[afi][safi] != distance_ebgp - || bgp->distance_ibgp[afi][safi] != distance_ibgp - || bgp->distance_local[afi][safi] != distance_local) { - bgp->distance_ebgp[afi][safi] = distance_ebgp; - bgp->distance_ibgp[afi][safi] = distance_ibgp; - bgp->distance_local[afi][safi] = distance_local; - bgp_announce_routes_distance_update(bgp, afi, safi); - } - return CMD_SUCCESS; -} - -DEFUN (no_bgp_distance, - no_bgp_distance_cmd, - "no distance bgp [(1-255) (1-255) (1-255)]", - NO_STR - "Define an administrative distance\n" - "BGP distance\n" - "Distance for routes external to the AS\n" - "Distance for routes internal to the AS\n" - "Distance for local routes\n") + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, + argv[idx_number_2]->arg); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, + argv[idx_number_3]->arg); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd, + "no distance bgp [(1-255) (1-255) (1-255)]", + NO_STR + "Define an administrative distance\n" + "BGP distance\n" + "Distance for routes external to the AS\n" + "Distance for routes internal to the AS\n" + "Distance for local routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); afi_t afi; safi_t safi; + char xpath[XPATH_MAXLEN]; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (bgp->distance_ebgp[afi][safi] != 0 - || bgp->distance_ibgp[afi][safi] != 0 - || bgp->distance_local[afi][safi] != 0) { - bgp->distance_ebgp[afi][safi] = 0; - bgp->distance_ibgp[afi][safi] = 0; - bgp->distance_local[afi][safi] = 0; - bgp_announce_routes_distance_update(bgp, afi, safi); - } - return CMD_SUCCESS; -} + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); -DEFUN (bgp_distance_source, - bgp_distance_source_cmd, - "distance (1-255) A.B.C.D/M", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") -{ - int idx_number = 1; - int idx_ipv4_prefixlen = 2; - bgp_distance_set(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_distance_source, - no_bgp_distance_source_cmd, - "no distance (1-255) A.B.C.D/M", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") +void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - int idx_number = 2; - int idx_ipv4_prefixlen = 3; - bgp_distance_unset(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, NULL); - return CMD_SUCCESS; -} + uint8_t distance_ebgp, distance_ibgp, distance_local; -DEFUN (bgp_distance_source_access_list, - bgp_distance_source_access_list_cmd, - "distance (1-255) A.B.C.D/M WORD", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") -{ - int idx_number = 1; - int idx_ipv4_prefixlen = 2; - int idx_word = 3; - bgp_distance_set(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); - return CMD_SUCCESS; -} + distance_ebgp = yang_dnode_get_uint8(dnode, "./external"); + distance_ibgp = yang_dnode_get_uint8(dnode, "./internal"); + distance_local = yang_dnode_get_uint8(dnode, "./local"); -DEFUN (no_bgp_distance_source_access_list, - no_bgp_distance_source_access_list_cmd, - "no distance (1-255) A.B.C.D/M WORD", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") -{ - int idx_number = 2; - int idx_ipv4_prefixlen = 3; - int idx_word = 4; - bgp_distance_unset(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); - return CMD_SUCCESS; + vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp, + distance_local); } -DEFUN (ipv6_bgp_distance_source, - ipv6_bgp_distance_source_cmd, - "distance (1-255) X:X::X:X/M", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") +DEFPY_YANG(bgp_distance_source, + bgp_distance_source_cmd, + "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]", + NO_STR + "Define an administrative distance\n" + "Distance value\n" + "IP source prefix\n" + "Access list name\n") { - bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL); - return CMD_SUCCESS; -} + afi_t afi; + safi_t safi; + char xpath[XPATH_MAXLEN]; -DEFUN (no_ipv6_bgp_distance_source, - no_ipv6_bgp_distance_source_cmd, - "no distance (1-255) X:X::X:X/M", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") -{ - bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL); - return CMD_SUCCESS; -} + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); -DEFUN (ipv6_bgp_distance_source_access_list, - ipv6_bgp_distance_source_access_list_cmd, - "distance (1-255) X:X::X:X/M WORD", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") -{ - bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg); - return CMD_SUCCESS; + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY, + distance_str); + if (acl) + nb_cli_enqueue_change(vty, + "./access-list-policy-export", + NB_OP_CREATE, acl); + else + nb_cli_enqueue_change(vty, + "./access-list-policy-export", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), prefix_str); + + return nb_cli_apply_changes(vty, xpath); } -DEFUN (no_ipv6_bgp_distance_source_access_list, - no_ipv6_bgp_distance_source_access_list_cmd, - "no distance (1-255) X:X::X:X/M WORD", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") +void cli_show_bgp_global_afi_safi_unicast_admin_distance_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg); - return CMD_SUCCESS; + vty_out(vty, " distance %d %s %s\n", + yang_dnode_get_uint8(dnode, "./distance"), + yang_dnode_get_string(dnode, "./prefix"), + (yang_dnode_exists(dnode, "./access-list-policy-export")) + ? yang_dnode_get_string(dnode, + "./access-list-policy-export") + : ""); } -DEFUN (bgp_damp_set, - bgp_damp_set_cmd, - "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", - "BGP Specific commands\n" - "Enable route-flap dampening\n" - "Half-life time for the penalty\n" - "Value to start reusing a route\n" - "Value to start suppressing a route\n" - "Maximum duration to suppress a stable route\n") +DEFPY_YANG(bgp_dampening, + bgp_dampening_cmd, + "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_supress]]", + NO_STR + "BGP Specific commands\n" + "Enable route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_half_life = 2; - int idx_reuse = 3; - int idx_suppress = 4; - int idx_max_suppress = 5; - int half = DEFAULT_HALF_LIFE * 60; - int reuse = DEFAULT_REUSE; - int suppress = DEFAULT_SUPPRESS; - int max = 4 * half; + afi_t afi; + safi_t safi; + char xpath[XPATH_MAXLEN]; - if (argc == 6) { - half = atoi(argv[idx_half_life]->arg) * 60; - reuse = atoi(argv[idx_reuse]->arg); - suppress = atoi(argv[idx_suppress]->arg); - max = atoi(argv[idx_max_suppress]->arg) * 60; - } else if (argc == 3) { - half = atoi(argv[idx_half_life]->arg) * 60; - max = 4 * half; - } + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - /* - * These can't be 0 but our SA doesn't understand the - * way our cli is constructed - */ - assert(reuse); - assert(half); - if (suppress < reuse) { - vty_out(vty, - "Suppress value cannot be less than reuse value \n"); - return 0; + if (!no) { + nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true"); + if (argc == 6) { + nb_cli_enqueue_change(vty, "./reach-decay", + NB_OP_MODIFY, halflife_str); + nb_cli_enqueue_change(vty, "./reuse-above", + NB_OP_MODIFY, reuse_str); + nb_cli_enqueue_change(vty, "./suppress-above", + NB_OP_MODIFY, suppress_str); + nb_cli_enqueue_change(vty, "./unreach-decay", + NB_OP_MODIFY, max_supress_str); + } if (argc == 3) { + nb_cli_enqueue_change(vty, "./reach-decay", + NB_OP_MODIFY, halflife_str); + } + } else { + nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false"); } - return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half, - reuse, suppress, max); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + return nb_cli_apply_changes(vty, xpath); } -DEFUN (bgp_damp_unset, - bgp_damp_unset_cmd, - "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", - NO_STR - "BGP Specific commands\n" - "Enable route-flap dampening\n" - "Half-life time for the penalty\n" - "Value to start reusing a route\n" - "Value to start suppressing a route\n" - "Maximum duration to suppress a stable route\n") +void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty)); + if (!yang_dnode_get_bool(dnode, "./enable")) + return; + + int half = DEFAULT_HALF_LIFE * 60; + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + int max; + + half = yang_dnode_get_uint8(dnode, "../reach-decay"); + reuse = yang_dnode_get_uint16(dnode, "../reuse-above"); + suppress = yang_dnode_get_uint16(dnode, "../suppress-above"); + max = yang_dnode_get_uint8(dnode, "../unreach-decay"); + + if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE + && suppress == DEFAULT_SUPPRESS && max == half * 4) + vty_out(vty, " bgp dampening\n"); + else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE + && suppress == DEFAULT_SUPPRESS && max == half * 4) + vty_out(vty, " bgp dampening %u\n", half); + else + vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse, + suppress, max); } /* Display specified route of BGP table. */ @@ -14319,54 +14470,27 @@ void bgp_route_init(void) install_element(BGP_NODE, &bgp_distance_cmd); install_element(BGP_NODE, &no_bgp_distance_cmd); install_element(BGP_NODE, &bgp_distance_source_cmd); - install_element(BGP_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV4_NODE, &bgp_distance_cmd); install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd); install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd); - install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV4M_NODE, &bgp_distance_cmd); install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd); install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd); - install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_IPV4M_NODE, - &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV6_NODE, &bgp_distance_cmd); install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd); - install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6_NODE, - &ipv6_bgp_distance_source_access_list_cmd); - install_element(BGP_IPV6_NODE, - &no_ipv6_bgp_distance_source_access_list_cmd); + install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd); install_element(BGP_IPV6M_NODE, &bgp_distance_cmd); install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd); - install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6M_NODE, - &ipv6_bgp_distance_source_access_list_cmd); - install_element(BGP_IPV6M_NODE, - &no_ipv6_bgp_distance_source_access_list_cmd); + install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd); /* BGP dampening */ - install_element(BGP_NODE, &bgp_damp_set_cmd); - install_element(BGP_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd); + install_element(BGP_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd); /* Large Communities */ install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 4a4959298..43744044b 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -454,6 +454,14 @@ struct bgp_aggregate { #define UNSUPPRESS_MAP_NAME(F) ((F)->usmap.name) #define UNSUPPRESS_MAP(F) ((F)->usmap.map) +#define ADVERTISE_MAP_NAME(F) ((F)->advmap.aname) +#define ADVERTISE_MAP(F) ((F)->advmap.amap) + +#define ADVERTISE_CONDITION(F) ((F)->advmap.condition) + +#define CONDITION_MAP_NAME(F) ((F)->advmap.cname) +#define CONDITION_MAP(F) ((F)->advmap.cmap) + /* path PREFIX (addpath rxid NUMBER) */ #define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32 @@ -663,6 +671,8 @@ extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, json_object *json); +extern void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp); + extern void subgroup_process_announce_selected(struct update_subgroup *subgrp, struct bgp_path_info *selected, struct bgp_dest *dest, @@ -671,7 +681,8 @@ extern void subgroup_process_announce_selected(struct update_subgroup *subgrp, extern bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, - const struct prefix *p, struct attr *attr); + const struct prefix *p, struct attr *attr, + bool skip_rmap_check); extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer); extern void bgp_process_queues_drain_immediate(void); @@ -719,4 +730,32 @@ extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, struct bgp *bgp, const struct prefix *p, afi_t afi, safi_t safi, bool suppress); +extern int bgp_static_set(struct bgp *bgp, const char *negate, + struct prefix *pfx, afi_t afi, safi_t safi, + const char *rmap, int backdoor, uint32_t label_index, + char *errmsg, size_t errmsg_len); + +extern int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, const char *rmap, + uint8_t summary_only, uint8_t as_set, + uint8_t origin, bool match_med, + const char *suppress_map, char *errmsg, + size_t errmsg_len); + +extern int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, + afi_t afi, safi_t safi, char *errmsg, + size_t errmsg_len); + +extern void bgp_announce_routes_distance_update(struct bgp *bgp, + afi_t update_afi, + safi_t update_safi); + +extern int bgp_distance_set(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len); + +extern int bgp_distance_unset(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, + safi_t safi, char *errmsg, size_t errmsg_len); + #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index c65574393..e4a9c2900 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3695,9 +3695,22 @@ static void bgp_route_map_process_peer(const char *rmap_name, if (filter->usmap.name && (strcmp(rmap_name, filter->usmap.name) == 0)) filter->usmap.map = map; + if (filter->advmap.aname + && (strcmp(rmap_name, filter->advmap.aname) == 0)) { + filter->advmap.amap = map; + } + + if (filter->advmap.cname + && (strcmp(rmap_name, filter->advmap.cname) == 0)) { + filter->advmap.cmap = map; + } + if (peer->default_rmap[afi][safi].name && (strcmp(rmap_name, peer->default_rmap[afi][safi].name) == 0)) peer->default_rmap[afi][safi].map = map; + + /* Notify BGP conditional advertisement scanner percess */ + peer->advmap_config_change[afi][safi] = true; } static void bgp_route_map_update_peer_group(const char *rmap_name, diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 21eca78ab..2788a8ea4 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -195,6 +195,19 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi, MTYPE_BGP_FILTER_NAME, UNSUPPRESS_MAP_NAME(srcfilter)); UNSUPPRESS_MAP(dstfilter) = UNSUPPRESS_MAP(srcfilter); } + + if (ADVERTISE_MAP_NAME(srcfilter)) { + ADVERTISE_MAP_NAME(dstfilter) = XSTRDUP( + MTYPE_BGP_FILTER_NAME, ADVERTISE_MAP_NAME(srcfilter)); + ADVERTISE_MAP(dstfilter) = ADVERTISE_MAP(srcfilter); + ADVERTISE_CONDITION(dstfilter) = ADVERTISE_CONDITION(srcfilter); + } + + if (CONDITION_MAP_NAME(srcfilter)) { + CONDITION_MAP_NAME(dstfilter) = XSTRDUP( + MTYPE_BGP_FILTER_NAME, CONDITION_MAP_NAME(srcfilter)); + CONDITION_MAP(dstfilter) = CONDITION_MAP(srcfilter); + } } /** @@ -218,6 +231,10 @@ static void conf_release(struct peer *src, afi_t afi, safi_t safi) XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name); + XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.aname); + + XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.cname); + XFREE(MTYPE_BGP_PEER_HOST, src->host); } @@ -353,6 +370,11 @@ static unsigned int updgrp_hash_key_make(const void *p) strlen(filter->usmap.name), SEED1), key); + if (filter->advmap.aname) + key = jhash_1word(jhash(filter->advmap.aname, + strlen(filter->advmap.aname), SEED1), + key); + if (peer->default_rmap[afi][safi].name) key = jhash_1word( jhash(peer->default_rmap[afi][safi].name, @@ -481,6 +503,12 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2) && strcmp(fl1->usmap.name, fl2->usmap.name))) return false; + if ((fl1->advmap.aname && !fl2->advmap.aname) + || (!fl1->advmap.aname && fl2->advmap.aname) + || (fl1->advmap.aname && fl2->advmap.aname + && strcmp(fl1->advmap.aname, fl2->advmap.aname))) + return false; + if ((pe1->default_rmap[afi][safi].name && !pe2->default_rmap[afi][safi].name) || (!pe1->default_rmap[afi][safi].name diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 2e59bb3a5..ac77ccd8a 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -215,6 +215,9 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg) } } } + + /* Notify BGP Conditional advertisement */ + bgp_notify_conditional_adv_scanner(subgrp); } return UPDWALK_CONTINUE; @@ -642,7 +645,8 @@ void subgroup_announce_table(struct update_subgroup *subgrp, peer->addpath_type[afi][safi], ri))) { if (subgroup_announce_check(dest, ri, subgrp, - dest_p, &attr)) + dest_p, &attr, + false)) bgp_adj_out_set_subgroup(dest, subgrp, &attr, ri); else { @@ -827,7 +831,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (subgroup_announce_check( dest, pi, subgrp, bgp_dest_get_prefix(dest), - &attr)) + &attr, false)) bgp_adj_out_set_subgroup( dest, subgrp, &attr, pi); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 087836425..00e781d80 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -273,6 +273,37 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi) return "Unknown"; } +/* return string maps to afi-safi specific container names + * defined in bgp yang file. + */ +const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi) +{ + if (afi == AFI_IP && safi == SAFI_UNICAST) + return "ipv4-unicast"; + else if (afi == AFI_IP && safi == SAFI_MULTICAST) + return "ipv4-multicast"; + else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) + return "ipv4-labeled-unicast"; + else if (afi == AFI_IP && safi == SAFI_MPLS_VPN) + return "l3vpn-ipv4-unicast"; + else if (afi == AFI_IP && safi == SAFI_FLOWSPEC) + return "ipv4-flowspec"; + else if (afi == AFI_IP6 && safi == SAFI_UNICAST) + return "ipv6-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_MULTICAST) + return "ipv6-multicast"; + else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) + return "ipv6-labeled-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN) + return "l3vpn-ipv6-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC) + return "ipv6-flowspec"; + else if (afi == AFI_L2VPN && safi == SAFI_EVPN) + return "l2vpn-evpn"; + else + return "Unknown"; +} + /* Utility function to get address family from current node. */ afi_t bgp_node_afi(struct vty *vty) { @@ -1585,23 +1616,16 @@ void cli_show_router_bgp_confederation_member_as(struct vty *vty, * @peer_type: BGP_PEER_EBGP or BGP_PEER_IBGP * @set: 1 for setting values, 0 for removing the max-paths config. */ -static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, - const char *mpaths, uint16_t options, - int set) +int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi, + int peer_type, uint16_t maxpaths, uint16_t options, + int set, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint16_t maxpaths = 0; int ret; - afi_t afi; - safi_t safi; - - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); if (set) { - maxpaths = strtol(mpaths, NULL, 10); if (maxpaths > multipath_num) { - vty_out(vty, + snprintf( + errmsg, errmsg_len, "%% Maxpaths Specified: %d is > than multipath num specified on bgp command line %d", maxpaths, multipath_num); return CMD_WARNING_CONFIG_FAILED; @@ -1612,7 +1636,8 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, ret = bgp_maximum_paths_unset(bgp, afi, safi, peer_type); if (ret < 0) { - vty_out(vty, + snprintf( + errmsg, errmsg_len, "%% Failed to %sset maximum-paths %s %u for afi %u, safi %u\n", (set == 1) ? "" : "un", (peer_type == BGP_PEER_EBGP) ? "ebgp" : "ibgp", @@ -1703,14 +1728,14 @@ DEFUN_YANG(no_bgp_maxmed_admin, return nb_cli_apply_changes(vty, NULL); } -DEFUN_YANG(bgp_maxmed_onstartup, - bgp_maxmed_onstartup_cmd, - "bgp max-med on-startup (5-86400) [(0-4294967295)]", - BGP_STR - "Advertise routes with max-med\n" - "Effective on a startup\n" - "Time (seconds) period for max-med\n" - "Max MED value to be used\n") +DEFUN_YANG (bgp_maxmed_onstartup, + bgp_maxmed_onstartup_cmd, + "bgp max-med on-startup (5-86400) [(0-4294967295)]", + BGP_STR + "Advertise routes with max-med\n" + "Effective on a startup\n" + "Time (seconds) period for max-med\n" + "Max MED value to be used\n") { int idx = 0; @@ -1731,14 +1756,14 @@ DEFUN_YANG(bgp_maxmed_onstartup, return nb_cli_apply_changes(vty, NULL); } -DEFUN_YANG(no_bgp_maxmed_onstartup, - no_bgp_maxmed_onstartup_cmd, - "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]", - NO_STR BGP_STR - "Advertise routes with max-med\n" - "Effective on a startup\n" - "Time (seconds) period for max-med\n" - "Max MED value to be used\n") +DEFUN_YANG (no_bgp_maxmed_onstartup, + no_bgp_maxmed_onstartup_cmd, + "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]", + NO_STR BGP_STR + "Advertise routes with max-med\n" + "Effective on a startup\n" + "Time (seconds) period for max-med\n" + "Max MED value to be used\n") { nb_cli_enqueue_change(vty, "./global/med-config/max-med-onstart-up-time", @@ -1972,12 +1997,12 @@ void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp) * Furthermore, the maximums used here should correspond to * BGP_WRITE_PACKET_MAX and BGP_READ_PACKET_MAX. */ -DEFPY_YANG(bgp_wpkt_quanta, - bgp_wpkt_quanta_cmd, - "[no] write-quanta (1-64)$quanta", - NO_STR - "How many packets to write to peer socket per run\n" - "Number of packets\n") +DEFPY_YANG (bgp_wpkt_quanta, + bgp_wpkt_quanta_cmd, + "[no] write-quanta (1-64)$quanta", + NO_STR + "How many packets to write to peer socket per run\n" + "Number of packets\n") { if (!no) nb_cli_enqueue_change( @@ -1993,12 +2018,12 @@ DEFPY_YANG(bgp_wpkt_quanta, return nb_cli_apply_changes(vty, NULL); } -DEFPY_YANG(bgp_rpkt_quanta, - bgp_rpkt_quanta_cmd, - "[no] read-quanta (1-10)$quanta", - NO_STR - "How many packets to read from peer socket per I/O cycle\n" - "Number of packets\n") +DEFPY_YANG (bgp_rpkt_quanta, + bgp_rpkt_quanta_cmd, + "[no] read-quanta (1-10)$quanta", + NO_STR + "How many packets to read from peer socket per I/O cycle\n" + "Number of packets\n") { if (!no) nb_cli_enqueue_change( @@ -2027,11 +2052,11 @@ void cli_show_router_global_update_group_config_coalesce_time( } -DEFUN_YANG(bgp_coalesce_time, - bgp_coalesce_time_cmd, - "coalesce-time (0-4294967295)", - "Subgroup coalesce timer\n" - "Subgroup coalesce timer value (in ms)\n") +DEFUN_YANG (bgp_coalesce_time, + bgp_coalesce_time_cmd, + "coalesce-time (0-4294967295)", + "Subgroup coalesce timer\n" + "Subgroup coalesce timer value (in ms)\n") { int idx = 0; @@ -2058,15 +2083,37 @@ DEFUN_YANG(no_bgp_coalesce_time, } /* Maximum-paths configuration */ -DEFUN (bgp_maxpaths, - bgp_maxpaths_cmd, - "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM), - "Forward packets over multiple paths\n" - "Number of paths\n") +DEFUN_YANG (bgp_maxpaths, + bgp_maxpaths_cmd, + "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM), + "Forward packets over multiple paths\n" + "Number of paths\n") { int idx_number = 1; - return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, - argv[idx_number]->arg, 0, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " maximum-paths %d\n", + yang_dnode_get_uint16(dnode, NULL)); } ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd, @@ -2074,16 +2121,31 @@ ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd, "Forward packets over multiple paths\n" "Number of paths\n") -DEFUN (bgp_maxpaths_ibgp, - bgp_maxpaths_ibgp_cmd, - "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM), - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n") +DEFUN_YANG (bgp_maxpaths_ibgp, + bgp_maxpaths_ibgp_cmd, + "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM), + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n") { int idx_number = 2; - return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, - argv[idx_number]->arg, 0, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd, @@ -2092,18 +2154,50 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd, "iBGP-multipath\n" "Number of paths\n") -DEFUN (bgp_maxpaths_ibgp_cluster, - bgp_maxpaths_ibgp_cluster_cmd, - "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length", - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n" - "Match the cluster length\n") +DEFUN_YANG (bgp_maxpaths_ibgp_cluster, + bgp_maxpaths_ibgp_cluster_cmd, + "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length", + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n" + "Match the cluster length\n") { int idx_number = 2; - return bgp_maxpaths_config_vty( - vty, BGP_PEER_IBGP, argv[idx_number]->arg, - BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " maximum-paths ibgp %d", + yang_dnode_get_uint16(dnode, "./maximum-paths")); + if (yang_dnode_get_bool(dnode, "./cluster-length-list")) + vty_out(vty, " equal-cluster-length"); + vty_out(vty, "\n"); } ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd, @@ -2114,14 +2208,29 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd, "Number of paths\n" "Match the cluster length\n") -DEFUN (no_bgp_maxpaths, - no_bgp_maxpaths_cmd, - "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", - NO_STR - "Forward packets over multiple paths\n" - "Number of paths\n") +DEFUN_YANG (no_bgp_maxpaths, + no_bgp_maxpaths_cmd, + "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", + NO_STR + "Forward packets over multiple paths\n" + "Number of paths\n") { - return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, NULL, 0, 0); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, @@ -2129,16 +2238,39 @@ ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, "Forward packets over multiple paths\n" "Number of paths\n") -DEFUN (no_bgp_maxpaths_ibgp, - no_bgp_maxpaths_ibgp_cmd, - "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]", - NO_STR - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n" - "Match the cluster length\n") +DEFUN_YANG (no_bgp_maxpaths_ibgp, + no_bgp_maxpaths_ibgp_cmd, + "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]", + NO_STR + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n" + "Match the cluster length\n") { - return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, NULL, 0, 0); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd, @@ -2170,13 +2302,13 @@ static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, /* BGP timers. */ -DEFUN_YANG(bgp_timers, - bgp_timers_cmd, - "timers bgp (0-65535) (0-65535)", - "Adjust routing timers\n" - "BGP timers\n" - "Keepalive interval\n" - "Holdtime\n") +DEFUN_YANG (bgp_timers, + bgp_timers_cmd, + "timers bgp (0-65535) (0-65535)", + "Adjust routing timers\n" + "BGP timers\n" + "Keepalive interval\n" + "Holdtime\n") { int idx_number = 2; int idx_number_2 = 3; @@ -2189,14 +2321,14 @@ DEFUN_YANG(bgp_timers, return nb_cli_apply_changes(vty, NULL); } -DEFUN_YANG(no_bgp_timers, - no_bgp_timers_cmd, - "no timers bgp [(0-65535) (0-65535)]", - NO_STR - "Adjust routing timers\n" - "BGP timers\n" - "Keepalive interval\n" - "Holdtime\n") +DEFUN_YANG (no_bgp_timers, + no_bgp_timers_cmd, + "no timers bgp [(0-65535) (0-65535)]", + NO_STR + "Adjust routing timers\n" + "BGP timers\n" + "Keepalive interval\n" + "Holdtime\n") { nb_cli_enqueue_change(vty, "./global/global-config-timers/keepalive", NB_OP_DESTROY, NULL); @@ -7043,6 +7175,68 @@ ALIAS_HIDDEN(no_neighbor_filter_list, no_neighbor_filter_list_hidden_cmd, "Filter incoming routes\n" "Filter outgoing routes\n") +/* Set advertise-map to the peer. */ +static int peer_advertise_map_set_vty(struct vty *vty, const char *ip_str, + afi_t afi, safi_t safi, + const char *advertise_str, + const char *condition_str, bool condition, + bool set) +{ + int ret = CMD_WARNING_CONFIG_FAILED; + struct peer *peer; + struct route_map *advertise_map; + struct route_map *condition_map; + + peer = peer_and_group_lookup_vty(vty, ip_str); + if (!peer) + return ret; + + condition_map = route_map_lookup_warn_noexist(vty, condition_str); + advertise_map = route_map_lookup_warn_noexist(vty, advertise_str); + + if (set) + ret = peer_advertise_map_set(peer, afi, safi, advertise_str, + advertise_map, condition_str, + condition_map, condition); + else + ret = peer_advertise_map_unset(peer, afi, safi, advertise_str, + advertise_map, condition_str, + condition_map, condition); + + return bgp_vty_return(vty, ret); +} + +DEFPY (neighbor_advertise_map, + neighbor_advertise_map_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$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" + "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n" + "Name of the exist or non exist map\n") +{ + bool condition = CONDITION_EXIST; + + if (!strcmp(exist, "non-exist-map")) + condition = CONDITION_NON_EXIST; + + 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 <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$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" + "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\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, afi_t afi, safi_t safi, const char *name_str, @@ -7890,6 +8084,33 @@ static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, return CMD_SUCCESS; } +bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi, + bool v2vimport, char *errmsg, size_t errmsg_len) +{ + if (!v2vimport) { + if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_IMPORT) + || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_EXPORT)) { + snprintf( + errmsg, errmsg_len, "%s", + "%% error: Please unconfigure import vrf commands before using vpn commands"); + return false; + } + } else { + if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) + || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { + snprintf( + errmsg, errmsg_len, "%s", + "%% error: Please unconfigure vpn to vrf commands before using import vrf commands"); + return false; + } + } + return true; +} + /* * v2vimport is true if we are handling a `import vrf ...` command */ @@ -7932,57 +8153,45 @@ static afi_t vpn_policy_getafi(struct vty *vty, struct bgp *bgp, bool v2vimport) return afi; } -DEFPY (af_rd_vpn_export, - af_rd_vpn_export_cmd, - "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str", - NO_STR - "Specify route distinguisher\n" - "Between current address-family and vpn\n" - "For routes leaked from current address-family to vpn\n" - "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n") +DEFPY_YANG( + af_rd_vpn_export, + af_rd_vpn_export_cmd, + "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str", + NO_STR + "Specify route distinguisher\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" + "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct prefix_rd prd; - int ret; + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; int idx = 0; - bool yes = true; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - if (yes) { - ret = str2prefix_rd(rd_str, &prd); - if (!ret) { - vty_out(vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); - /* - * pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, "./rd", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./rd", NB_OP_MODIFY, rd_str); - if (yes) { - bgp->vpn_policy[afi].tovpn_rd = prd; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); - } else { - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); - } + return nb_cli_apply_changes(vty, base_xpath); +} - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - return CMD_SUCCESS; + vty_out(vty, "%*srd vpn export %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } ALIAS (af_rd_vpn_export, @@ -8083,7 +8292,7 @@ ALIAS (af_label_vpn_export, "Between current address-family and vpn\n" "For routes leaked from current address-family to vpn\n") -DEFPY (af_nexthop_vpn_export, +DEFPY_YANG (af_nexthop_vpn_export, af_nexthop_vpn_export_cmd, "[no] nexthop vpn export [<A.B.C.D|X:X::X:X>$nexthop_su]", NO_STR @@ -8093,8 +8302,10 @@ DEFPY (af_nexthop_vpn_export, "IPv4 prefix\n" "IPv6 prefix\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; + int idx = 0; struct prefix p; if (!no) { @@ -8106,30 +8317,31 @@ DEFPY (af_nexthop_vpn_export, return CMD_WARNING_CONFIG_FAILED; } - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - /* - * pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); - if (!no) { - bgp->vpn_policy[afi].tovpn_nexthop = p; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); - } else { - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); - } + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, "./nexthop", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./nexthop", NB_OP_MODIFY, + nexthop_su_str); - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + return nb_cli_apply_changes(vty, base_xpath); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; + + vty_out(vty, "%*snexthop vpn export %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } static int vpn_policy_getdirs(struct vty *vty, const char *dstr, int *dodir) @@ -8230,7 +8442,7 @@ ALIAS (af_rt_vpn_imexport, "For routes leaked from current address-family to vpn\n" "both import and export\n") -DEFPY (af_route_map_vpn_imexport, +DEFPY_YANG (af_route_map_vpn_imexport, af_route_map_vpn_imexport_cmd, /* future: "route-map <vpn|evpn|vrf NAME> <import|export> RMAP" */ "[no] route-map vpn <import|export>$direction_str RMAP$rmap_str", @@ -8241,53 +8453,54 @@ DEFPY (af_route_map_vpn_imexport, "For routes leaked from current address-family to vpn\n" "name of route-map\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; - vpn_policy_direction_t dir; + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; int idx = 0; - bool yes = true; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; - - ret = vpn_policy_getdirs(vty, direction_str, dodir); - if (ret != CMD_SUCCESS) - return ret; + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { - if (!dodir[dir]) - continue; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + if (argv_find(argv, argc, "no", &idx)) { + if (!strcmp(direction_str, "import")) + nb_cli_enqueue_change(vty, "./rmap-import", + NB_OP_DESTROY, NULL); + else if (!strcmp(direction_str, "export")) + nb_cli_enqueue_change(vty, "./rmap-export", + NB_OP_DESTROY, NULL); + } else { + if (!strcmp(direction_str, "import")) + nb_cli_enqueue_change(vty, "./rmap-import", + NB_OP_MODIFY, rmap_str); + if (!strcmp(direction_str, "export")) + nb_cli_enqueue_change(vty, "./rmap-export", + NB_OP_MODIFY, rmap_str); + } + return nb_cli_apply_changes(vty, base_xpath); +} - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - if (yes) { - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP( - MTYPE_ROUTE_MAP_NAME, rmap_str); - bgp->vpn_policy[afi].rmap[dir] = - route_map_lookup_warn_noexist(vty, rmap_str); - if (!bgp->vpn_policy[afi].rmap[dir]) - return CMD_SUCCESS; - } else { - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = NULL; - bgp->vpn_policy[afi].rmap[dir] = NULL; - } + vty_out(vty, "%*sroute-map vpn import %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); +} - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); - } +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - return CMD_SUCCESS; + vty_out(vty, "%*sroute-map vpn import %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } ALIAS (af_route_map_vpn_imexport, @@ -8384,24 +8597,18 @@ DEFPY(af_no_import_vrf_route_map, af_no_import_vrf_route_map_cmd, return CMD_SUCCESS; } -DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, - "[no] import vrf VIEWVRFNAME$import_name", - NO_STR - "Import routes from another VRF\n" - "VRF to import from\n" - "The name of the VRF\n") +DEFPY_YANG(bgp_imexport_vrf, + bgp_imexport_vrf_cmd, + "[no] import vrf VIEWVRFNAME$import_name", + NO_STR + "Import routes from another VRF\n" + "VRF to import from\n" + "The name of the VRF\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct listnode *node; - struct bgp *vrf_bgp, *bgp_default; - int32_t ret = 0; - as_t as = bgp->as; - bool remove = false; - int32_t idx = 0; - char *vname; - enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + char base_xpath[XPATH_MAXLEN]; safi_t safi; afi_t afi; + int32_t idx = 0; if (import_name == NULL) { vty_out(vty, "%% Missing import name\n"); @@ -8413,70 +8620,32 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, return CMD_WARNING; } - if (argv_find(argv, argc, "no", &idx)) - remove = true; - - afi = vpn_policy_getafi(vty, bgp, true); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; - + afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) - && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) - || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { - vty_out(vty, "%% Cannot %s vrf %s into itself\n", - remove ? "unimport" : "import", import_name); - return CMD_WARNING; - } - - bgp_default = bgp_get_default(); - if (!bgp_default) { - /* Auto-create assuming the same AS */ - ret = bgp_get_vty(&bgp_default, &as, NULL, - BGP_INSTANCE_TYPE_DEFAULT); - - if (ret) { - vty_out(vty, - "VRF default is not configured as a bgp instance\n"); - return CMD_WARNING; - } - } - - vrf_bgp = bgp_lookup_by_name(import_name); - if (!vrf_bgp) { - if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) - vrf_bgp = bgp_default; - else - /* Auto-create assuming the same AS */ - ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vrf-list[vrf='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), import_name); - if (ret) { - vty_out(vty, - "VRF %s is not configured as a bgp instance\n", - import_name); - return CMD_WARNING; - } - } - - if (remove) { - vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi); - } else { - /* Already importing from "import_vrf"? */ - for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node, - vname)) { - if (strcmp(vname, import_name) == 0) - return CMD_WARNING; - } + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - vrf_import_from_vrf(bgp, vrf_bgp, afi, safi); - } + return nb_cli_apply_changes(vty, base_xpath); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " import vrf %s\n", + yang_dnode_get_string(dnode, "./vrf")); } /* This command is valid only in a bgp vrf instance or the default instance */ -DEFPY (bgp_imexport_vpn, +DEFPY_YANG (bgp_imexport_vpn, bgp_imexport_vpn_cmd, "[no] <import|export>$direction_str vpn", NO_STR @@ -8484,60 +8653,51 @@ DEFPY (bgp_imexport_vpn, "Export routes from this address-family\n" "to/from default instance VPN RIB\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int previous_state; - afi_t afi; + char base_xpath[XPATH_MAXLEN]; safi_t safi; - int idx = 0; - bool yes = true; - int flag; - vpn_policy_direction_t dir; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - - if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type && - BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { - - vty_out(vty, "%% import|export vpn valid only for bgp vrf or default instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } + afi_t afi; + int32_t idx = 0; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) { - vty_out(vty, "%% import|export vpn valid only for unicast ipv4|ipv6\n"); - return CMD_WARNING_CONFIG_FAILED; - } if (!strcmp(direction_str, "import")) { - flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT; - dir = BGP_VPN_POLICY_DIR_FROMVPN; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vpn", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); } else if (!strcmp(direction_str, "export")) { - flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT; - dir = BGP_VPN_POLICY_DIR_TOVPN; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/export-vpn", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); } else { vty_out(vty, "%% unknown direction %s\n", direction_str); return CMD_WARNING_CONFIG_FAILED; } - previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag); + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, "true"); + + return nb_cli_apply_changes(vty, base_xpath); +} - if (yes) { - SET_FLAG(bgp->af_flags[afi][safi], flag); - if (!previous_state) { - /* trigger export current vrf */ - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); - } - } else { - if (previous_state) { - /* trigger un-export current vrf */ - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); - } - UNSET_FLAG(bgp->af_flags[afi][safi], flag); - } +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " import vpn\n"); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " export vpn\n"); } DEFPY (af_routetarget_import, @@ -8603,6 +8763,51 @@ DEFPY (af_routetarget_import, return CMD_SUCCESS; } +void cli_show_bgp_global_afi_safi_header(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + const char *af_name; + afi_t afi; + safi_t safi; + + af_name = yang_dnode_get_string(dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + vty_out(vty, " !\n address-family "); + if (afi == AFI_IP) { + if (safi == SAFI_UNICAST) + vty_out(vty, "ipv4 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_out(vty, "ipv4 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_out(vty, "ipv4 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_out(vty, "ipv4 vpn"); + else if (safi == SAFI_ENCAP) + vty_out(vty, "ipv4 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_out(vty, "ipv4 flowspec"); + } else if (afi == AFI_IP6) { + if (safi == SAFI_UNICAST) + vty_out(vty, "ipv6 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_out(vty, "ipv6 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_out(vty, "ipv6 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_out(vty, "ipv6 vpn"); + else if (safi == SAFI_ENCAP) + vty_out(vty, "ipv6 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_out(vty, "ipv6 flowspec"); + } else if (afi == AFI_L2VPN) { + if (safi == SAFI_EVPN) + vty_out(vty, "l2vpn evpn"); + } + vty_out(vty, "\n"); +} + DEFUN_NOSH (address_family_ipv4_safi, address_family_ipv4_safi_cmd, "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast|flowspec>]", @@ -8611,19 +8816,28 @@ DEFUN_NOSH (address_family_ipv4_safi, BGP_SAFI_WITH_LABEL_HELP_STR) { + safi_t safi = SAFI_UNICAST; + const struct lyd_node *vrf_dnode, *bgp_glb_dnode; + const char *vrf_name = NULL; + if (argc == 3) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + safi = bgp_vty_safi_from_str(argv[2]->text); + + bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode, + VTY_CURR_XPATH); + vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (!strmatch(vrf_name, VRF_DEFAULT_NAME) && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); return CMD_WARNING_CONFIG_FAILED; } - vty->node = bgp_node_type(AFI_IP, safi); - } else - vty->node = BGP_IPV4_NODE; + } + vty->node = bgp_node_type(AFI_IP, safi); return CMD_SUCCESS; } @@ -8635,19 +8849,27 @@ DEFUN_NOSH (address_family_ipv6_safi, "Address Family\n" BGP_SAFI_WITH_LABEL_HELP_STR) { + safi_t safi = SAFI_UNICAST; + const struct lyd_node *vrf_dnode, *bgp_glb_dnode; + const char *vrf_name = NULL; + if (argc == 3) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + safi = bgp_vty_safi_from_str(argv[2]->text); + bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode, + VTY_CURR_XPATH); + vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (!strmatch(vrf_name, VRF_DEFAULT_NAME) && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); return CMD_WARNING_CONFIG_FAILED; } - vty->node = bgp_node_type(AFI_IP6, safi); - } else - vty->node = BGP_IPV6_NODE; + } + vty->node = bgp_node_type(AFI_IP6, safi); return CMD_SUCCESS; } @@ -8704,6 +8926,13 @@ DEFUN_NOSH (exit_address_family, return CMD_SUCCESS; } +void cli_show_bgp_global_afi_safi_header_end(struct vty *vty, + struct lyd_node *dnode + __attribute__((__unused__))) +{ + vty_out(vty, " exit-address-family\n"); +} + /* Recalculate bestpath and re-advertise a prefix */ static int bgp_clear_prefix(struct vty *vty, const char *view_name, const char *ip_str, afi_t afi, safi_t safi, @@ -10712,6 +10941,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, json_object *json_prefA = NULL; json_object *json_prefB = NULL; json_object *json_addr = NULL; + json_object *json_advmap = NULL; if (use_json) { json_addr = json_object_new_object(); @@ -10986,6 +11216,26 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, "selectiveUnsuppressRouteMap", filter->usmap.name); + /* advertise-map */ + if (filter->advmap.aname) { + json_advmap = json_object_new_object(); + json_object_string_add(json_advmap, "condition", + filter->advmap.condition + ? "EXIST" + : "NON_EXIST"); + json_object_string_add(json_advmap, "conditionMap", + filter->advmap.cname); + json_object_string_add(json_advmap, "advertiseMap", + filter->advmap.aname); + json_object_string_add(json_advmap, "advertiseStatus", + filter->advmap.update_type + == ADVERTISE + ? "Advertise" + : "Withdraw"); + json_object_object_add(json_addr, "advertiseMap", + json_advmap); + } + /* Receive prefix count */ json_object_int_add(json_addr, "acceptedPrefixCounter", p->pcount[afi][safi]); @@ -11281,6 +11531,20 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, filter->usmap.map ? "*" : "", filter->usmap.name); + /* advertise-map */ + if (filter->advmap.aname && filter->advmap.cname) + vty_out(vty, + " Condition %s, Condition-map %s%s, Advertise-map %s%s, status: %s\n", + filter->advmap.condition ? "EXIST" + : "NON_EXIST", + filter->advmap.cmap ? "*" : "", + filter->advmap.cname, + filter->advmap.amap ? "*" : "", + filter->advmap.aname, + filter->advmap.update_type == ADVERTISE + ? "Advertise" + : "Withdraw"); + /* Receive prefix count */ vty_out(vty, " %u accepted prefixes\n", p->pcount[afi][safi]); @@ -14247,24 +14511,23 @@ DEFUN (show_ip_bgp_peer_groups, /* Redistribute VTY commands. */ -DEFUN (bgp_redistribute_ipv4, - bgp_redistribute_ipv4_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD, - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD) +DEFUN_YANG (bgp_redistribute_ipv4, + bgp_redistribute_ipv4_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD, + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - bgp_redist_add(bgp, AFI_IP, type, 0); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, false); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14272,33 +14535,28 @@ ALIAS_HIDDEN( "redistribute " FRR_IP_REDIST_STR_BGPD, "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD) -DEFUN (bgp_redistribute_ipv4_rmap, - bgp_redistribute_ipv4_rmap_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv4_rmap, + bgp_redistribute_ipv4_rmap_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD", + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; - int type; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = route_map_lookup_warn_noexist( - vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + char base_xpath[XPATH_MAXLEN]; - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14308,32 +14566,28 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_metric, - bgp_redistribute_ipv4_metric_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG (bgp_redistribute_ipv4_metric, + bgp_redistribute_ipv4_metric_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_number = 3; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14343,39 +14597,34 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_rmap_metric, - bgp_redistribute_ipv4_rmap_metric_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv4_rmap_metric, + bgp_redistribute_ipv4_rmap_metric_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD + " route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; int idx_number = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14389,39 +14638,34 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_metric_rmap, - bgp_redistribute_ipv4_metric_rmap_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv4_metric_rmap, + bgp_redistribute_ipv4_metric_rmap_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD + " metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int idx_number = 3; int idx_word = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + int idx_number = 3; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14435,29 +14679,26 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_ospf, - bgp_redistribute_ipv4_ospf_cmd, - "redistribute <ospf|table> (1-65535)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n") +DEFUN_YANG (bgp_redistribute_ipv4_ospf, + bgp_redistribute_ipv4_ospf_cmd, + "redistribute <ospf|table> (1-65535)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; - unsigned short instance; - unsigned short protocol; + char base_xpath[XPATH_MAXLEN]; - instance = strtoul(argv[idx_number]->arg, NULL, 10); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - bgp_redist_add(bgp, AFI_IP, protocol, instance); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, false); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, @@ -14467,37 +14708,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, "Non-main Kernel Routing Table\n" "Instance ID/Table ID\n") -DEFUN (bgp_redistribute_ipv4_ospf_rmap, - bgp_redistribute_ipv4_ospf_rmap_cmd, - "redistribute <ospf|table> (1-65535) route-map WORD", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv4_ospf_rmap, + bgp_redistribute_ipv4_ospf_rmap_cmd, + "redistribute <ospf|table> (1-65535) route-map WORD", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_word = 4; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, @@ -14510,38 +14746,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_ospf_metric, - bgp_redistribute_ipv4_ospf_metric_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG(bgp_redistribute_ipv4_ospf_metric, + bgp_redistribute_ipv4_ospf_metric_cmd, + "redistribute <ospf|table> (1-65535) metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_number_2 = 4; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, @@ -14554,45 +14784,38 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, - bgp_redistribute_ipv4_ospf_rmap_metric_cmd, - "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv4_ospf_rmap_metric, + bgp_redistribute_ipv4_ospf_rmap_metric_cmd, + "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_word = 4; int idx_number_2 = 6; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14608,45 +14831,38 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, - bgp_redistribute_ipv4_ospf_metric_rmap_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv4_ospf_metric_rmap, + bgp_redistribute_ipv4_ospf_metric_rmap_cmd, + "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_number_2 = 4; int idx_word = 6; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14662,32 +14878,31 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (no_bgp_redistribute_ipv4_ospf, - no_bgp_redistribute_ipv4_ospf_cmd, - "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (no_bgp_redistribute_ipv4_ospf, + no_bgp_redistribute_ipv4_ospf_cmd, + "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 2; + int idx_protocol = 2; int idx_number = 3; - unsigned short instance; - int protocol; + char base_xpath[XPATH_MAXLEN]; - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - return bgp_redistribute_unset(bgp, AFI_IP, protocol, instance); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14703,27 +14918,28 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (no_bgp_redistribute_ipv4, - no_bgp_redistribute_ipv4_cmd, - "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (no_bgp_redistribute_ipv4, + no_bgp_redistribute_ipv4_cmd, + "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 2; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return bgp_redistribute_unset(bgp, AFI_IP, type, 0); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14737,56 +14953,50 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv6, - bgp_redistribute_ipv6_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD, - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD) +DEFUN_YANG (bgp_redistribute_ipv6, + bgp_redistribute_ipv6_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD, + "Redistribute information from another routing protocol\n" + FRR_IP6_REDIST_HELP_STR_BGPD) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - bgp_redist_add(bgp, AFI_IP6, type, 0); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false); + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_rmap, - bgp_redistribute_ipv6_rmap_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv6_rmap, + bgp_redistribute_ipv6_rmap_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD", + "Redistribute information from another routing protocol\n" + FRR_IP6_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; - int type; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_metric, +DEFUN_YANG (bgp_redistribute_ipv6_metric, bgp_redistribute_ipv6_metric_cmd, "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295)", "Redistribute information from another routing protocol\n" @@ -14794,120 +15004,123 @@ DEFUN (bgp_redistribute_ipv6_metric, "Metric for redistributed routes\n" "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_number = 3; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_rmap_metric, - bgp_redistribute_ipv6_rmap_metric_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv6_rmap_metric, + bgp_redistribute_ipv6_rmap_metric_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD + " route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; int idx_number = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, - metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_metric_rmap, - bgp_redistribute_ipv6_metric_rmap_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv6_metric_rmap, + bgp_redistribute_ipv6_metric_rmap_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD + " metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int idx_number = 3; int idx_word = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + int idx_number = 3; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST, - metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (no_bgp_redistribute_ipv6, - no_bgp_redistribute_ipv6_cmd, - "no redistribute " FRR_IP6_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + no_bgp_redistribute_ipv6, + no_bgp_redistribute_ipv6_cmd, + "no redistribute " FRR_IP6_REDIST_STR_BGPD + " [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 2; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - return bgp_redistribute_unset(bgp, AFI_IP6, type, 0); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + uint32_t instance = 0; + + vty_out(vty, " redistribute %s", + yang_dnode_get_string(dnode, "./route-type")); + if ((instance = yang_dnode_get_uint16(dnode, "./route-instance"))) + vty_out(vty, " %d", instance); + if (yang_dnode_exists(dnode, "./metric")) + vty_out(vty, " metric %u", + yang_dnode_get_uint32(dnode, "./metric")); + if (yang_dnode_exists(dnode, "./rmap-policy-import")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-import")); + vty_out(vty, "\n"); } static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, @@ -14996,6 +15209,10 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi, return !!(filter->map[direct].name); case PEER_FT_UNSUPPRESS_MAP: return !!(filter->usmap.name); + case PEER_FT_ADVERTISE_MAP: + return !!(filter->advmap.aname + && ((filter->advmap.condition == direct) + && filter->advmap.cname)); default: return false; } @@ -15181,6 +15398,18 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer, vty_out(vty, " neighbor %s unsuppress-map %s\n", addr, filter->usmap.name); + /* advertise-map : always applied in OUT direction*/ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP, + CONDITION_NON_EXIST)) + vty_out(vty, + " neighbor %s advertise-map %s non-exist-map %s\n", + addr, filter->advmap.aname, filter->advmap.cname); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP, + CONDITION_EXIST)) + vty_out(vty, " neighbor %s advertise-map %s exist-map %s\n", + addr, filter->advmap.aname, filter->advmap.cname); + /* filter-list. */ if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, FILTER_IN)) @@ -17385,6 +17614,17 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd); + /* "neighbor advertise-map" commands. */ + install_element(BGP_NODE, &neighbor_advertise_map_hidden_cmd); + install_element(BGP_IPV4_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_VPNV4_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_VPNV6_NODE, &neighbor_advertise_map_cmd); + /* neighbor maximum-prefix-out commands. */ install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd); install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd); diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index a9e86ec09..349efbac4 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -186,6 +186,13 @@ extern int bgp_clear_star_soft_out(const char *name, char *errmsg, size_t errmsg_len); int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set); int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set); - +extern int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi, + int peer_type, uint16_t maxpaths, + uint16_t options, int set, char *errmsg, + size_t errmsg_len); +extern const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi); +extern bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi, + bool v2vimport, char *errmsg, + size_t errmsg_len); #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index be3322e46..cf16378de 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -54,6 +54,7 @@ #include "bgpd/bgp_debug.h" #include "bgpd/bgp_errors.h" #include "bgpd/bgp_community.h" +#include "bgpd/bgp_conditional_adv.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_regex.h" #include "bgpd/bgp_clist.h" @@ -6585,6 +6586,172 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi) return 0; } +static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi, + safi_t safi, const char *amap_name, + struct route_map *amap, + const char *cmap_name, + struct route_map *cmap, + bool condition, bool set) +{ + struct bgp_filter *filter; + bool filter_exists = false; + + filter = &peer->filter[afi][safi]; + + /* advertise-map is already configured. */ + if (filter->advmap.aname) { + filter_exists = true; + XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname); + XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname); + } + + route_map_counter_decrement(filter->advmap.amap); + + /* Removed advertise-map configuration */ + if (!set) { + memset(filter, 0, sizeof(struct bgp_filter)); + + /* 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); + + return; + } + + /* Update filter data with newly configured values. */ + filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name); + filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name); + filter->advmap.amap = amap; + filter->advmap.cmap = cmap; + filter->advmap.condition = condition; + route_map_counter_increment(filter->advmap.amap); + peer->advmap_config_change[afi][safi] = true; + + /* Increment condition_filter_count and/or create timer. */ + if (!filter_exists) { + filter->advmap.update_type = ADVERTISE; + bgp_conditional_adv_enable(peer, afi, safi); + } +} + +/* Set advertise-map to the peer but do not process peer route updates here. * + * Hold filter changes until the conditional routes polling thread is called * + * AS we need to advertise/withdraw prefixes (in advertise-map) based on the * + * condition (exist-map/non-exist-map) and routes(specified in condition-map) * + * in BGP table. So do not call peer_on_policy_change() here, only create * + * polling timer thread, update filters and increment condition_filter_count. + */ +int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, bool condition) +{ + struct peer *member; + struct listnode *node, *nnode; + + /* Set configuration on peer. */ + peer_advertise_map_filter_update(peer, afi, safi, advertise_name, + advertise_map, condition_name, + condition_map, condition, true); + + /* Check if handling a regular peer & Skip peer-group mechanics. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Set override-flag and process peer route updates. */ + SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP); + return 0; + } + + /* + * Set configuration on all peer-group members, unless they are + * explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP)) + continue; + + /* Set configuration on peer-group member. */ + peer_advertise_map_filter_update( + member, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, true); + } + + return 0; +} + +/* Unset advertise-map from the peer. */ +int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, bool condition) +{ + struct peer *member; + struct listnode *node, *nnode; + + /* advertise-map is not configured */ + if (!peer->filter[afi][safi].advmap.aname) + return 0; + + /* Unset override-flag unconditionally. */ + UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP); + + /* Inherit configuration from peer-group if peer is member. */ + if (peer_group_active(peer)) { + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].advmap.aname, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].advmap.amap); + } else + peer_advertise_map_filter_update( + peer, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, false); + + /* Check if handling a regular peer and skip peer-group mechanics. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Process peer route updates. */ + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Send normal update to %s for %s", + __func__, peer->host, + get_afi_safi_str(afi, safi, false)); + + peer_on_policy_change(peer, afi, safi, 1); + return 0; + } + + /* + * Remove configuration on all peer-group members, unless they are + * explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP)) + continue; + /* Remove configuration on peer-group member. */ + peer_advertise_map_filter_update( + member, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, false); + + /* Process peer route updates. */ + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Send normal update to %s for %s ", + __func__, member->host, + get_afi_safi_str(afi, safi, false)); + + peer_on_policy_change(member, afi, safi, 1); + } + + return 0; +} + int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi, uint32_t max, uint8_t threshold, int warning, uint16_t restart, bool force) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index eae3d9773..74828e91d 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -682,6 +682,10 @@ struct bgp { /* Process Queue for handling routes */ struct work_queue *process_queue; + /* BGP Conditional advertisement */ + uint32_t condition_filter_count; + struct thread *t_condition_check; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) @@ -759,6 +763,12 @@ struct bgp_nexthop { #define BGP_GTSM_HOPS_DISABLED 0 #define BGP_GTSM_HOPS_CONNECTED 1 +/* Advertise map */ +#define CONDITION_NON_EXIST false +#define CONDITION_EXIST true + +enum update_type { WITHDRAW, ADVERTISE }; + #include "filter.h" /* BGP filter structure. */ @@ -792,6 +802,19 @@ struct bgp_filter { char *name; struct route_map *map; } usmap; + + /* Advertise-map */ + struct { + char *aname; + struct route_map *amap; + + bool condition; + + char *cname; + struct route_map *cmap; + + enum update_type update_type; + } advmap; }; /* IBGP/EBGP identifier. We also have a CONFED peer, which is to say, @@ -1355,6 +1378,7 @@ struct peer { #define PEER_FT_PREFIX_LIST (1U << 2) /* prefix-list */ #define PEER_FT_ROUTE_MAP (1U << 3) /* route-map */ #define PEER_FT_UNSUPPRESS_MAP (1U << 4) /* unsuppress-map */ +#define PEER_FT_ADVERTISE_MAP (1U << 5) /* advertise-map */ /* ORF Prefix-list */ struct prefix_list *orf_plist[AFI_MAX][SAFI_MAX]; @@ -1448,6 +1472,10 @@ struct peer { /* Sender side AS path loop detection. */ bool as_path_loop_detection; + /* Conditional advertisement */ + bool advmap_config_change[AFI_MAX][SAFI_MAX]; + bool advmap_table_change; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(peer) @@ -1939,11 +1967,25 @@ extern int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi, const char *name, struct route_map *route_map); +extern int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, + bool condition); + extern int peer_password_set(struct peer *, const char *); extern int peer_password_unset(struct peer *); extern int peer_unsuppress_map_unset(struct peer *, afi_t, safi_t); +extern int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, + bool condition); + extern int peer_maximum_prefix_set(struct peer *, afi_t, safi_t, uint32_t, uint8_t, int, uint16_t, bool force); extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t); diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 3cb32b1f0..ea60b921d 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -61,6 +61,7 @@ bgpd_libbgp_a_SOURCES = \ bgpd/bgp_bfd.c \ bgpd/bgp_clist.c \ bgpd/bgp_community.c \ + bgpd/bgp_conditional_adv.c \ bgpd/bgp_damp.c \ bgpd/bgp_debug.c \ bgpd/bgp_dump.c \ @@ -137,6 +138,7 @@ noinst_HEADERS += \ bgpd/bgp_bfd.h \ bgpd/bgp_clist.h \ bgpd/bgp_community.h \ + bgpd/bgp_conditional_adv.h \ bgpd/bgp_damp.h \ bgpd/bgp_debug.h \ bgpd/bgp_dump.h \ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 79e5afde7..339be7f4d 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -2595,6 +2595,194 @@ This makes it possible to separate not only layer 3 networks like VRF-lite netwo Also, VRF netns based make possible to separate layer 2 networks on separate VRF instances. +.. _bgp-conditional-advertisement: + +BGP Conditional Advertisement +----------------------------- +The BGP conditional advertisement feature uses the ``non-exist-map`` or the +``exist-map`` and the ``advertise-map`` keywords of the neighbor advertise-map +command in order to track routes by the route prefix. + +``non-exist-map`` + 1. If a route prefix is not present in the output of non-exist-map command, + then advertise the route specified by the advertise-map command. + + 2. If a route prefix is present in the output of non-exist-map command, + then do not advertise the route specified by the addvertise-map command. + +``exist-map`` + 1. If a route prefix is present in the output of exist-map command, + then advertise the route specified by the advertise-map command. + + 2. If a route prefix is not present in the output of exist-map command, + then do not advertise the route specified by the advertise-map command. + +This feature is useful when some prefixes are advertised to one of its peers +only if the information from the other peer is not present (due to failure in +peering session or partial reachability etc). + +The conditional BGP announcements are sent in addition to the normal +announcements that a BGP router sends to its peer. + +The conditional advertisement process is triggered by the BGP scanner process, +which runs every 60 seconds. This means that the maximum time for the conditional +advertisement to take effect is 60 seconds. The conditional advertisement can take +effect depending on when the tracked route is removed from the BGP table and +when the next instance of the BGP scanner occurs. + +.. index:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME +.. clicmd:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME + + This command enables BGP scanner process to monitor routes specified by + exist-map or non-exist-map command in BGP table and conditionally advertises + the routes specified by advertise-map command. + +Sample Configuration +^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: frr + + interface enp0s9 + ip address 10.10.10.2/24 + ! + interface enp0s10 + ip address 10.10.20.2/24 + ! + interface lo + ip address 203.0.113.1/32 + ! + router bgp 2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.1 remote-as 1 + neighbor 10.10.20.3 remote-as 3 + ! + address-family ipv4 unicast + neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 10.10.20.3 soft-reconfiguration inbound + neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP + exit-address-family + ! + ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 + ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 + ip prefix-list EXIST seq 5 permit 10.10.10.10/32 + ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 + ip prefix-list IP1 seq 5 permit 10.139.224.0/20 + ! + bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 + bgp community-list standard DC-ROUTES seq 10 permit 64671:501 + bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 + bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 + ! + route-map ADV-MAP permit 10 + match ip address prefix-list IP1 + ! + route-map ADV-MAP permit 20 + match community DC-ROUTES + ! + route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE + ! + +Sample Output +^^^^^^^^^^^^^ + +When default route is present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are not advertised to R3. + +.. code-block:: frr + + Router2# show ip bgp + BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 0.0.0.0/0 10.10.10.1 0 0 1 i + *> 10.139.224.0/20 10.10.10.1 0 0 1 ? + *> 192.0.2.1/32 10.10.10.1 0 0 1 i + *> 192.0.2.5/32 10.10.10.1 0 0 1 i + + Displayed 4 routes and 4 total paths + Router2# show ip bgp neighbors 10.10.20.3 + + !--- Output suppressed. + + For address family: IPv4 Unicast + Update group 7, subgroup 7 + Packet Queue length 0 + Inbound soft reconfiguration allowed + Community attribute sent to this neighbor(all) + Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Withdraw + 0 accepted prefixes + + !--- Output suppressed. + + Router2# show ip bgp neighbors 10.10.20.3 advertised-routes + BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 0.0.0.0/0 0.0.0.0 0 1 i + *> 192.0.2.5/32 0.0.0.0 0 1 i + + Total number of prefixes 2 + +When default route is not present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are advertised to R3. + +.. code-block:: frr + + Router2# show ip bgp + BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.139.224.0/20 10.10.10.1 0 0 1 ? + *> 192.0.2.1/32 10.10.10.1 0 0 1 i + *> 192.0.2.5/32 10.10.10.1 0 0 1 i + + Displayed 3 routes and 3 total paths + + Router2# show ip bgp neighbors 10.10.20.3 + + !--- Output suppressed. + + For address family: IPv4 Unicast + Update group 7, subgroup 7 + Packet Queue length 0 + Inbound soft reconfiguration allowed + Community attribute sent to this neighbor(all) + Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Advertise + 0 accepted prefixes + + !--- Output suppressed. + + Router2# show ip bgp neighbors 10.10.20.3 advertised-routes + BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.139.224.0/20 0.0.0.0 0 1 ? + *> 192.0.2.1/32 0.0.0.0 0 1 i + *> 192.0.2.5/32 0.0.0.0 0 1 i + + Total number of prefixes 3 + Router2# + .. _bgp-debugging: Debugging diff --git a/lib/command.c b/lib/command.c index 1e950fe48..7d335e1c3 100644 --- a/lib/command.c +++ b/lib/command.c @@ -139,6 +139,27 @@ static struct cmd_node config_node = { .node_exit = vty_config_node_exit, }; +static bool vty_check_node_for_xpath_decrement(enum node_type target_node, + enum node_type node) +{ + /* bgp afi-safi (`address-family <afi> <safi>`) node + * does not increment xpath_index. + * In order to use (`router bgp`) BGP_NODE's xpath as a base, + * retain xpath_index as 1 upon exiting from + * afi-safi node. + */ + + if (target_node == BGP_NODE + && (node == BGP_IPV4_NODE || node == BGP_IPV6_NODE + || node == BGP_IPV4M_NODE || node == BGP_IPV6M_NODE + || node == BGP_VPNV4_NODE || node == BGP_VPNV6_NODE + || node == BGP_EVPN_NODE || node == BGP_IPV4L_NODE + || node == BGP_IPV6L_NODE )) + return false; + + return true; +} + /* This is called from main when a daemon is invoked with -v or --version. */ void print_version(const char *progname) { @@ -985,7 +1006,9 @@ int cmd_execute_command(vector vline, struct vty *vty, while (vty->node > CONFIG_NODE) { try_node = node_parent(try_node); vty->node = try_node; - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(try_node, + onode)) vty->xpath_index--; ret = cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd); @@ -1194,7 +1217,9 @@ int command_config_read_one_line(struct vty *vty, && ret != CMD_SUCCESS && ret != CMD_WARNING && vty->node > CONFIG_NODE) { vty->node = node_parent(vty->node); - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(vty->node, + saved_node)) vty->xpath_index--; ret = cmd_execute_command_strict(vline, vty, cmd); } @@ -1316,7 +1341,8 @@ void cmd_exit(struct vty *vty) } if (cnode->parent_node) vty->node = cnode->parent_node; - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(vty->node, cnode->node)) vty->xpath_index--; } diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index fac85c9dc..fd9b16643 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -289,8 +289,9 @@ void ospf_asbr_nssa_redist_task(struct ospf *ospf) continue; for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - ospf_external_lsa_refresh_type( - ospf, type, red->instance, LSA_REFRESH_FORCE); + ospf_external_lsa_refresh_type(ospf, type, + red->instance, + LSA_REFRESH_IF_CHANGED); } ospf_external_lsa_refresh_default(ospf); diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 297a79639..9ad7f2c4d 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -3639,3 +3639,34 @@ int ospf_lsa_refresh_walker(struct thread *t) return 0; } + +/* Flush the LSAs for the specific area */ +void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, + int type) +{ + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + area = ospf_area_get(ospf, area_id); + + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + if ((area->external_routing == OSPF_AREA_NSSA) || + (area->external_routing == OSPF_AREA_STUB)) { + LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) + if (IS_LSA_SELF(lsa) && + !(CHECK_FLAG(lsa->flags, + OSPF_LSA_LOCAL_XLT))) + ospf_lsa_flush_area(lsa, area); + } + break; + case OSPF_AS_NSSA_LSA: + LSDB_LOOP (NSSA_LSDB(area), rn, lsa) + if (IS_LSA_SELF(lsa)) + ospf_lsa_flush_area(lsa, area); + break; + default: + break; + } +} diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 90f7b5363..e63af4b34 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -339,5 +339,6 @@ extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *, struct ospf_lsa *); extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *, struct ospf_lsa *); - +extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, + int type); #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index bef9490ef..1060f20bd 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1446,6 +1446,8 @@ DEFUN (ospf_area_stub, return CMD_WARNING_CONFIG_FAILED; } + /* Flush the external LSAs from the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA); ospf_area_no_summary_unset(ospf, area_id); return CMD_SUCCESS; @@ -1568,6 +1570,8 @@ static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc, ospf_area_no_summary_unset(ospf, area_id); } + /* Flush the external LSA for the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA); ospf_schedule_abr_task(ospf); return CMD_SUCCESS; @@ -1673,6 +1677,8 @@ DEFUN (no_ospf_area_nssa, VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, argv[idx_ipv4_number]->arg); + /* Flush the NSSA LSA for the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA); ospf_area_nssa_unset(ospf, area_id, argc); ospf_schedule_abr_task(ospf); diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c index e95a1d11e..941d06761 100644 --- a/pimd/pim_igmp_mtrace.c +++ b/pimd/pim_igmp_mtrace.c @@ -82,10 +82,10 @@ static bool mtrace_fwd_info_weak(struct pim_instance *pim, zlog_debug("mtrace pim_nexthop_lookup OK"); if (PIM_DEBUG_MTRACE) - zlog_warn("mtrace next_hop=%s", - inet_ntop(nexthop.mrib_nexthop_addr.family, - &nexthop.mrib_nexthop_addr.u.prefix, - nexthop_str, sizeof(nexthop_str))); + zlog_debug("mtrace next_hop=%s", + inet_ntop(nexthop.mrib_nexthop_addr.family, + &nexthop.mrib_nexthop_addr.u.prefix, + nexthop_str, sizeof(nexthop_str))); if (nexthop.mrib_nexthop_addr.family == AF_INET) nh_addr = nexthop.mrib_nexthop_addr.u.prefix4; @@ -270,8 +270,8 @@ static uint32_t query_arrival_time(void) if (gettimeofday(&tv, NULL) < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn("Query arrival time lookup failed: errno=%d: %s", - errno, safe_strerror(errno)); + zlog_debug("Query arrival time lookup failed: errno=%d: %s", + errno, safe_strerror(errno)); return 0; } /* not sure second offset correct, as I get different value */ @@ -336,7 +336,7 @@ static int mtrace_send_packet(struct interface *ifp, if (ret < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn("Failed to set socket multicast TTL"); + zlog_debug("Failed to set socket multicast TTL"); ret = -1; goto close_fd; } @@ -354,14 +354,14 @@ static int mtrace_send_packet(struct interface *ifp, sizeof(group_str)); if (sent < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Send mtrace request failed for %s on%s: group=%s msg_size=%zd: errno=%d: %s", dst_str, ifp->name, group_str, mtrace_buf_len, errno, safe_strerror(errno)); } else { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Send mtrace request failed for %s on %s: group=%s msg_size=%zd: sent=%zd", dst_str, ifp->name, group_str, mtrace_buf_len, sent); @@ -411,7 +411,7 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr, if (!pim_nexthop_lookup(pim, &nexthop, ip_hdr->ip_dst, 0)) { close(fd); if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Dropping mtrace packet, no route to destination"); return -1; } @@ -440,7 +440,7 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr, if (sent < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Failed to forward mtrace packet: sendto errno=%d, %s", errno, safe_strerror(errno)); return -1; @@ -514,6 +514,7 @@ static int mtrace_send_mc_response(struct pim_instance *pim, struct listnode *chnextnode; struct pim_ifchannel *ch = NULL; int ret = -1; + char buf[PREFIX_STRLEN]; memset(&sg, 0, sizeof(struct prefix_sg)); sg.grp = mtracep->rsp_addr; @@ -523,9 +524,10 @@ static int mtrace_send_mc_response(struct pim_instance *pim, if (c_oil == NULL) { if (PIM_DEBUG_MTRACE) { zlog_debug( - "Dropping mtrace multicast response packet len=%u to %pI4", + "Dropping mtrace multicast response packet len=%u to %s", (unsigned int)mtrace_len, - &mtracep->rsp_addr); + inet_ntop(AF_INET, &mtracep->rsp_addr, + buf, sizeof(buf))); } return -1; } @@ -570,10 +572,10 @@ static int mtrace_send_response(struct pim_instance *pim, if (p_rpf == NULL) { if (PIM_DEBUG_MTRACE) - zlog_warn("mtrace no RP for %s", - inet_ntop(AF_INET, - &(mtracep->rsp_addr), - grp_str, sizeof(grp_str))); + zlog_debug("mtrace no RP for %s", + inet_ntop(AF_INET, + &(mtracep->rsp_addr), + grp_str, sizeof(grp_str))); return -1; } nexthop = p_rpf->source_nexthop; @@ -584,7 +586,7 @@ static int mtrace_send_response(struct pim_instance *pim, /* TODO: should use unicast rib lookup */ if (!pim_nexthop_lookup(pim, &nexthop, mtracep->rsp_addr, 1)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Dropped response qid=%ud, no route to response address", mtracep->qry_id); return -1; @@ -633,7 +635,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu", from_str, ifp->name, igmp_msg_len, sizeof(struct igmp_mtrace)); @@ -650,7 +652,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (recv_checksum != checksum) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: checksum mismatch: received=%x computed=%x", from_str, ifp->name, recv_checksum, checksum); return -1; @@ -700,12 +702,12 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, last_rsp_ind = r_len / sizeof(struct igmp_mtrace_rsp); if (last_rsp_ind > MTRACE_MAX_HOPS) { if (PIM_DEBUG_MTRACE) - zlog_warn("Mtrace request of excessive size"); + zlog_debug("Mtrace request of excessive size"); return -1; } } else { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: invalid length %d", from_str, ifp->name, igmp_msg_len); return -1; @@ -715,7 +717,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (IPV4_CLASS_DE(ntohl(ip_hdr->ip_dst.s_addr)) && !IPV4_MC_LINKLOCAL(ntohl(ip_hdr->ip_dst.s_addr))) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: not link-local multicast %pI4", from_str, ifp->name, &ip_hdr->ip_dst); return -1; @@ -848,7 +850,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr, if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu", from_str, ifp->name, igmp_msg_len, sizeof(struct igmp_mtrace)); @@ -865,7 +867,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr, if (recv_checksum != checksum) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace response from %s on %s: checksum mismatch: received=%x computed=%x", from_str, ifp->name, recv_checksum, checksum); return -1; diff --git a/staticd/static_vty.c b/staticd/static_vty.c index e2eb8cb7a..c3c453f42 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -499,12 +499,6 @@ DEFPY_YANG(ip_route_blackhole, "Table to configure\n" "The table number to configure\n") { - if (table_str && vrf && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, NULL, NULL, flag, tag_str, distance_str, vrf, label, table_str); @@ -818,12 +812,6 @@ DEFPY_YANG(ipv6_route_blackhole, "Table to configure\n" "The table number to configure\n") { - if (table_str && vrf && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, NULL, NULL, flag, tag_str, distance_str, vrf, label, table_str); diff --git a/tests/topotests/bgp_conditional_advertisement/__init__.py b/tests/topotests/bgp_conditional_advertisement/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/__init__.py diff --git a/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf new file mode 100644 index 000000000..633d1832f --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf @@ -0,0 +1,30 @@ +! +ip prefix-list CUST seq 5 permit 10.139.224.0/20 +ip prefix-list DEFAULT seq 5 permit 0.0.0.0/0 +ip prefix-list PL1 seq 5 permit 192.0.2.1/32 +! +route-map CUST permit 10 + match ip address prefix-list CUST + set community 64671:501 +! +route-map RM1 permit 10 + match ip address prefix-list PL1 + set community 64952:3008 +! +route-map DEF permit 10 + match ip address prefix-list DEFAULT + set community 64848:3011 65011:200 65013:200 +! +router bgp 1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.2 remote-as 2 + ! + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + network 192.0.2.1/32 route-map RM1 + network 192.0.2.5/32 + redistribute connected route-map CUST + neighbor 10.10.10.2 soft-reconfiguration inbound + exit-address-family +! diff --git a/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf new file mode 100644 index 000000000..bb887e41a --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf @@ -0,0 +1,19 @@ +! +hostname Router1 +! +ip route 0.0.0.0/0 blackhole +ip route 192.0.2.1/32 blackhole +ip route 192.0.2.2/32 blackhole +ip route 192.0.2.3/32 blackhole +ip route 192.0.2.4/32 blackhole +ip route 192.0.2.5/32 blackhole +! +interface r1-eth0 + ip address 10.10.10.1/24 +! +interface lo + ip address 10.139.224.1/20 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf new file mode 100644 index 000000000..c6147fe65 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf @@ -0,0 +1,44 @@ +! +ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 +ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 +ip prefix-list EXIST seq 5 permit 10.10.10.10/32 +ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 +ip prefix-list IP1 seq 5 permit 10.139.224.0/20 +ip prefix-list IP2 seq 5 permit 203.0.113.1/32 +! +bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 +bgp community-list standard DC-ROUTES seq 10 permit 64671:501 +bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 +bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 +! +route-map ADV-MAP-1 permit 10 + match ip address prefix-list IP1 +! +route-map ADV-MAP-1 permit 20 + match community DC-ROUTES +! +route-map ADV-MAP-2 permit 10 + match ip address prefix-list IP2 +! +route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE +! +route-map RMAP-1 deny 10 + match ip address prefix-list IP1 +! +route-map RMAP-2 deny 10 + match ip address prefix-list IP2 +! +router bgp 2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.1 remote-as 1 + neighbor 10.10.20.3 remote-as 3 + ! + address-family ipv4 unicast + network 203.0.113.1/32 + neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 10.10.20.3 soft-reconfiguration inbound + exit-address-family +! diff --git a/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf new file mode 100644 index 000000000..434ab68e3 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf @@ -0,0 +1,15 @@ +! +hostname Router2 +! +interface r2-eth0 + ip address 10.10.10.2/24 +! +interface r2-eth1 + ip address 10.10.20.2/24 +! +interface lo + ip address 203.0.113.1/32 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf new file mode 100644 index 000000000..2f4f5068d --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf @@ -0,0 +1,11 @@ +! +router bgp 3 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.20.2 remote-as 2 + ! + address-family ipv4 unicast + neighbor 10.10.20.2 soft-reconfiguration inbound + exit-address-family +! + diff --git a/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf new file mode 100644 index 000000000..0dadfdb3a --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf @@ -0,0 +1,12 @@ +! +hostname Router3 +! +interface r3-eth0 + ip address 10.10.20.3/24 +! +interface lo + ip address 198.51.100.1/32 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py new file mode 100644 index 000000000..0e31ab199 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py @@ -0,0 +1,961 @@ +#!/usr/bin/env python + +# +# test_bgp_conditional_advertisement.py +# +# Copyright (c) 2020 by +# Samsung R&D Institute India - Bangalore. +# Madhurilatha Kuruganti +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test BGP conditional advertisement functionality. + + +--------+ +--------+ +--------+ + | | | | | | + | R1 |------------| R2 |------------| R3 | + | | | | | | + +--------+ +--------+ +--------+ + +R2 is DUT and peers with R1 and R3 in default bgp instance. + +Following tests are covered under BGP conditional advertisement functionality. +Conditional advertisement +------------------------- +TC11: R3 BGP convergence, without advertise-map configuration. + All routes are advertised to R3. + +TC21: exist-map routes present in R2's BGP table. + advertise-map routes present in R2's BGP table are advertised to R3. +TC22: exist-map routes not present in R2's BGP table + advertise-map routes present in R2's BGP table are withdrawn from R3. +TC31: non-exist-map routes not present in R2's BGP table + advertise-map routes present in R2's BGP table are advertised to R3. +TC32: non-exist-map routes present in R2's BGP table + advertise-map routes present in R2's BGP table are withdrawn from R3. + +TC41: non-exist-map route-map configuration removed in R2. + advertise-map routes present in R2's BGP table are advertised to R3. +TC42: exist-map route-map configuration removed in R2 + advertise-map routes present in R2's BGP table are withdrawn from R3. + +Conditional advertisement(received routes) along with Route-map Filter +---------------------------------------------------------------------- +TC51: exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC52: exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. +TC53: non-exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC54: non-exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. + +TC61: exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC62: exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. +TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. + +Conditional advertisement(attached routes) along with Route-map Filter +----------------------------------------------------------------- +TC71: exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC72: exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. +TC73: non-exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC74: non-exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. + +TC81: exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC82: exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. +TC83: non-exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC84: non-exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. + +TC91: exist-map routes present in R2's BGP table, with route-map filter and network. + All routes are advertised to R3 including advertise-map routes. +TC92: exist-map routes present in R2's BGP table, with route-map filter and no network. + All routes are advertised to R3 except advertise-map routes. +TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network. + All routes are advertised to R3 including advertise-map routes. +TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network. + All routes are advertised to R3 except advertise-map routes. + +i.e. ++----------------+-------------------------+------------------------+ +| Routes in | exist-map status | advertise-map status | +| BGP table | | | ++----------------+-------------------------+------------------------+ +| Present | Condition matched | Advertise | ++----------------+-------------------------+------------------------+ +| Not Present | Condition not matched | Withdrawn | ++----------------+-------------------------+------------------------+ +| | non-exist-map status | advertise-map status | +| | | | ++----------------+-------------------------+------------------------+ +| Present | Condition matched | Withdrawn | ++----------------+-------------------------+------------------------+ +| Not Present | Condition not matched | Advertise | ++----------------+-------------------------+------------------------+ +Here in this topology, based on the default route presence in R2 and +the configured condition-map (exist-map/non-exist-map) 10.139.224.0/20 +will be either advertised/withdrawn to/from R3. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class BgpConditionalAdvertisementTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + r3 = tgen.add_router("r3") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(r2) + + switch = tgen.add_switch("s2") + switch.add_link(r2) + switch.add_link(r3) + + +def setup_module(mod): + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + tgen = Topogen(BgpConditionalAdvertisementTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +def test_bgp_conditional_advertisement(): + """ + Test BGP conditional advertisement functionality. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + router3 = tgen.gears["r3"] + + passed = "PASSED!!!" + failed = "FAILED!!!" + + def _all_routes_advertised(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _all_routes_withdrawn(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": None, + "10.139.224.0/20": None, + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + # BGP conditional advertisement with route-maps + # EXIST-MAP, ADV-MAP-1 and RMAP-1 + def _exist_map_routes_present(router): + return _all_routes_advertised(router) + + def _exist_map_routes_not_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": None, + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _exist_map_no_condition_route_map(router): + return _non_exist_map_routes_present(router) + + def _non_exist_map_no_condition_route_map(router): + return _all_routes_advertised(router) + + def _exist_map_routes_present_rmap_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": None, + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _exist_map_routes_present_no_rmap_filter(router): + return _all_routes_advertised(router) + + def _non_exist_map_routes_present_rmap_filter(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_present_no_rmap_filter(router): + return _non_exist_map_routes_present(router) + + def _exist_map_routes_not_present_rmap_filter(router): + return _all_routes_withdrawn(router) + + def _exist_map_routes_not_present_no_rmap_filter(router): + return _exist_map_routes_not_present(router) + + def _non_exist_map_routes_not_present_rmap_filter(router): + return _exist_map_routes_present_rmap_filter(router) + + def _non_exist_map_routes_not_present_no_rmap_filter(router): + return _non_exist_map_routes_not_present(router) + + # BGP conditional advertisement with route-maps + # EXIST-MAP, ADV-MAP-2 and RMAP-2 + def _exist_map_routes_not_present_rmap2_filter(router): + return _all_routes_withdrawn(router) + + def _exist_map_routes_not_present_no_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": None, + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present_no_rmap2_filter(router): + return _non_exist_map_routes_not_present(router) + + def _exist_map_routes_present_rmap2_filter(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _exist_map_routes_present_no_rmap2_filter(router): + return _all_routes_advertised(router) + + def _non_exist_map_routes_present_rmap2_filter(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_present_no_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _exist_map_routes_present_rmap2_network(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _exist_map_routes_present_rmap2_no_network(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_not_present_rmap2_network(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _non_exist_map_routes_not_present_rmap2_no_network(router): + return _all_routes_withdrawn(router) + + # TC11: R3 BGP convergence, without advertise-map configuration. + # All routes are advertised to R3. + test_func = functools.partial(_all_routes_advertised, router3) + success, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + + msg = 'TC11: "router3" BGP convergence - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC21: exist-map routes present in R2's BGP table. + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC21: exist-map routes present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC22: exist-map routes not present in R2's BGP table + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC22: exist-map routes not present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC31: non-exist-map routes not present in R2's BGP table + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_not_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC31: non-exist-map routes not present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC32: non-exist-map routes present in R2's BGP table + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC32: non-exist-map routes present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC41: non-exist-map route-map configuration removed in R2. + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + no route-map EXIST-MAP permit 10 + """ + ) + + test_func = functools.partial(_non_exist_map_no_condition_route_map, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC41: non-exist-map route-map removed in "router2" - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC42: exist-map route-map configuration removed in R2 + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_no_condition_route_map, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC42: exist-map route-map removed in "router2" - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC51: exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE + ! + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC51: exist-map routes present with route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC52: exist-map routes present in R2's BGP table, no route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC52: exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC53: non-exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC53: non-exist-map routes present, with route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC54: non-exist-map routes present in R2's BGP table, no route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC54: non-exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC61: exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC61: exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC62: exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC62: exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC63: non-exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_no_rmap_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC64: non-exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC71: exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC71: exist-map routes present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC72: exist-map routes present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_no_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC72: exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC73: non-exist-map routes present in R2's BGP table, with route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC73: non-exist-map routes present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC74: non-exist-map routes present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC74: non-exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC81: exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC81: exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC82: exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _exist_map_routes_not_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC82: exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC83: non-exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC83: non-exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC84: non-exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC84: non-exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC91: exist-map routes present in R2's BGP table, with route-map filter and network. + # All routes are advertised to R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_network, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC91: exist-map routes present, route-map filter and network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC92: exist-map routes present in R2's BGP table, with route-map filter and no network. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no network 203.0.113.1/32 + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_no_network, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC92: exist-map routes present, route-map filter and no network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network. + # All routes are advertised to R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + network 203.0.113.1/32 + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_network, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC93: non-exist-map routes not present, route-map filter and network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no network 203.0.113.1/32 + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_no_network, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC94: non-exist-map routes not present, route-map filter and no network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons index 0221b0c19..f6d512be7 100644 --- a/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons @@ -12,7 +12,7 @@ # When using "vtysh" such a config file is also needed. It should be owned by # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. # -# The watchfrr and zebra daemons are always started. +# The watchfrr, zebra and staticd daemons are always started. # bgpd=no ospfd=no diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang index f02d28800..de78758db 100644 --- a/yang/frr-bgp-common.yang +++ b/yang/frr-bgp-common.yang @@ -779,6 +779,48 @@ submodule frr-bgp-common { description "Apply route map to aggregate network."; } + + leaf origin { + type enumeration { + enum "igp" { + value 0; + description + "Local IGP."; + } + enum "egp" { + value 1; + description + "Remote EGP."; + } + enum "incomplete" { + value 2; + description + "Unknown heritage."; + } + enum "unspecified" { + value 255; + description + "Unspecified."; + } + } + default "unspecified"; + description + "BGP origin type."; + } + + leaf match-med { + type boolean; + default "false"; + description + "When set to 'true' aggregate-route matches only + med."; + } + + leaf suppress-map { + type string; + description + "Suppress more specific routes specified in route-map."; + } } grouping admin-distance { @@ -791,6 +833,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "20"; description "Administrative distance for routes learned from external BGP (EBGP)."; @@ -800,6 +843,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "200"; description "Administrative distance for routes learned from internal BGP (IBGP)."; @@ -809,6 +853,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "200"; description "Administrative distance for routes learned from local."; @@ -1017,6 +1062,7 @@ submodule frr-bgp-common { case import-export { uses rt-list; } + case both { leaf-list rt-list { type rt-types:route-target; @@ -1064,7 +1110,11 @@ submodule frr-bgp-common { grouping global-afi-safi-vpn-config { container vpn-config { - uses route-distinguisher-params; + leaf rd { + type string; + description + "Route distinguisher value as per RFC4364."; + } uses vpn-label-params; diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang index e10b5e784..820c4b286 100644 --- a/yang/frr-bgp.yang +++ b/yang/frr-bgp.yang @@ -353,6 +353,8 @@ module frr-bgp { uses distance-per-route-config; } + uses route-flap-dampening; + uses mp-afi-unicast-common; uses global-filter-config; @@ -362,10 +364,14 @@ module frr-bgp { augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast" { uses global-group-use-multiple-paths; + + uses route-flap-dampening; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast" { uses global-group-use-multiple-paths; + + uses route-flap-dampening; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-multicast" { @@ -411,6 +417,8 @@ module frr-bgp { description "IPv4 multicast destination prefix."; } + + uses distance-per-route-config; } uses admin-distance; @@ -463,8 +471,12 @@ module frr-bgp { description "IPv6 multicast destination prefix."; } + + uses distance-per-route-config; } + uses route-flap-dampening; + uses admin-distance; } diff --git a/yang/frr-route-types.yang b/yang/frr-route-types.yang index 057c32a7e..5a0f58071 100644 --- a/yang/frr-route-types.yang +++ b/yang/frr-route-types.yang @@ -76,6 +76,9 @@ module frr-route-types { enum vnc { value 17; } + enum vnc-direct { + value 18; + } enum babel { value 22; } @@ -120,6 +123,9 @@ module frr-route-types { enum vnc { value 17; } + enum vnc-direct { + value 18; + } enum babel { value 22; } diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 8e9a1a4e8..4a2d8db42 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -490,6 +490,8 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) struct timeval detect_start_time = {0, 0}; char timebuf[MONOTIME_STRLEN]; char thread_buf[THREAD_TIMER_STRLEN]; + time_t uptime; + char up_str[MONOTIME_STRLEN]; zvrf = zebra_vrf_get_evpn(); if (!zvrf) @@ -498,6 +500,11 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) vty = (struct vty *)ctxt; prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)); + uptime = monotime(NULL); + uptime -= mac->uptime; + + frrtime_to_interval(uptime, up_str, sizeof(up_str)); + if (json) { json_object *json_mac = json_object_new_object(); @@ -535,6 +542,7 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) json_object_boolean_true_add(json_mac, "remoteGatewayMac"); + json_object_string_add(json_mac, "uptime", up_str); json_object_int_add(json_mac, "localSequence", mac->loc_seq); json_object_int_add(json_mac, "remoteSequence", mac->rem_seq); @@ -648,9 +656,9 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) sizeof(thread_buf), mac->hold_timer)); vty_out(vty, "\n"); - vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq, + vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq, mac->rem_seq); - vty_out(vty, "\n"); + vty_out(vty, " Uptime: %s\n", up_str); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { vty_out(vty, " Duplicate, detected at %s", @@ -972,6 +980,7 @@ zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr) mac->neigh_list = list_new(); mac->neigh_list->cmp = neigh_list_cmp; + mac->uptime = monotime(NULL); if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char buf[ETHER_ADDR_STRLEN]; @@ -1459,6 +1468,8 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, bool sticky; bool remote_gw; + mac->uptime = monotime(NULL); + old_flags = mac->flags; sticky = !!CHECK_FLAG(old_flags, ZEBRA_MAC_STICKY); remote_gw = !!CHECK_FLAG(old_flags, ZEBRA_MAC_REMOTE_DEF_GW); diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index f9ca81445..596fd0faa 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -129,6 +129,8 @@ struct zebra_mac_t_ { * ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY */ uint32_t sync_neigh_cnt; + + time_t uptime; }; /* diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index bb848255d..e4f38008a 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -592,6 +592,7 @@ static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn, n->zevpn = zevpn; n->dad_ip_auto_recovery_timer = NULL; n->flags = n_flags; + n->uptime = monotime(NULL); if (!zmac) zmac = zebra_evpn_mac_lookup(zevpn, mac); @@ -802,6 +803,8 @@ zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n, n->ifindex = ifindex; inform_dataplane = true; } + + n->uptime = monotime(NULL); } /* update the neigh seq. we don't bother with the mac seq as @@ -1798,11 +1801,18 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct timeval detect_start_time = {0, 0}; char timebuf[MONOTIME_STRLEN]; char thread_buf[THREAD_TIMER_STRLEN]; + time_t uptime; + char up_str[MONOTIME_STRLEN]; zvrf = zebra_vrf_get_evpn(); if (!zvrf) return; + uptime = monotime(NULL); + uptime -= n->uptime; + + frrtime_to_interval(uptime, up_str, sizeof(up_str)); + ipaddr2str(&n->ip, buf2, sizeof(buf2)); prefix_mac2str(&n->emac, buf1, sizeof(buf1)); type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote"; @@ -1815,6 +1825,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) ipaddr2str(&n->ip, buf2, sizeof(buf2))); vty_out(vty, " Type: %s\n", type_str); vty_out(vty, " State: %s\n", state_str); + vty_out(vty, " Uptime: %s\n", up_str); vty_out(vty, " MAC: %s\n", prefix_mac2str(&n->emac, buf1, sizeof(buf1))); vty_out(vty, " Sync-info:"); @@ -1841,6 +1852,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) vty_out(vty, " -"); vty_out(vty, "\n"); } else { + json_object_string_add(json, "uptime", up_str); json_object_string_add(json, "ip", buf2); json_object_string_add(json, "type", type_str); json_object_string_add(json, "state", state_str); diff --git a/zebra/zebra_evpn_neigh.h b/zebra/zebra_evpn_neigh.h index 4b98266c8..50efdc0e0 100644 --- a/zebra/zebra_evpn_neigh.h +++ b/zebra/zebra_evpn_neigh.h @@ -113,6 +113,8 @@ struct zebra_neigh_t_ { time_t dad_dup_detect_time; + time_t uptime; + /* used for ageing out the PEER_ACTIVE flag */ struct thread *hold_timer; }; |