]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: convert addr-family clis to transactional clis
authorChirag Shah <chirag@nvidia.com>
Wed, 19 Aug 2020 04:21:16 +0000 (21:21 -0700)
committerChirag Shah <chirag@nvidia.com>
Mon, 26 Oct 2020 15:57:15 +0000 (08:57 -0700)
Convert IPv4 and IPv6 unicast address family clis
to transactional clis and implementation of
northbound callbacks.

Signed-off-by: Chirag Shah <chirag@nvidia.com>
bgpd/bgp_nb.c
bgpd/bgp_nb.h
bgpd/bgp_nb_config.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_vty.c
bgpd/bgp_vty.h

index e9770117e7448487b3af18cb294d089d9035c7af..8095c04405165fe627ff61c92feb39ef3605a95a 100644 (file)
@@ -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,
                        }
                },
                {
@@ -1338,8 +1344,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/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,
                        }
                },
                {
@@ -1355,6 +1363,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_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-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 = {
@@ -1393,6 +1408,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,
                        }
                },
                {
@@ -1411,8 +1434,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,
                        }
                },
                {
@@ -1429,6 +1454,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = bgp_global_afi_safis_afi_safi_ipv4_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/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 = {
@@ -1459,6 +1491,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,
                        }
                },
                {
@@ -1480,18 +1513,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,
                        }
                },
                {
@@ -1499,6 +1535,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,
                        }
                },
                {
@@ -1506,6 +1543,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,
                        }
                },
                {
@@ -1513,6 +1551,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,
                        }
                },
                {
@@ -1546,8 +1585,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,
                        }
                },
                {
@@ -1573,8 +1614,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,
                        }
                },
                {
@@ -1605,8 +1648,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/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,
                        }
                },
                {
@@ -1622,6 +1667,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_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-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 = {
@@ -1660,6 +1712,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/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,
                        }
                },
                {
@@ -1678,8 +1738,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,
                        }
                },
                {
@@ -1696,6 +1758,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = 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/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 = {
@@ -1773,6 +1842,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,
                        }
                },
                {
@@ -1780,6 +1850,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,
                        }
                },
                {
@@ -1814,6 +1885,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,
                        }
                },
                {
@@ -1829,6 +1908,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_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",
+                       .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 = {
@@ -1867,6 +1953,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/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,
                        }
                },
                {
@@ -1882,6 +1976,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_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",
+                       .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 = {
@@ -1919,8 +2020,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-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,
                        }
                },
                {
@@ -1978,8 +2081,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-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,
                        }
                },
                {
@@ -1995,6 +2100,12 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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 = {
@@ -2013,6 +2124,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify,
                        }
                },
+               {
+                       .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,
+                       }
+               },
                {
                        .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable",
                        .cbs = {
@@ -2057,8 +2175,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,
                        }
                },
                {
@@ -2116,8 +2236,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/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,
                        }
                },
                {
@@ -2133,6 +2255,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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 = {
@@ -2167,6 +2296,12 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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 = {
@@ -2195,8 +2330,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,
                        }
                },
                {
index aa47663e9497ca0824318c1d66a3712edd1d6193..f05c22e2e2a0e0bf243c7f4972c2262fef7315ed 100644 (file)
@@ -3491,10 +3491,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 */
@@ -3507,5 +3565,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
index 593833c03252da29f969b7dc3f9650272124032c..3eb501b55880627df4f33a29769f70e6e21d45e0 100644 (file)
@@ -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,14 +5587,7 @@ 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)
 {
-       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;
 }
@@ -5509,8 +5599,11 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_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;
        }
 
@@ -5524,14 +5617,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy(
 int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_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 unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -5543,12 +5629,46 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify(
 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;
        }
 
@@ -5558,14 +5678,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify
 int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_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;
-       }
+       /* Handled in unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -5577,14 +5690,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destro
 int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_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;
-       }
+       /* Handled in unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -5592,6 +5698,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export
 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:
@@ -5604,6 +5713,72 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export
        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");
+
+       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/aggregate-route
@@ -5630,9 +5805,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_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_aggregate_route_destroy(args);
        }
 
        return NB_OK;
@@ -5729,6 +5904,60 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify(
        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
@@ -5755,9 +5984,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;
@@ -5816,6 +6045,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
@@ -5825,10 +6116,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;
        }
 
@@ -5876,8 +6167,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:
@@ -5971,6 +6276,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
@@ -5978,18 +6322,70 @@ 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;
 }
 
+/*
+ * 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
@@ -5997,12 +6393,22 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_p
 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;
        }
 
@@ -6043,6 +6449,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
@@ -6065,12 +6514,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;
        }
 
@@ -6145,21 +6613,52 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i
        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
- */
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
-       struct nb_cb_modify_args *args)
+static int
+bgp_global_afi_safis_admin_distance_modify(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;
-       }
+       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
+ */
+void bgp_global_afi_safis_afi_safi_ipv4_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/ipv4-unicast/admin-distance/external
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
 
        return NB_OK;
 }
@@ -6171,14 +6670,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
 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;
 }
@@ -6190,14 +6682,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify(
 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;
 }
@@ -6236,6 +6721,83 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy
        return NB_OK;
 }
 
+static int bgp_global_afi_safi_ip_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;
+       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;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_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;
+       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;
+}
+
 /*
  * XPath:
  * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rd
@@ -6243,12 +6805,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;
        }
 
@@ -6262,9 +6846,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;
@@ -6338,6 +6923,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
@@ -6345,13 +6993,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;
@@ -6364,9 +7031,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;
@@ -6379,13 +7096,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;
@@ -6398,18 +7135,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
@@ -6417,13 +7320,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;
@@ -6436,9 +7358,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;
@@ -6451,13 +7468,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;
@@ -6466,13 +7501,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;
@@ -6489,9 +7542,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;
@@ -6504,8 +7558,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;
        }
 
@@ -6655,14 +7711,7 @@ 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)
 {
-       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;
 }
@@ -6674,8 +7723,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_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;
        }
 
@@ -6689,14 +7740,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
 int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_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 unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -6708,14 +7752,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify(
 int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_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 unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -6742,14 +7779,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destro
 int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_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;
-       }
+       /* Handled in unicast_network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -6795,9 +7825,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_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_aggregate_route_destroy(args);
        }
 
        return NB_OK;
@@ -6920,9 +7950,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,10 +8020,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_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;
        }
 
@@ -7041,8 +8071,22 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_
 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:
@@ -7143,13 +8187,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_deca
 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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
@@ -7230,12 +8285,31 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create(
 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;
        }
 
@@ -7310,6 +8384,16 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i
        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
+ */
+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
@@ -7317,14 +8401,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i
 int bgp_global_afi_safis_afi_safi_ipv6_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;
 }
@@ -7336,14 +8413,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify(
 int bgp_global_afi_safis_afi_safi_ipv6_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;
 }
@@ -7355,14 +8425,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify(
 int bgp_global_afi_safis_afi_safi_ipv6_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;
 }
@@ -7408,13 +8471,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;
@@ -7427,9 +8510,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;
@@ -7510,13 +8594,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;
@@ -7529,9 +8633,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;
@@ -7582,13 +8687,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;
@@ -7601,9 +8725,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;
@@ -7620,9 +8745,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;
@@ -7635,9 +8761,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;
@@ -7654,9 +8781,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;
@@ -7669,9 +8797,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;
@@ -7820,13 +8949,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;
@@ -7894,10 +9034,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enab
 {
        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;
        }
 
@@ -8047,13 +9187,24 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unre
 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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
@@ -8066,8 +9217,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:
@@ -8121,10 +9282,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enab
 {
        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;
        }
 
@@ -8274,14 +9435,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unre
 int bgp_global_afi_safis_afi_safi_ipv4_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;
 }
@@ -8293,8 +9447,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_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;
        }
 
@@ -8539,9 +9695,9 @@ 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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
        }
 
        return NB_OK;
@@ -8662,10 +9818,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_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;
        }
 
@@ -8808,6 +9964,16 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_de
        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
@@ -8815,14 +9981,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_de
 int bgp_global_afi_safis_afi_safi_ipv4_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;
 }
@@ -8834,14 +9993,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify(
 int bgp_global_afi_safis_afi_safi_ipv4_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;
 }
@@ -8853,14 +10005,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
 int bgp_global_afi_safis_afi_safi_ipv4_multicast_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;
 }
@@ -8874,10 +10019,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;
        }
 
@@ -9061,14 +10206,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;
 }
@@ -9080,8 +10218,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;
        }
 
@@ -9326,14 +10467,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_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;
 }
 
+/*
+ * 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_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
@@ -9341,14 +10492,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
 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;
 }
@@ -9360,14 +10504,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify(
 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;
 }
@@ -9379,14 +10516,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify(
 int bgp_global_afi_safis_afi_safi_ipv6_multicast_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;
 }
index b637191d103508205a129640bcdbf39c1d4c1b68..5f6272b16ecb10d1edd1f5078607e906e10a9e83 100644 (file)
@@ -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"
@@ -5584,28 +5587,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 +5605,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 +5644,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 +5708,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 +6158,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 +6191,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 +7316,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 +7395,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 +7464,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 +7502,39 @@ 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"
+       "}",
+       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 +7543,128 @@ 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 (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);
+
+       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"
+          "}",
+          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 (rmap_name)
+               nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
+                                     rmap_name);
+
+       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 bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
-                                rmap_name, summary_only != NULL, as_set,
-                                origin, match_med != NULL, suppress_map);
+       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");
+
+       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));
+
+       vty_out(vty, "\n");
 }
 
 /* Redistribute route treatment. */
@@ -13385,28 +13494,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 +13531,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 +13634,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 +13655,363 @@ 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;
+       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")
+{
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       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);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-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")
+void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
+                                                       struct lyd_node *dnode,
+                                                       bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       uint8_t distance_ebgp, distance_ibgp, distance_local;
+
+       distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
+       distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
+       distance_local = yang_dnode_get_uint8(dnode, "./local");
+
+       vty_out(vty, "  distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
+               distance_local);
+}
+
+static int bgp_nb_distance_source_set(struct vty *vty, struct cmd_token **argv,
+                                     int argc)
+{
+       int idx_number = 1;
+       int idx_ip_prefixlen = 2;
+       int idx_word = 3;
        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;
+       nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       if (argv_find(argv, argc, "WORD", &idx_word))
+               nb_cli_enqueue_change(vty, "./access-list-policy-export",
+                                     NB_OP_CREATE, argv[idx_word]->arg);
+
+       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),
+               argv[idx_ip_prefixlen]->arg);
+
+       return nb_cli_apply_changes(vty, xpath);
 }
 
+static int bgp_nb_distance_source_unset(struct vty *vty,
+                                       struct cmd_token **argv, int argc)
+{
+       int idx_ip_prefixlen = 3;
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       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),
+               argv[idx_ip_prefixlen]->arg);
 
-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")
+       return nb_cli_apply_changes(vty, xpath);
+}
+
+DEFUN_YANG(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 bgp_nb_distance_source_set(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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")
 {
-       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;
+       return bgp_nb_distance_source_unset(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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;
+       return bgp_nb_distance_source_set(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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;
+       return bgp_nb_distance_source_unset(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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")
 {
-       bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
-       return CMD_SUCCESS;
+       int idx_number = 1;
+       int idx_ip_prefixlen = 2;
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       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),
+               argv[idx_ip_prefixlen]->arg);
+
+       return nb_cli_apply_changes(vty, xpath);
 }
 
-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")
+DEFUN_YANG(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;
+       return bgp_nb_distance_source_unset(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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;
+       return bgp_nb_distance_source_set(vty, argv, argc);
 }
 
-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")
+DEFUN_YANG(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")
 {
-       bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
-       return CMD_SUCCESS;
+       return bgp_nb_distance_source_unset(vty, argv, argc);
 }
 
-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")
+void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       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_YANG(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")
 {
-       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];
 
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
        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;
-       }
+               nb_cli_enqueue_change(vty, "./reach-decay", NB_OP_MODIFY,
+                                     argv[idx_half_life]->arg);
+               nb_cli_enqueue_change(vty, "./reuse-above", NB_OP_MODIFY,
+                                     argv[idx_reuse]->arg);
+               nb_cli_enqueue_change(vty, "./suppress-above", NB_OP_MODIFY,
+                                     argv[idx_suppress]->arg);
+               nb_cli_enqueue_change(vty, "./unreach-decay", NB_OP_MODIFY,
+                                     argv[idx_max_suppress]->arg);
+       }
+       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_YANG(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")
+{
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
 
-       /*
-        * 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;
-       }
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       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. */
index 4a4959298a15ef776f6987cceb130deb0d25ac72..3281ae32b0e91d4cf707a013edd7fc4770314cef 100644 (file)
@@ -719,4 +719,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 */
index 087836425b28f7f06026d05fe10bbf8d936b1e50..1ce6bd4f2d070e14de139013cbf025d76f201c9b 100644 (file)
@@ -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);
@@ -7890,6 +8022,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 +8091,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 +8230,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 +8240,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 +8255,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 +8380,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 +8391,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 +8535,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 +8558,32 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
                return CMD_WARNING;
        }
 
-       if (argv_find(argv, argc, "no", &idx))
-               remove = true;
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
 
-       afi = vpn_policy_getafi(vty, bgp, true);
-       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/import-vrf-list[vrf='%s']",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi), import_name);
 
-       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);
-
-               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 +8591,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");
 
-       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);
-       }
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return CMD_SUCCESS;
+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");
+}
+
+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 +8701,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 +8754,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 +8787,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 +8864,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,
@@ -14247,24 +14414,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");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       bgp_redist_add(bgp, AFI_IP, type, 0);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, false);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14272,33 +14438,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];
+
+       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);
 
-       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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14308,32 +14469,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];
+
+       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);
 
-       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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14343,39 +14500,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 +14541,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 +14582,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 +14611,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];
+
+       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);
 
-       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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap,
@@ -14510,38 +14649,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);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       metric = strtoul(argv[idx_number_2]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       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);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number_2]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric,
@@ -14554,45 +14687,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];
 
-       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_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);
+       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_2]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14608,45 +14734,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 +14781,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 +14821,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 +14856,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");
 
-       bgp_redist_add(bgp, AFI_IP6, type, 0);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       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 +14907,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];
 
-       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);
+       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);
+       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");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
+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,
index a9e86ec09a999e23a0c300493dc4b03bf53e2431..349efbac454a3f738f90b629a4ad2505941bb003 100644 (file)
@@ -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 */