diff options
author | Chirag Shah <chirag@nvidia.com> | 2020-08-12 22:30:24 +0200 |
---|---|---|
committer | Chirag Shah <chirag@nvidia.com> | 2020-10-03 20:25:37 +0200 |
commit | ff8a8a7ac10b3211d5586c29dfcc5a3b32841029 (patch) | |
tree | 3a6354d31147a423a90c05a6abb3a48fcfde83a5 /bgpd | |
parent | bgpd: register northbound callbacks to bootstrap (diff) | |
download | frr-ff8a8a7ac10b3211d5586c29dfcc5a3b32841029.tar.xz frr-ff8a8a7ac10b3211d5586c29dfcc5a3b32841029.zip |
bgpd: convert global config to transactional cli
Convert global congigurations clis to transactional
clis using northbound plugin callbacks.
Signed-off-by: Chirag Shah <chirag@nvidia.com>
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 6 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_nb.c | 41 | ||||
-rw-r--r-- | bgpd/bgp_nb.h | 68 | ||||
-rw-r--r-- | bgpd/bgp_nb_config.c | 1033 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 1756 | ||||
-rw-r--r-- | bgpd/bgp_vty.h | 7 | ||||
-rw-r--r-- | bgpd/bgpd.c | 10 | ||||
-rw-r--r-- | bgpd/bgpd.h | 7 |
9 files changed, 1886 insertions, 1044 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 5ef3cf736..b33251635 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2581,7 +2581,7 @@ void vpn_leak_postchange_all(void) * also VRF Y should unimport its routes from VRF X table. * This will ensure VPN table is cleaned up appropriately. */ -int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) +void bgp_vpn_leak_unimport(struct bgp *from_bgp) { struct bgp *to_bgp; const char *tmp_name; @@ -2593,7 +2593,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) int debug; if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) - return 0; + return; debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF)); @@ -2662,7 +2662,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) } } } - return 0; + return; } /* When a router bgp is configured, there could be a bgp vrf diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index ccd0d9616..df2544d60 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -266,7 +266,7 @@ extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); extern void vpn_leak_postchange_all(void); extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, bool is_config); -extern int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty); +extern void bgp_vpn_leak_unimport(struct bgp *from_bgp); extern void bgp_vpn_leak_export(struct bgp *from_bgp); #endif /* _QUAGGA_BGP_MPLSVPN_H */ diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c index 1983b7ae6..b4a4269b0 100644 --- a/bgpd/bgp_nb.c +++ b/bgpd/bgp_nb.c @@ -29,6 +29,7 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global", .cbs = { + .cli_show = cli_show_router_bgp, .create = routing_control_plane_protocols_control_plane_protocol_bgp_global_create, .destroy = routing_control_plane_protocols_control_plane_protocol_bgp_global_destroy, } @@ -42,6 +43,7 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/router-id", .cbs = { + .cli_show = cli_show_router_bgp_router_id, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_modify, .destroy = routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_destroy, } @@ -49,6 +51,7 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/identifier", .cbs = { + .cli_show = cli_show_router_bgp_confederation_identifier, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_identifier_modify, .destroy = routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_identifier_destroy, } @@ -56,11 +59,19 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/member-as", .cbs = { + .cli_show = cli_show_router_bgp_confederation_member_as, .create = routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_member_as_create, .destroy = routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_member_as_destroy, } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config", + .cbs = { + .cli_show = cli_show_router_bgp_med_config, + .apply_finish = routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_apply_finish, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_enable_med_admin_modify, @@ -86,6 +97,12 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector", + .cbs = { + .cli_show = cli_show_router_bgp_route_reflector, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/route-reflector-cluster-id", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_route_reflector_route_reflector_cluster_id_modify, @@ -105,6 +122,13 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options", + .cbs = { + .apply_finish = routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_apply_finish, + .cli_show = cli_show_router_bgp_route_selection, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_always_compare_med_modify, @@ -160,6 +184,12 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config", + .cbs = { + .cli_show = cli_show_router_global_neighbor_config, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/dynamic-neighbors-limit", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify, @@ -231,12 +261,14 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/subgroup-pkt-queue-size", .cbs = { + .cli_show = cli_show_router_global_update_group_config_subgroup_pkt_queue_size, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/coalesce-time", .cbs = { + .cli_show = cli_show_router_global_update_group_config_coalesce_time, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_global_update_group_config_coalesce_time_modify, } }, @@ -287,54 +319,63 @@ const struct frr_yang_module_info frr_bgp_info = { { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-multihop-connected-route-check", .cbs = { + .cli_show = cli_show_router_global_ebgp_multihop_connected_route_check, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_multihop_connected_route_check_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/fast-external-failover", .cbs = { + .cli_show = cli_show_router_bgp_fast_external_failover, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_fast_external_failover_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-pref", .cbs = { + .cli_show = cli_show_router_bgp_local_pref, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_local_pref_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/default-shutdown", .cbs = { + .cli_show = cli_show_router_bgp_default_shutdown, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_default_shutdown_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-requires-policy", .cbs = { + .cli_show = cli_show_router_bgp_ebgp_requires_policy, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_requires_policy_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-hostname", .cbs = { + .cli_show = cli_show_router_bgp_show_hostname, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_show_hostname_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-nexthop-hostname", .cbs = { + .cli_show = cli_show_router_bgp_show_nexthop_hostname, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_show_nexthop_hostname_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/import-check", .cbs = { + .cli_show = cli_show_router_bgp_import_check, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_import_check_modify, } }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-shutdown/enable", .cbs = { + .cli_show = cli_show_router_bgp_graceful_shutdown, .modify = routing_control_plane_protocols_control_plane_protocol_bgp_global_graceful_shutdown_enable_modify, } }, diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h index ecfdf987d..2bed6bcfe 100644 --- a/bgpd/bgp_nb.h +++ b/bgpd/bgp_nb.h @@ -3406,4 +3406,72 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_peer_groups_peer_ struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); + +/* Optional 'cli_show' callbacks. */ +void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_route_selection(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_default_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_fast_external_failover(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_global_neighbor_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_global_update_group_config_subgroup_pkt_queue_size( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_global_update_group_config_coalesce_time( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_global_ebgp_multihop_connected_route_check( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_route_reflector(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_confederation_identifier(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_confederation_member_as(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_graceful_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); + +void routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_apply_finish( + struct nb_cb_apply_finish_args *args); +void routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_apply_finish( + struct nb_cb_apply_finish_args *args); + +/* xpath macros */ +/* route-list */ +#define FRR_BGP_GLOBAL_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-bgp:bgp/global" + +#define FRR_BGP_GLOBAL_AS_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-bgp:bgp/local-as[" + #endif diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index a0b65056c..e3bb7ec29 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -25,6 +25,24 @@ #include "bgpd/bgp_nb.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_vty.h" +#include "bgpd/bgp_mplsvpn.h" +#include "bgpd/bgp_fsm.h" +#include "bgpd/bgp_addpath.h" +#include "bgpd/bgp_updgrp.h" +#include "bgpd/bgp_io.h" + +FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, + { .val_ulong = 10, .match_profile = "datacenter", }, + { .val_ulong = 120 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME, + { .val_ulong = 9, .match_profile = "datacenter", }, + { .val_ulong = 180 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, + { .val_ulong = 3, .match_profile = "datacenter", }, + { .val_ulong = 60 }, +) /* * XPath: @@ -33,12 +51,70 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_create( struct nb_cb_create_args *args) { + + const struct lyd_node *vrf_dnode; + struct bgp *bgp; + struct vrf *vrf; + const char *name = NULL; + as_t as; + enum bgp_instance_type inst_type; + bool is_view_inst = false; + int ret; + int is_new_bgp = 0; + + inst_type = BGP_INSTANCE_TYPE_DEFAULT; + 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. */ + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf = nb_running_get_entry(vrf_dnode, NULL, true); + + if (strmatch(vrf->name, VRF_DEFAULT_NAME)) { + name = NULL; + } else { + name = vrf->name; + inst_type = BGP_INSTANCE_TYPE_VRF; + } + + as = yang_dnode_get_uint32(args->dnode, "./local-as"); + + is_view_inst = yang_dnode_get_bool(args->dnode, + "./instance-type-view"); + if (is_view_inst) + inst_type = BGP_INSTANCE_TYPE_VIEW; + + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) + is_new_bgp = (bgp_lookup(as, name) == NULL); + + ret = bgp_get_vty(&bgp, &as, name, inst_type); + if (ret == BGP_ERR_INSTANCE_MISMATCH) { + snprintf( + args->errmsg, args->errmsg_len, + "BGP instance name and AS number mismatch\nBGP instance is already running; AS is %u", + as); + + return NB_ERR_INCONSISTENCY; + } + /* + * If we just instantiated the default instance, complete + * any pending VRF-VPN leaking that was configured via + * earlier "router bgp X vrf FOO" blocks. + */ + if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) + vpn_leak_postchange_all(); + + if (inst_type == BGP_INSTANCE_TYPE_VRF) + bgp_vpn_leak_export(bgp); + + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + + nb_running_set_entry(args->dnode, bgp); + break; } @@ -48,12 +124,44 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_create( int routing_control_plane_protocols_control_plane_protocol_bgp_global_destroy( struct nb_cb_destroy_args *args) { + struct bgp *bgp; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + + if (bgp->l3vni) { + snprintf(args->errmsg, args->errmsg_len, + "Please unconfigure l3vni %u", bgp->l3vni); + return NB_ERR_VALIDATION; + } + + /* Cannot delete default instance if vrf instances exist */ + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) { + struct listnode *node; + struct bgp *tmp_bgp; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) { + if (tmp_bgp->inst_type + == BGP_INSTANCE_TYPE_VRF) { + snprintf( + args->errmsg, args->errmsg_len, + "Cannot delete default BGP instance. Dependent VRF instances exist\n"); + return NB_ERR_VALIDATION; + } + } + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_unset_entry(args->dnode); + + bgp_vpn_leak_unimport(bgp); + bgp_delete(bgp); + break; } @@ -67,12 +175,38 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_destroy( int routing_control_plane_protocols_control_plane_protocol_bgp_global_local_as_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + as_t as; + switch (args->event) { case NB_EV_VALIDATE: + as = yang_dnode_get_uint32(args->dnode, NULL); + + bgp = nb_running_get_entry_non_rec(args->dnode, NULL, false); + if (bgp && bgp->as != as) { + snprintf(args->errmsg, args->errmsg_len, + "BGP instance is already running; AS is %u", + bgp->as); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + /* NOTE: handled in bgp_global_create callback, the as change + * will be rejected in validate phase. + */ + as = yang_dnode_get_uint32(args->dnode, NULL); + bgp = nb_running_get_entry(args->dnode, NULL, true); + if (bgp->as != as) { + snprintf(args->errmsg, args->errmsg_len, + "BGP instance is already running; AS is %u", + bgp->as); + return NB_ERR_INCONSISTENCY; + } + break; } @@ -86,14 +220,15 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_local_as_m int routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr router_id; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4(&router_id, args->dnode, NULL); + bgp_router_id_static_set(bgp, router_id); return NB_OK; } @@ -101,14 +236,16 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_ int routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr router_id; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + router_id.s_addr = 0; + bgp_router_id_static_set(bgp, router_id); return NB_OK; } @@ -120,29 +257,48 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_router_id_ int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_identifier_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + as_t as; + switch (args->event) { case NB_EV_VALIDATE: + as = yang_dnode_get_uint32(args->dnode, NULL); + if (!as) { + snprintf(args->errmsg, args->errmsg_len, "Invalid AS."); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + as = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_confederation_id_set(bgp, as); + break; } + as = yang_dnode_get_uint32(args->dnode, NULL); + + return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_identifier_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_confederation_id_unset(bgp); return NB_OK; } @@ -154,12 +310,39 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederat int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_member_as_create( struct nb_cb_create_args *args) { + as_t my_as, as; + struct bgp *bgp; + int ret; + switch (args->event) { case NB_EV_VALIDATE: + my_as = yang_dnode_get_uint32(args->dnode, + "../../../global/local-as"); + as = yang_dnode_get_uint32(args->dnode, NULL); + if (my_as == as) { + snprintf( + args->errmsg, args->errmsg_len, + "Local member-AS %u not allowed in confed peer list", + my_as); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + as = yang_dnode_get_uint32(args->dnode, NULL); + + ret = bgp_confederation_peers_add(bgp, as); + if (ret == BGP_ERR_INVALID_AS) { + snprintf( + args->errmsg, args->errmsg_len, + "Local member-AS not alloed in confed peer list"); + return NB_ERR_INCONSISTENCY; + } + break; } @@ -169,33 +352,49 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederat int routing_control_plane_protocols_control_plane_protocol_bgp_global_confederation_member_as_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + as_t as; + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + as = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_confederation_peers_remove(bgp, as); return NB_OK; } /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config + */ +void routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_maxmed_update(bgp); +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin */ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_enable_med_admin_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->v_maxmed_admin = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -207,12 +406,35 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_max_med_admin_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + uint32_t med_admin_val; + switch (args->event) { case NB_EV_VALIDATE: + med_admin_val = yang_dnode_get_uint32(args->dnode, NULL); + + /* enable_med_admin is required to be enabled for max-med-admin + * non default value. + */ + if (med_admin_val != BGP_MAXMED_VALUE_DEFAULT + && !yang_dnode_get_bool(args->dnode, + "../enable-med-admin")) { + snprintf(args->errmsg, args->errmsg_len, + "enable med admin is not set"); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + med_admin_val = yang_dnode_get_uint32(args->dnode, NULL); + + bgp->maxmed_admin_value = med_admin_val; + break; } @@ -226,12 +448,19 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_max_med_onstart_up_time_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + 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. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->v_maxmed_onstartup = + yang_dnode_get_uint32(args->dnode, NULL); + break; } @@ -241,12 +470,28 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_max_med_onstart_up_time_destroy( struct nb_cb_destroy_args *args) { + struct bgp *bgp; + 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. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + /* Cancel max-med onstartup if its on */ + if (bgp->t_maxmed_onstartup) { + THREAD_TIMER_OFF(bgp->t_maxmed_onstartup); + bgp->maxmed_onstartup_over = 1; + } + + bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED; + /* Resetting onstartup value as part of dependent node is + * detroyed. + */ + bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; + break; } @@ -260,12 +505,31 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config_max_med_onstart_up_value_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + uint32_t onstartup_val; + switch (args->event) { case NB_EV_VALIDATE: + onstartup_val = yang_dnode_get_uint32(args->dnode, NULL); + + if (!yang_dnode_exists(args->dnode, + "../max-med-onstart-up-time") + && onstartup_val != BGP_MAXMED_VALUE_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "max-med-onstart-up-time is not set."); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->maxmed_onstartup_value = + yang_dnode_get_uint32(args->dnode, NULL); + break; } @@ -279,14 +543,25 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_med_config int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_reflector_route_reflector_cluster_id_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr cluster_id; + const struct lyd_node_leaf_list *dleaf; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + dleaf = (const struct lyd_node_leaf_list *)args->dnode; + if (dleaf->value_type == LY_TYPE_STRING) + yang_dnode_get_ipv4(&cluster_id, args->dnode, NULL); + else + (void)inet_aton(dleaf->value_str, &cluster_id); + + bgp_cluster_id_set(bgp, &cluster_id); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } @@ -294,14 +569,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_refl int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_reflector_route_reflector_cluster_id_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_cluster_id_unset(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } @@ -313,14 +591,20 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_refl int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_reflector_no_client_reflect_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } @@ -332,33 +616,59 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_refl int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_reflector_allow_outbound_policy_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + + update_group_announce_rrclients(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options + */ +void routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_recalculate_all_bestpaths(bgp); +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med */ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_always_compare_med_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); + return NB_OK; } @@ -370,12 +680,58 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_deterministic_med_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + int bestpath_per_as_used; + afi_t afi; + safi_t safi; + struct peer *peer; + struct listnode *node; + switch (args->event) { case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + + if (!bgp) + return NB_OK; + + /* for deconfiguring deterministic-med case */ + if (!yang_dnode_get_bool(args->dnode, NULL) + && CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { + bestpath_per_as_used = 0; + + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + FOREACH_AFI_SAFI (afi, safi) + if (bgp_addpath_dmed_required( + peer->addpath_type[afi] + [safi])) { + bestpath_per_as_used = 1; + break; + } + + if (bestpath_per_as_used) + break; + } + + if (bestpath_per_as_used) { + snprintf( + args->errmsg, args->errmsg_len, + "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use"); + return NB_ERR_VALIDATION; + } + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); + break; } @@ -389,14 +745,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_confed_med_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); return NB_OK; } @@ -408,14 +767,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_missing_as_worst_med_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); return NB_OK; } @@ -446,14 +808,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_ignore_as_path_length_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); return NB_OK; } @@ -465,14 +830,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_external_compare_router_id_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); return NB_OK; } @@ -484,12 +852,29 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_allow_multiple_as_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + 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. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) { + SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); + if (yang_dnode_get_bool(args->dnode, + "../multi-path-as-set")) { + SET_FLAG(bgp->flags, + BGP_FLAG_MULTIPATH_RELAX_AS_SET); + } + } else { + UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); + /* unset as-set */ + UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + } + break; } @@ -503,12 +888,24 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_multi_path_as_set_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + 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. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (!CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { + SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + + } else + zlog_debug( + "%s multi-path-as-set as part of allow-multiple-as modify cb.", + __func__); + break; } @@ -518,12 +915,24 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_selection_options_multi_path_as_set_destroy( struct nb_cb_destroy_args *args) { + struct bgp *bgp; + 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. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + /* Only unset if it set, it is possible allow_multiple_as_modify + * unset this. + */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { + UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + + bgp_recalculate_all_bestpaths(bgp); + } + break; } @@ -537,14 +946,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_route_sele int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_dynamic_neighbors_limit_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t listen_limit; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + listen_limit = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_listen_limit_set(bgp, listen_limit); return NB_OK; } @@ -552,14 +964,14 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_nei int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_dynamic_neighbors_limit_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_listen_limit_unset(bgp); return NB_OK; } @@ -571,14 +983,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_nei int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_log_neighbor_changes_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); return NB_OK; } @@ -590,14 +1005,21 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_nei int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t quanta; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + quanta = yang_dnode_get_uint32(args->dnode, NULL); + + if (atomic_load_explicit(&bgp->wpkt_quanta, memory_order_relaxed) + == BGP_WRITE_PACKET_MAX) + bgp_wpkt_quanta_config_vty(bgp, quanta, true); + else + bgp_wpkt_quanta_config_vty(bgp, quanta, false); return NB_OK; } @@ -609,14 +1031,21 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_nei int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t quanta; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + quanta = yang_dnode_get_uint32(args->dnode, NULL); + + if (atomic_load_explicit(&bgp->rpkt_quanta, memory_order_relaxed) + == BGP_READ_PACKET_MAX) + bgp_rpkt_quanta_config_vty(bgp, quanta, true); + else + bgp_rpkt_quanta_config_vty(bgp, quanta, false); return NB_OK; } @@ -791,14 +1220,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_graceful_r int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_update_group_config_subgroup_pkt_queue_size_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t max_size; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + max_size = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_default_subgroup_pkt_queue_max_set(bgp, max_size); return NB_OK; } @@ -810,13 +1242,22 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_upd int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_update_group_config_coalesce_time_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; + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t coalesce_time; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + coalesce_time = yang_dnode_get_uint32(args->dnode, NULL); + + if (coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME) { + bgp->heuristic_coalesce = false; + bgp->coalesce_time = coalesce_time; + } else { + bgp->heuristic_coalesce = true; + bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; } return NB_OK; @@ -935,12 +1376,35 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_con int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_config_timers_hold_time_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + unsigned long keepalive = 0; + unsigned long holdtime = 0; + switch (args->event) { case NB_EV_VALIDATE: + keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive"); + holdtime = yang_dnode_get_uint16(args->dnode, NULL); + /* Holdtime value check. */ + if (holdtime < 3 && holdtime != 0) { + snprintf( + args->errmsg, args->errmsg_len, + "hold time value must be either 0 or greater than 3"); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive"); + holdtime = yang_dnode_get_uint16(args->dnode, NULL); + + bgp_timers_set(bgp, keepalive, holdtime, + DFLT_BGP_CONNECT_RETRY); + break; } @@ -954,12 +1418,35 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_con int routing_control_plane_protocols_control_plane_protocol_bgp_global_global_config_timers_keepalive_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + unsigned long keepalive = 0; + unsigned long holdtime = 0; + switch (args->event) { case NB_EV_VALIDATE: + keepalive = yang_dnode_get_uint16(args->dnode, NULL); + holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time"); + /* Holdtime value check. */ + if (holdtime < 3 && holdtime != 0) { + snprintf( + args->errmsg, args->errmsg_len, + "hold time value must be either 0 or greater than 3"); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + keepalive = yang_dnode_get_uint16(args->dnode, NULL); + holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time"); + + bgp_timers_set(bgp, keepalive, holdtime, + DFLT_BGP_CONNECT_RETRY); + break; } @@ -992,14 +1479,20 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_instance_t int routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_multihop_connected_route_check_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } @@ -1011,14 +1504,15 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_multi int routing_control_plane_protocols_control_plane_protocol_bgp_global_fast_external_failover_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + if (!yang_dnode_get_bool(args->dnode, NULL)) { + SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); + } else + UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); return NB_OK; } @@ -1030,14 +1524,18 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_fast_exter int routing_control_plane_protocols_control_plane_protocol_bgp_global_local_pref_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + struct bgp *bgp; + uint32_t local_pref; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + local_pref = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_default_local_preference_set(bgp, local_pref); + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; return NB_OK; } @@ -1049,14 +1547,13 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_local_pref int routing_control_plane_protocols_control_plane_protocol_bgp_global_default_shutdown_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + bgp->autoshutdown = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -1068,14 +1565,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_default_sh int routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_requires_policy_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); return NB_OK; } @@ -1087,14 +1587,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_ebgp_requi int routing_control_plane_protocols_control_plane_protocol_bgp_global_show_hostname_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); return NB_OK; } @@ -1106,14 +1609,17 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_show_hostn int routing_control_plane_protocols_control_plane_protocol_bgp_global_show_nexthop_hostname_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); return NB_OK; } @@ -1125,14 +1631,19 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_show_nexth int routing_control_plane_protocols_control_plane_protocol_bgp_global_import_check_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; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); + + bgp_static_redo_import_check(bgp); return NB_OK; } @@ -1144,12 +1655,40 @@ int routing_control_plane_protocols_control_plane_protocol_bgp_global_import_che int routing_control_plane_protocols_control_plane_protocol_bgp_global_graceful_shutdown_enable_modify( struct nb_cb_modify_args *args) { + struct bgp *bgp; + switch (args->event) { case NB_EV_VALIDATE: + if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { + snprintf( + args->errmsg, args->errmsg_len, + "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown"); + return NB_ERR_VALIDATION; + } + + break; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* TODO: implement me. */ + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); + + bgp_static_redo_import_check(bgp); + bgp_redistribute_redo(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, + args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, + args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + break; } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 795a4adfc..8264519a8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -73,6 +73,11 @@ #include "bgpd/rfapi/bgp_rfapi_cfg.h" #endif +#include "northbound.h" +#include "northbound_cli.h" +#include "bgpd/bgp_nb.h" + + FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK, { .val_bool = false, @@ -751,18 +756,19 @@ enum clear_sort { clear_as }; -static void bgp_clear_vty_error(struct vty *vty, struct peer *peer, afi_t afi, - safi_t safi, int error) +static void bgp_clear_vty_error(struct peer *peer, afi_t afi, safi_t safi, + int error, char *errmsg, size_t errmsg_len) { switch (error) { case BGP_ERR_AF_UNCONFIGURED: - vty_out(vty, - "%%BGP: Enable %s address family for the neighbor %s\n", - get_afi_safi_str(afi, safi, false), peer->host); + snprintf(errmsg, errmsg_len, + "%%BGP: Enable %s address family for the neighbor %s", + get_afi_safi_str(afi, safi, false), peer->host); break; case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED: - vty_out(vty, - "%%BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig\n", + snprintf( + errmsg, errmsg_len, + "%%BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig", peer->host); break; default: @@ -820,9 +826,9 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi, } /* `clear ip bgp' functions. */ -static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, +static int bgp_clear(struct bgp *bgp, afi_t afi, safi_t safi, enum clear_sort sort, enum bgp_clear_type stype, - const char *arg) + const char *arg, char *errmsg, size_t errmsg_len) { int ret = 0; bool found = false; @@ -848,7 +854,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); } if (gr_router_detected @@ -877,8 +884,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (!peer) { peer = peer_lookup_by_hostname(bgp, arg); if (!peer) { - vty_out(vty, - "Malformed address or name: %s\n", + snprintf( + errmsg, errmsg_len, + "Malformed address or name: %s", arg); return CMD_WARNING; } @@ -886,9 +894,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } else { peer = peer_lookup(bgp, &su); if (!peer) { - vty_out(vty, - "%%BGP: Unknown neighbor - \"%s\"\n", - arg); + snprintf(errmsg, errmsg_len, + "%%BGP: Unknown neighbor - \"%s\"", + arg); return CMD_WARNING; } } @@ -903,7 +911,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = BGP_ERR_AF_UNCONFIGURED; if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, errmsg, + errmsg_len); return CMD_SUCCESS; } @@ -914,7 +923,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, group = peer_group_lookup(bgp, arg); if (!group) { - vty_out(vty, "%%BGP: No such peer-group %s\n", arg); + snprintf(errmsg, errmsg_len, + "%%BGP: No such peer-group %s", arg); return CMD_WARNING; } @@ -922,14 +932,16 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } if (!found) - vty_out(vty, - "%%BGP: No %s peer belonging to peer-group %s is configured\n", + snprintf( + errmsg, errmsg_len, + "%%BGP: No %s peer belonging to peer-group %s is configured", get_afi_safi_str(afi, safi, false), arg); return CMD_SUCCESS; @@ -949,7 +961,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } @@ -963,9 +976,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } if (!found) - vty_out(vty, - "%%BGP: No external %s peer is configured\n", - get_afi_safi_str(afi, safi, false)); + snprintf(errmsg, errmsg_len, + "%%BGP: No external %s peer is configured", + get_afi_safi_str(afi, safi, false)); return CMD_SUCCESS; } @@ -986,7 +999,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } @@ -1000,9 +1014,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } if (!found) - vty_out(vty, - "%%BGP: No %s peer is configured with AS %s\n", - get_afi_safi_str(afi, safi, false), arg); + snprintf(errmsg, errmsg_len, + "%%BGP: No %s peer is configured with AS %s", + get_afi_safi_str(afi, safi, false), arg); return CMD_SUCCESS; } @@ -1010,9 +1024,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, return CMD_SUCCESS; } -static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, enum clear_sort sort, - enum bgp_clear_type stype, const char *arg) +static int bgp_clear_vty(const char *name, afi_t afi, safi_t safi, + enum clear_sort sort, enum bgp_clear_type stype, + const char *arg, char *errmsg, size_t errmsg_len) { struct bgp *bgp; @@ -1020,40 +1034,56 @@ static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi, if (name) { bgp = bgp_lookup_by_name(name); if (bgp == NULL) { - vty_out(vty, "Can't find BGP instance %s\n", name); + snprintf(errmsg, errmsg_len, + "Can't find BGP instance %s", name); return CMD_WARNING; } } else { bgp = bgp_get_default(); if (bgp == NULL) { - vty_out(vty, "No BGP process is configured\n"); + snprintf(errmsg, errmsg_len, + "No BGP process is configured"); return CMD_WARNING; } } - return bgp_clear(vty, bgp, afi, safi, sort, stype, arg); + return bgp_clear(bgp, afi, safi, sort, stype, arg, errmsg, errmsg_len); } /* clear soft inbound */ -static void bgp_clear_star_soft_in(struct vty *vty, const char *name) +int bgp_clear_star_soft_in(const char *name, char *errmsg, size_t errmsg_len) { afi_t afi; safi_t safi; + int ret; - FOREACH_AFI_SAFI (afi, safi) - bgp_clear_vty(vty, name, afi, safi, clear_all, - BGP_CLEAR_SOFT_IN, NULL); + FOREACH_AFI_SAFI (afi, safi) { + ret = bgp_clear_vty(name, afi, safi, clear_all, + BGP_CLEAR_SOFT_IN, NULL, errmsg, + errmsg_len); + if (ret != CMD_SUCCESS) + return -1; + } + + return 0; } /* clear soft outbound */ -static void bgp_clear_star_soft_out(struct vty *vty, const char *name) +int bgp_clear_star_soft_out(const char *name, char *errmsg, size_t errmsg_len) { afi_t afi; safi_t safi; + int ret; - FOREACH_AFI_SAFI (afi, safi) - bgp_clear_vty(vty, name, afi, safi, clear_all, - BGP_CLEAR_SOFT_OUT, NULL); + FOREACH_AFI_SAFI (afi, safi) { + ret = bgp_clear_vty(name, afi, safi, clear_all, + BGP_CLEAR_SOFT_OUT, NULL, errmsg, + errmsg_len); + if (ret != CMD_SUCCESS) + return -1; + } + + return 0; } @@ -1162,23 +1192,21 @@ DEFUN (no_auto_summary, } /* "router bgp" commands. */ -DEFUN_NOSH (router_bgp, - router_bgp_cmd, - "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", - ROUTER_STR - BGP_STR - AS_STR - BGP_INSTANCE_HELP_STR) +DEFUN_YANG_NOSH(router_bgp, + router_bgp_cmd, + "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", + ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR) { int idx_asn = 2; int idx_view_vrf = 3; int idx_vrf = 4; - int is_new_bgp = 0; - int ret; + int ret = CMD_SUCCESS; as_t as; struct bgp *bgp; const char *name = NULL; + char as_str[12] = {'\0'}; enum bgp_instance_type inst_type; + char base_xpath[XPATH_MAXLEN]; // "router bgp" without an ASN if (argc == 2) { @@ -1194,12 +1222,38 @@ DEFUN_NOSH (router_bgp, vty_out(vty, "%% Please specify ASN and VRF\n"); return CMD_WARNING_CONFIG_FAILED; } + /* unset the auto created flag as the user config is now present + */ + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", name ? name : VRF_DEFAULT_NAME); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + snprintf(as_str, 12, "%d", bgp->as); + nb_cli_enqueue_change(vty, "./local-as", NB_OP_MODIFY, as_str); + if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) { + nb_cli_enqueue_change(vty, "./instance-type-view", + NB_OP_MODIFY, "true"); + } + + ret = nb_cli_apply_changes(vty, base_xpath); + if (ret == CMD_SUCCESS) { + VTY_PUSH_XPATH(BGP_NODE, base_xpath); + + /* + * For backward compatibility with old commands we still + * need to use the qobj infrastructure. + */ + VTY_PUSH_CONTEXT(BGP_NODE, bgp); + } + return ret; } // "router bgp X" else { - as = strtoul(argv[idx_asn]->arg, NULL, 10); + as = strtoul(argv[idx_asn]->arg, NULL, 10); inst_type = BGP_INSTANCE_TYPE_DEFAULT; if (argc > 3) { name = argv[idx_vrf]->arg; @@ -1209,63 +1263,51 @@ DEFUN_NOSH (router_bgp, name = NULL; else inst_type = BGP_INSTANCE_TYPE_VRF; - } else if (!strcmp(argv[idx_view_vrf]->text, "view")) + } else if (!strcmp(argv[idx_view_vrf]->text, "view")) { inst_type = BGP_INSTANCE_TYPE_VIEW; + } } - - if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) - is_new_bgp = (bgp_lookup(as, name) == NULL); - - ret = bgp_get_vty(&bgp, &as, name, inst_type); - switch (ret) { - case BGP_ERR_AS_MISMATCH: - vty_out(vty, "BGP is already running; AS is %u\n", as); - return CMD_WARNING_CONFIG_FAILED; - case BGP_ERR_INSTANCE_MISMATCH: - vty_out(vty, - "BGP instance name and AS number mismatch\n"); - vty_out(vty, - "BGP instance is already running; AS is %u\n", - as); - return CMD_WARNING_CONFIG_FAILED; + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", name ? name : VRF_DEFAULT_NAME); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./local-as", NB_OP_MODIFY, + argv[idx_asn]->arg); + if (inst_type == BGP_INSTANCE_TYPE_VIEW) { + nb_cli_enqueue_change(vty, "./instance-type-view", + NB_OP_MODIFY, "true"); } - /* - * If we just instantiated the default instance, complete - * any pending VRF-VPN leaking that was configured via - * earlier "router bgp X vrf FOO" blocks. - */ - if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) - vpn_leak_postchange_all(); + nb_cli_pending_commit_check(vty); + ret = nb_cli_apply_changes(vty, base_xpath); + if (ret == CMD_SUCCESS) { + VTY_PUSH_XPATH(BGP_NODE, base_xpath); - if (inst_type == BGP_INSTANCE_TYPE_VRF) - bgp_vpn_leak_export(bgp); - /* Pending: handle when user tries to change a view to vrf n vv. - */ + /* + * For backward compatibility with old commands we still + * need to use the qobj infrastructure. + */ + bgp = bgp_lookup(as, name); + if (bgp) + VTY_PUSH_CONTEXT(BGP_NODE, bgp); + } } - /* unset the auto created flag as the user config is now present */ - UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); - VTY_PUSH_CONTEXT(BGP_NODE, bgp); - - return CMD_SUCCESS; + return ret; } /* "no router bgp" commands. */ -DEFUN (no_router_bgp, - no_router_bgp_cmd, - "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", - NO_STR - ROUTER_STR - BGP_STR - AS_STR - BGP_INSTANCE_HELP_STR) +DEFUN_YANG(no_router_bgp, + no_router_bgp_cmd, + "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", + NO_STR ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR) { int idx_asn = 3; int idx_vrf = 5; - as_t as; + as_t as = 0; struct bgp *bgp; const char *name = NULL; + char base_xpath[XPATH_MAXLEN]; // "no router bgp" without an ASN if (argc == 3) { @@ -1321,94 +1363,93 @@ DEFUN (no_router_bgp, } } } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", + bgp->name ? bgp->name : VRF_DEFAULT_NAME); - if (bgp_vpn_leak_unimport(bgp, vty)) - return CMD_WARNING_CONFIG_FAILED; - - bgp_delete(bgp); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, base_xpath); } +void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const struct lyd_node *vrf_dnode; + const char *vrf_name; + as_t as; -/* BGP router-id. */ + vrf_dnode = yang_dnode_get_parent(dnode, "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + as = yang_dnode_get_uint32(dnode, "./local-as"); -DEFPY (bgp_router_id, - bgp_router_id_cmd, - "bgp router-id A.B.C.D", - BGP_STR - "Override configured router identifier\n" - "Manually configured router identifier\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_router_id_static_set(bgp, router_id); - return CMD_SUCCESS; + vty_out(vty, "!\n"); + vty_out(vty, "router bgp %u", as); + if (!strmatch(vrf_name, VRF_DEFAULT_NAME)) + vty_out(vty, " vrf %s", vrf_name); + vty_out(vty, "\n"); } -DEFPY (no_bgp_router_id, - no_bgp_router_id_cmd, - "no bgp router-id [A.B.C.D]", - NO_STR - BGP_STR - "Override configured router identifier\n" - "Manually configured router identifier\n") +/* BGP router-id. */ + +DEFPY_YANG(bgp_router_id, bgp_router_id_cmd, "bgp router-id A.B.C.D", + BGP_STR + "Override configured router identifier\n" + "Manually configured router identifier\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, "./router-id", NB_OP_MODIFY, router_id_str); - if (router_id_str) { - if (!IPV4_ADDR_SAME(&bgp->router_id_static, &router_id)) { - vty_out(vty, "%% BGP router-id doesn't match\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } + return nb_cli_apply_changes(vty, NULL); +} - router_id.s_addr = 0; - bgp_router_id_static_set(bgp, router_id); +DEFPY_YANG(no_bgp_router_id, no_bgp_router_id_cmd, "no bgp router-id [A.B.C.D]", + NO_STR BGP_STR + "Override configured router identifier\n" + "Manually configured router identifier\n") +{ + nb_cli_enqueue_change(vty, "./router-id", NB_OP_DESTROY, + router_id_str ? router_id_str : NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp router-id %s\n", yang_dnode_get_string(dnode, NULL)); +} /* BGP Cluster ID. */ -DEFUN (bgp_cluster_id, - bgp_cluster_id_cmd, - "bgp cluster-id <A.B.C.D|(1-4294967295)>", - BGP_STR - "Configure Route-Reflector Cluster-id\n" - "Route-Reflector Cluster-id in IP address format\n" - "Route-Reflector Cluster-id as 32 bit quantity\n") +DEFUN_YANG(bgp_cluster_id, + bgp_cluster_id_cmd, + "bgp cluster-id <A.B.C.D|(1-4294967295)>", + BGP_STR + "Configure Route-Reflector Cluster-id\n" + "Route-Reflector Cluster-id in IP address format\n" + "Route-Reflector Cluster-id as 32 bit quantity\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_ipv4 = 2; - int ret; - struct in_addr cluster; - ret = inet_aton(argv[idx_ipv4]->arg, &cluster); - if (!ret) { - vty_out(vty, "%% Malformed bgp cluster identifier\n"); - return CMD_WARNING_CONFIG_FAILED; - } + nb_cli_enqueue_change(vty, + "./route-reflector/route-reflector-cluster-id", + NB_OP_MODIFY, argv[idx_ipv4]->arg); - bgp_cluster_id_set(bgp, &cluster); - bgp_clear_star_soft_out(vty, bgp->name); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_cluster_id, - no_bgp_cluster_id_cmd, - "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]", - NO_STR - BGP_STR - "Configure Route-Reflector Cluster-id\n" - "Route-Reflector Cluster-id in IP address format\n" - "Route-Reflector Cluster-id as 32 bit quantity\n") +DEFUN_YANG(no_bgp_cluster_id, + no_bgp_cluster_id_cmd, + "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]", + NO_STR BGP_STR + "Configure Route-Reflector Cluster-id\n" + "Route-Reflector Cluster-id in IP address format\n" + "Route-Reflector Cluster-id as 32 bit quantity\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_cluster_id_unset(bgp); - bgp_clear_star_soft_out(vty, bgp->name); + nb_cli_enqueue_change(vty, + "./route-reflector/route-reflector-cluster-id", + NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } DEFPY (bgp_norib, @@ -1446,87 +1487,86 @@ DEFPY (no_bgp_norib, return CMD_SUCCESS; } -DEFUN (bgp_confederation_identifier, - bgp_confederation_identifier_cmd, - "bgp confederation identifier (1-4294967295)", - "BGP specific commands\n" - "AS confederation parameters\n" - "AS number\n" - "Set routing domain confederation AS\n") +DEFUN_YANG(bgp_confederation_identifier, + bgp_confederation_identifier_cmd, + "bgp confederation identifier (1-4294967295)", + "BGP specific commands\n" + "AS confederation parameters\n" + "AS number\n" + "Set routing domain confederation AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - as_t as; - - as = strtoul(argv[idx_number]->arg, NULL, 10); - bgp_confederation_id_set(bgp, as); + nb_cli_enqueue_change(vty, "./confederation/identifier", NB_OP_MODIFY, + argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_confederation_identifier, - no_bgp_confederation_identifier_cmd, - "no bgp confederation identifier [(1-4294967295)]", - NO_STR - "BGP specific commands\n" - "AS confederation parameters\n" - "AS number\n" - "Set routing domain confederation AS\n") +DEFUN_YANG(no_bgp_confederation_identifier, + no_bgp_confederation_identifier_cmd, + "no bgp confederation identifier [(1-4294967295)]", + NO_STR + "BGP specific commands\n" + "AS confederation parameters\n" + "AS number\n" + "Set routing domain confederation AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_confederation_id_unset(bgp); + nb_cli_enqueue_change(vty, "./confederation/identifier", NB_OP_DESTROY, + NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (bgp_confederation_peers, - bgp_confederation_peers_cmd, - "bgp confederation peers (1-4294967295)...", - "BGP specific commands\n" - "AS confederation parameters\n" - "Peer ASs in BGP confederation\n" - AS_STR) +void cli_show_router_bgp_confederation_identifier(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp confederation identifier %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} + +DEFUN_YANG(bgp_confederation_peers, + bgp_confederation_peers_cmd, + "bgp confederation peers (1-4294967295)...", + "BGP specific commands\n" + "AS confederation parameters\n" + "Peer ASs in BGP confederation\n" AS_STR) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_asn = 3; - as_t as; int i; - for (i = idx_asn; i < argc; i++) { - as = strtoul(argv[i]->arg, NULL, 10); - - if (bgp->as == as) { - vty_out(vty, - "%% Local member-AS not allowed in confed peer list\n"); - continue; - } + for (i = idx_asn; i < argc; i++) + nb_cli_enqueue_change(vty, "./confederation/member-as", + NB_OP_CREATE, argv[i]->arg); - bgp_confederation_peers_add(bgp, as); - } - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_confederation_peers, - no_bgp_confederation_peers_cmd, - "no bgp confederation peers (1-4294967295)...", - NO_STR - "BGP specific commands\n" - "AS confederation parameters\n" - "Peer ASs in BGP confederation\n" - AS_STR) +DEFUN_YANG(no_bgp_confederation_peers, + no_bgp_confederation_peers_cmd, + "no bgp confederation peers (1-4294967295)...", + NO_STR + "BGP specific commands\n" + "AS confederation parameters\n" + "Peer ASs in BGP confederation\n" AS_STR) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_asn = 4; - as_t as; int i; - for (i = idx_asn; i < argc; i++) { - as = strtoul(argv[i]->arg, NULL, 10); + for (i = idx_asn; i < argc; i++) + nb_cli_enqueue_change(vty, "./confederation/member-as", + NB_OP_DESTROY, argv[i]->arg); - bgp_confederation_peers_remove(bgp, as); - } - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_confederation_member_as(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp confederation peers %u \n", + yang_dnode_get_uint32(dnode, NULL)); } /** @@ -1574,107 +1614,127 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, return CMD_SUCCESS; } -DEFUN (bgp_maxmed_admin, - bgp_maxmed_admin_cmd, - "bgp max-med administrative ", - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n") +void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + if (yang_dnode_get_bool(dnode, "./enable-med-admin")) { + uint32_t med_admin_val; - bgp->v_maxmed_admin = 1; - bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT; + vty_out(vty, " bgp max-med administrative"); + if ((med_admin_val = + yang_dnode_get_uint32(dnode, "./max-med-admin")) + != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", med_admin_val); + vty_out(vty, "\n"); + } - bgp_maxmed_update(bgp); + if (yang_dnode_exists(dnode, "./max-med-onstart-up-time")) { + uint32_t onstartup_val; - return CMD_SUCCESS; + vty_out(vty, " bgp max-med on-startup %u", + yang_dnode_get_uint32(dnode, + "./max-med-onstart-up-time")); + onstartup_val = yang_dnode_get_uint32( + dnode, "./max-med-onstart-up-value"); + if (onstartup_val != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", onstartup_val); + + vty_out(vty, "\n"); + } } -DEFUN (bgp_maxmed_admin_medv, - bgp_maxmed_admin_medv_cmd, - "bgp max-med administrative (0-4294967295)", - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n" - "Max MED value to be used\n") +DEFUN_YANG(bgp_maxmed_admin, + bgp_maxmed_admin_cmd, + "bgp max-med administrative ", + BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n") +{ + nb_cli_enqueue_change(vty, "./med-config/enable-med-admin", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(bgp_maxmed_admin_medv, + bgp_maxmed_admin_medv_cmd, + "bgp max-med administrative (0-4294967295)", + BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - bgp->v_maxmed_admin = 1; - bgp->maxmed_admin_value = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./med-config/enable-med-admin", + NB_OP_MODIFY, "true"); - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, "./med-config/max-med-admin", NB_OP_MODIFY, + argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_maxmed_admin, - no_bgp_maxmed_admin_cmd, - "no bgp max-med administrative [(0-4294967295)]", - NO_STR - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n" - "Max MED value to be used\n") +DEFUN_YANG(no_bgp_maxmed_admin, + no_bgp_maxmed_admin_cmd, + "no bgp max-med administrative [(0-4294967295)]", + NO_STR BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->v_maxmed_admin = BGP_MAXMED_ADMIN_UNCONFIGURED; - bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT; - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, "./med-config/enable-med-admin", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./med-config/max-med-admin", NB_OP_MODIFY, + NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (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") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx = 0; argv_find(argv, argc, "(5-86400)", &idx); - bgp->v_maxmed_onstartup = strtoul(argv[idx]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./med-config/max-med-onstart-up-time", + NB_OP_MODIFY, argv[idx]->arg); + if (argv_find(argv, argc, "(0-4294967295)", &idx)) - bgp->maxmed_onstartup_value = strtoul(argv[idx]->arg, NULL, 10); + nb_cli_enqueue_change(vty, + "./med-config/max-med-onstart-up-value", + NB_OP_MODIFY, argv[idx]->arg); else - bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; - - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, + "./med-config/max-med-onstart-up-value", + NB_OP_MODIFY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (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") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* Cancel max-med onstartup if its on */ - if (bgp->t_maxmed_onstartup) { - THREAD_TIMER_OFF(bgp->t_maxmed_onstartup); - bgp->maxmed_onstartup_over = 1; - } - - bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED; - bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; + nb_cli_enqueue_change(vty, "./med-config/max-med-onstart-up-time", + NB_OP_DESTROY, NULL); - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, "./med-config/max-med-onstart-up-value", + NB_OP_MODIFY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } static int bgp_global_update_delay_config_vty(struct vty *vty, @@ -1858,22 +1918,16 @@ DEFPY (no_bgp_update_delay, } -static int bgp_wpkt_quanta_config_vty(struct vty *vty, uint32_t quanta, - bool set) +int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - quanta = set ? quanta : BGP_WRITE_PACKET_MAX; atomic_store_explicit(&bgp->wpkt_quanta, quanta, memory_order_relaxed); return CMD_SUCCESS; } -static int bgp_rpkt_quanta_config_vty(struct vty *vty, uint32_t quanta, - bool set) +int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - quanta = set ? quanta : BGP_READ_PACKET_MAX; atomic_store_explicit(&bgp->rpkt_quanta, quanta, memory_order_relaxed); @@ -1904,24 +1958,46 @@ 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 (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") -{ - return bgp_wpkt_quanta_config_vty(vty, quanta, !no); -} +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( + vty, + "./global-neighbor-config/packet-quanta-config/wpkt-quanta", + NB_OP_MODIFY, quanta_str); + else + nb_cli_enqueue_change( + vty, + "./global-neighbor-config/packet-quanta-config/wpkt-quanta", + NB_OP_MODIFY, NULL); + + 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") +{ + if (!no) + nb_cli_enqueue_change( + vty, + "./global-neighbor-config/packet-quanta-config/rpkt-quanta", + NB_OP_MODIFY, quanta_str); + else + nb_cli_enqueue_change( + vty, + "./global-neighbor-config/packet-quanta-config/rpkt-quanta", + NB_OP_MODIFY, NULL); -DEFPY (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") -{ - return bgp_rpkt_quanta_config_vty(vty, quanta, !no); + return nb_cli_apply_changes(vty, NULL); } void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp) @@ -1930,34 +2006,39 @@ void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp) vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time); } - -DEFUN (bgp_coalesce_time, - bgp_coalesce_time_cmd, - "coalesce-time (0-4294967295)", - "Subgroup coalesce timer\n" - "Subgroup coalesce timer value (in ms)\n") +void cli_show_router_global_update_group_config_coalesce_time( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + vty_out(vty, " coalesce-time %u\n", yang_dnode_get_uint32(dnode, NULL)); +} + +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; + argv_find(argv, argc, "(0-4294967295)", &idx); - bgp->heuristic_coalesce = false; - bgp->coalesce_time = strtoul(argv[idx]->arg, NULL, 10); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global-update-group-config/coalesce-time", + NB_OP_MODIFY, argv[idx]->arg); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_coalesce_time, - no_bgp_coalesce_time_cmd, - "no coalesce-time (0-4294967295)", - NO_STR - "Subgroup coalesce timer\n" - "Subgroup coalesce timer value (in ms)\n") +DEFUN_YANG(no_bgp_coalesce_time, + no_bgp_coalesce_time_cmd, + "no coalesce-time (0-4294967295)", + NO_STR + "Subgroup coalesce timer\n" + "Subgroup coalesce timer value (in ms)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, "./global-update-group-config/coalesce-time", + NB_OP_MODIFY, NULL); - bgp->heuristic_coalesce = true; - bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* Maximum-paths configuration */ @@ -2073,129 +2154,181 @@ static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, /* BGP timers. */ -DEFUN (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") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 2; int idx_number_2 = 3; - unsigned long keepalive = 0; - unsigned long holdtime = 0; - keepalive = strtoul(argv[idx_number]->arg, NULL, 10); - holdtime = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./global-config-timers/keepalive", + NB_OP_MODIFY, argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./global-config-timers/hold-time", + NB_OP_MODIFY, argv[idx_number_2]->arg); - /* Holdtime value check. */ - if (holdtime < 3 && holdtime != 0) { - vty_out(vty, - "%% hold time value must be either 0 or greater than 3\n"); - return CMD_WARNING_CONFIG_FAILED; - } + return nb_cli_apply_changes(vty, NULL); +} - bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY); +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-config-timers/keepalive", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./global-config-timers/hold-time", + NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (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") +void cli_show_router_bgp_route_reflector(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, - DFLT_BGP_CONNECT_RETRY); + if (yang_dnode_get_bool(dnode, "./no-client-reflect")) + vty_out(vty, " no bgp client-to-client reflection\n"); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, "./allow-outbound-policy")) + vty_out(vty, " bgp route-reflector allow-outbound-policy\n"); + + if (yang_dnode_exists(dnode, "./route-reflector-cluster-id")) + vty_out(vty, " bgp cluster-id %s\n", + yang_dnode_get_string(dnode, + "./route-reflector-cluster-id")); } +DEFUN_YANG(bgp_client_to_client_reflection, + bgp_client_to_client_reflection_cmd, + "bgp client-to-client reflection", + "BGP specific commands\n" + "Configure client to client route reflection\n" + "reflection of routes allowed\n") +{ + nb_cli_enqueue_change(vty, "./route-reflector/no-client-reflect", + NB_OP_MODIFY, "false"); -DEFUN (bgp_client_to_client_reflection, - bgp_client_to_client_reflection_cmd, - "bgp client-to-client reflection", - "BGP specific commands\n" - "Configure client to client route reflection\n" - "reflection of routes allowed\n") + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(no_bgp_client_to_client_reflection, + no_bgp_client_to_client_reflection_cmd, + "no bgp client-to-client reflection", + NO_STR + "BGP specific commands\n" + "Configure client to client route reflection\n" + "reflection of routes allowed\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); - bgp_clear_star_soft_out(vty, bgp->name); + nb_cli_enqueue_change(vty, "./route-reflector/no-client-reflect", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_client_to_client_reflection, - no_bgp_client_to_client_reflection_cmd, - "no bgp client-to-client reflection", - NO_STR - "BGP specific commands\n" - "Configure client to client route reflection\n" - "reflection of routes allowed\n") +void cli_show_router_bgp_route_selection(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); - bgp_clear_star_soft_out(vty, bgp->name); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, "./always-compare-med")) + vty_out(vty, " bgp always-compare-med\n"); + + if (yang_dnode_get_bool(dnode, "./ignore-as-path-length")) + vty_out(vty, " bgp bestpath as-path ignore\n"); + + if (yang_dnode_get_bool(dnode, "./aspath-confed")) + vty_out(vty, " bgp bestpath as-path confed\n"); + + if (yang_dnode_get_bool(dnode, "./external-compare-router-id")) + vty_out(vty, " bgp bestpath compare-routerid\n"); + + if (yang_dnode_get_bool(dnode, "./allow-multiple-as")) { + if (yang_dnode_get_bool(dnode, "./multi-path-as-set")) + vty_out(vty, + " bgp bestpath as-path multipath-relax as-set\n"); + else + vty_out(vty, " bgp bestpath as-path multipath-relax\n"); + } + + if (yang_dnode_get_bool(dnode, "./deterministic-med")) + vty_out(vty, " bgp deterministic-med\n"); + + if (yang_dnode_get_bool(dnode, "./confed-med") + || yang_dnode_get_bool(dnode, "./missing-as-worst-med")) { + vty_out(vty, " bgp bestpath med"); + if (yang_dnode_get_bool(dnode, "./confed-med")) + vty_out(vty, " confed"); + if (yang_dnode_get_bool(dnode, "./missing-as-worst-med")) + vty_out(vty, " missing-as-worst"); + vty_out(vty, "\n"); + } } /* "bgp always-compare-med" configuration. */ -DEFUN (bgp_always_compare_med, - bgp_always_compare_med_cmd, - "bgp always-compare-med", - "BGP specific commands\n" - "Allow comparing MED from different neighbors\n") +DEFUN_YANG(bgp_always_compare_med, + bgp_always_compare_med_cmd, + "bgp always-compare-med", + "BGP specific commands\n" + "Allow comparing MED from different neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/always-compare-med", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_always_compare_med, - no_bgp_always_compare_med_cmd, - "no bgp always-compare-med", - NO_STR - "BGP specific commands\n" - "Allow comparing MED from different neighbors\n") +DEFUN_YANG(no_bgp_always_compare_med, + no_bgp_always_compare_med_cmd, + "no bgp always-compare-med", + NO_STR + "BGP specific commands\n" + "Allow comparing MED from different neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/always-compare-med", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +DEFUN_YANG(bgp_ebgp_requires_policy, + bgp_ebgp_requires_policy_cmd, + "bgp ebgp-requires-policy", + "BGP specific commands\n" + "Require in and out policy for eBGP peers (RFC8212)\n") +{ + nb_cli_enqueue_change(vty, "./ebgp-requires-policy", NB_OP_MODIFY, + "true"); + return nb_cli_apply_changes(vty, NULL); +} -DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd, - "bgp ebgp-requires-policy", - "BGP specific commands\n" - "Require in and out policy for eBGP peers (RFC8212)\n") +DEFUN_YANG(no_bgp_ebgp_requires_policy, + no_bgp_ebgp_requires_policy_cmd, + "no bgp ebgp-requires-policy", + NO_STR + "BGP specific commands\n" + "Require in and out policy for eBGP peers (RFC8212)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./ebgp-requires-policy", NB_OP_MODIFY, + "false"); + return nb_cli_apply_changes(vty, NULL); } -DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, - "no bgp ebgp-requires-policy", - NO_STR - "BGP specific commands\n" - "Require in and out policy for eBGP peers (RFC8212)\n") +void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_EBGP_REQUIRES_POLICY) + vty_out(vty, " bgp ebgp-requires-policy\n"); } DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, @@ -2250,62 +2383,31 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, } /* "bgp deterministic-med" configuration. */ -DEFUN (bgp_deterministic_med, +DEFUN_YANG (bgp_deterministic_med, bgp_deterministic_med_cmd, "bgp deterministic-med", "BGP specific commands\n" "Pick the best-MED path among paths advertised from the neighboring AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/deterministic-med", + NB_OP_MODIFY, "true"); - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { - SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); - bgp_recalculate_all_bestpaths(bgp); - } - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_deterministic_med, +DEFUN_YANG (no_bgp_deterministic_med, no_bgp_deterministic_med_cmd, "no bgp deterministic-med", NO_STR "BGP specific commands\n" "Pick the best-MED path among paths advertised from the neighboring AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int bestpath_per_as_used; - afi_t afi; - safi_t safi; - struct peer *peer; - struct listnode *node, *nnode; - - if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { - bestpath_per_as_used = 0; - - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - FOREACH_AFI_SAFI (afi, safi) - if (bgp_addpath_dmed_required( - peer->addpath_type[afi][safi])) { - bestpath_per_as_used = 1; - break; - } - - if (bestpath_per_as_used) - break; - } - - if (bestpath_per_as_used) { - vty_out(vty, - "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use\n"); - return CMD_WARNING_CONFIG_FAILED; - } else { - UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); - bgp_recalculate_all_bestpaths(bgp); - } - } + nb_cli_enqueue_change(vty, + "./route-selection-options/deterministic-med", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp graceful-restart mode" configuration. */ @@ -2840,13 +2942,18 @@ DEFUN (no_bgp_graceful_restart_rib_stale_time, return CMD_SUCCESS; } -static inline void bgp_initiate_graceful_shut_unshut(struct vty *vty, - struct bgp *bgp) +static inline int bgp_initiate_graceful_shut_unshut(struct bgp *bgp, + char *errmsg, + size_t errmsg_len) { bgp_static_redo_import_check(bgp); bgp_redistribute_redo(bgp); - bgp_clear_star_soft_out(vty, bgp->name); - bgp_clear_star_soft_in(vty, bgp->name); + if (bgp_clear_star_soft_out(bgp->name, errmsg, errmsg_len) < 0) + return -1; + if (bgp_clear_star_soft_in(bgp->name, errmsg, errmsg_len) < 0) + return -1; + + return 0; } static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) @@ -2854,6 +2961,7 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) struct listnode *node, *nnode; struct bgp *bgp; bool vrf_cfg = false; + char errmsg[BUFSIZ] = {'\0'}; if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) return CMD_SUCCESS; @@ -2879,8 +2987,13 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN); /* Initiate processing for all BGP instances. */ - for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) - bgp_initiate_graceful_shut_unshut(vty, bgp); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (bgp_initiate_graceful_shut_unshut(bgp, errmsg, + sizeof(errmsg)) + < 0) + if (strlen(errmsg)) + vty_out(vty, "%s\n", errmsg); + } return CMD_SUCCESS; } @@ -2889,6 +3002,7 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty) { struct listnode *node, *nnode; struct bgp *bgp; + char errmsg[BUFSIZ] = {'\0'}; if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) return CMD_SUCCESS; @@ -2897,8 +3011,13 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty) UNSET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN); /* Initiate processing for all BGP instances. */ - for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) - bgp_initiate_graceful_shut_unshut(vty, bgp); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (bgp_initiate_graceful_shut_unshut(bgp, errmsg, + sizeof(errmsg)) + < 0) + if (strlen(errmsg)) + vty_out(vty, "%s\n", errmsg); + } return CMD_SUCCESS; } @@ -2913,24 +3032,13 @@ DEFUN (bgp_graceful_shutdown, if (vty->node == CONFIG_NODE) return bgp_global_graceful_shutdown_config_vty(vty); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* if configured globally, per-instance config is not allowed */ - if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { - vty_out(vty, - "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); - bgp_initiate_graceful_shut_unshut(vty, bgp); - } + nb_cli_enqueue_change(vty, "./graceful-shutdown/enable", NB_OP_MODIFY, + "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_graceful_shutdown, +DEFUN_YANG (no_bgp_graceful_shutdown, no_bgp_graceful_shutdown_cmd, "no bgp graceful-shutdown", NO_STR @@ -2940,111 +3048,118 @@ DEFUN (no_bgp_graceful_shutdown, if (vty->node == CONFIG_NODE) return bgp_global_graceful_shutdown_deconfig_vty(vty); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* If configured globally, cannot remove from one bgp instance */ - if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { - vty_out(vty, - "%%Failed: bgp graceful-shutdown configured globally. Delete per-vrf not permitted\n"); - return CMD_WARNING_CONFIG_FAILED; - } + nb_cli_enqueue_change(vty, "./graceful-shutdown/enable", NB_OP_MODIFY, + "false"); - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); - bgp_initiate_graceful_shut_unshut(vty, bgp); - } + return nb_cli_apply_changes(vty, NULL); +} - return CMD_SUCCESS; +void cli_show_router_bgp_graceful_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp graceful-shutdown\n"); } /* "bgp fast-external-failover" configuration. */ -DEFUN (bgp_fast_external_failover, +DEFUN_YANG (bgp_fast_external_failover, bgp_fast_external_failover_cmd, "bgp fast-external-failover", BGP_STR "Immediately reset session if a link to a directly connected external peer goes down\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./fast-external-failover", NB_OP_MODIFY, + "false"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_fast_external_failover, +DEFUN_YANG (no_bgp_fast_external_failover, no_bgp_fast_external_failover_cmd, "no bgp fast-external-failover", NO_STR BGP_STR "Immediately reset session if a link to a directly connected external peer goes down\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./fast-external-failover", NB_OP_MODIFY, + "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_fast_external_failover(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no bgp fast-external-failover\n"); } /* "bgp bestpath compare-routerid" configuration. */ -DEFUN (bgp_bestpath_compare_router_id, - bgp_bestpath_compare_router_id_cmd, - "bgp bestpath compare-routerid", - "BGP specific commands\n" - "Change the default bestpath selection\n" - "Compare router-id for identical EBGP paths\n") +DEFUN_YANG(bgp_bestpath_compare_router_id, + bgp_bestpath_compare_router_id_cmd, + "bgp bestpath compare-routerid", + "BGP specific commands\n" + "Change the default bestpath selection\n" + "Compare router-id for identical EBGP paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./route-selection-options/external-compare-router-id", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_compare_router_id, - no_bgp_bestpath_compare_router_id_cmd, - "no bgp bestpath compare-routerid", - NO_STR - "BGP specific commands\n" - "Change the default bestpath selection\n" - "Compare router-id for identical EBGP paths\n") +DEFUN_YANG(no_bgp_bestpath_compare_router_id, + no_bgp_bestpath_compare_router_id_cmd, + "no bgp bestpath compare-routerid", + NO_STR + "BGP specific commands\n" + "Change the default bestpath selection\n" + "Compare router-id for identical EBGP paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./route-selection-options/external-compare-router-id", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path ignore" configuration. */ -DEFUN (bgp_bestpath_aspath_ignore, - bgp_bestpath_aspath_ignore_cmd, - "bgp bestpath as-path ignore", - "BGP specific commands\n" - "Change the default bestpath selection\n" - "AS-path attribute\n" - "Ignore as-path length in selecting a route\n") +DEFUN_YANG(bgp_bestpath_aspath_ignore, + bgp_bestpath_aspath_ignore_cmd, + "bgp bestpath as-path ignore", + "BGP specific commands\n" + "Change the default bestpath selection\n" + "AS-path attribute\n" + "Ignore as-path length in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/ignore-as-path-length", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_ignore, - no_bgp_bestpath_aspath_ignore_cmd, - "no bgp bestpath as-path ignore", - NO_STR - "BGP specific commands\n" - "Change the default bestpath selection\n" - "AS-path attribute\n" - "Ignore as-path length in selecting a route\n") +DEFUN_YANG(no_bgp_bestpath_aspath_ignore, + no_bgp_bestpath_aspath_ignore_cmd, + "no bgp bestpath as-path ignore", + NO_STR + "BGP specific commands\n" + "Change the default bestpath selection\n" + "AS-path attribute\n" + "Ignore as-path length in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/ignore-as-path-length", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path confed" configuration. */ -DEFUN (bgp_bestpath_aspath_confed, +DEFUN_YANG (bgp_bestpath_aspath_confed, bgp_bestpath_aspath_confed_cmd, "bgp bestpath as-path confed", "BGP specific commands\n" @@ -3052,14 +3167,13 @@ DEFUN (bgp_bestpath_aspath_confed, "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, "./route-selection-options/aspath-confed", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_confed, +DEFUN_YANG (no_bgp_bestpath_aspath_confed, no_bgp_bestpath_aspath_confed_cmd, "no bgp bestpath as-path confed", NO_STR @@ -3068,15 +3182,14 @@ DEFUN (no_bgp_bestpath_aspath_confed, "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, "./route-selection-options/aspath-confed", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path multipath-relax" configuration. */ -DEFUN (bgp_bestpath_aspath_multipath_relax, +DEFUN_YANG (bgp_bestpath_aspath_multipath_relax, bgp_bestpath_aspath_multipath_relax_cmd, "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", "BGP specific commands\n" @@ -3086,23 +3199,24 @@ DEFUN (bgp_bestpath_aspath_multipath_relax, "Generate an AS_SET\n" "Do not generate an AS_SET\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx = 0; - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); - /* no-as-set is now the default behavior so we can silently - * ignore it */ + nb_cli_enqueue_change(vty, + "./route-selection-options/allow-multiple-as", + NB_OP_MODIFY, "true"); if (argv_find(argv, argc, "as-set", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + nb_cli_enqueue_change( + vty, "./route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "true"); else - UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); - - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_multipath_relax, +DEFUN_YANG (no_bgp_bestpath_aspath_multipath_relax, no_bgp_bestpath_aspath_multipath_relax_cmd, "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", NO_STR @@ -3113,40 +3227,46 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax, "Generate an AS_SET\n" "Do not generate an AS_SET\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); - UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/allow-multiple-as", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change(vty, + "./route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp log-neighbor-changes" configuration. */ -DEFUN (bgp_log_neighbor_changes, - bgp_log_neighbor_changes_cmd, - "bgp log-neighbor-changes", - "BGP specific commands\n" - "Log neighbor up/down and reset reason\n") +DEFUN_YANG(bgp_log_neighbor_changes, + bgp_log_neighbor_changes_cmd, + "bgp log-neighbor-changes", + "BGP specific commands\n" + "Log neighbor up/down and reset reason\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, + "./global-neighbor-config/log-neighbor-changes", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_log_neighbor_changes, - no_bgp_log_neighbor_changes_cmd, - "no bgp log-neighbor-changes", - NO_STR - "BGP specific commands\n" - "Log neighbor up/down and reset reason\n") +DEFUN_YANG(no_bgp_log_neighbor_changes, + no_bgp_log_neighbor_changes_cmd, + "no bgp log-neighbor-changes", + NO_STR + "BGP specific commands\n" + "Log neighbor up/down and reset reason\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, + "./global-neighbor-config/log-neighbor-changes", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath med" configuration. */ -DEFUN (bgp_bestpath_med, +DEFUN_YANG (bgp_bestpath_med, bgp_bestpath_med_cmd, "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", "BGP specific commands\n" @@ -3157,21 +3277,29 @@ DEFUN (bgp_bestpath_med, "Treat missing MED as the least preferred one\n" "Compare MED among confederation paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx = 0; + bool confed = false; + bool worst_med = false; + + if (argv_find(argv, argc, "confed", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + confed = true; + + nb_cli_enqueue_change(vty, "./route-selection-options/confed-med", + NB_OP_MODIFY, confed ? "true" : "false"); + idx = 0; if (argv_find(argv, argc, "missing-as-worst", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + worst_med = true; - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./route-selection-options/missing-as-worst-med", + NB_OP_MODIFY, worst_med ? "true" : "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_med, +DEFUN_YANG (no_bgp_bestpath_med, no_bgp_bestpath_med_cmd, "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", NO_STR @@ -3183,18 +3311,20 @@ DEFUN (no_bgp_bestpath_med, "Treat missing MED as the least preferred one\n" "Compare MED among confederation paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx = 0; + if (argv_find(argv, argc, "confed", &idx)) - UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + nb_cli_enqueue_change(vty, + "./route-selection-options/confed-med", + NB_OP_MODIFY, "false"); + idx = 0; if (argv_find(argv, argc, "missing-as-worst", &idx)) - UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + nb_cli_enqueue_change( + vty, "./route-selection-options/missing-as-worst-med", + NB_OP_MODIFY, "false"); - bgp_recalculate_all_bestpaths(bgp); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath bandwidth" configuration. */ @@ -3288,29 +3418,36 @@ DEFUN (bgp_default_ipv4_unicast, } /* Display hostname in certain command outputs */ -DEFUN (bgp_default_show_hostname, +DEFUN_YANG (bgp_default_show_hostname, bgp_default_show_hostname_cmd, "bgp default show-hostname", "BGP specific commands\n" "Configure BGP defaults\n" "Show hostname in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./show-hostname", NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_show_hostname, - no_bgp_default_show_hostname_cmd, - "no bgp default show-hostname", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "Show hostname in certain command outputs\n") +DEFUN_YANG(no_bgp_default_show_hostname, + no_bgp_default_show_hostname_cmd, + "no bgp default show-hostname", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "Show hostname in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./show-hostname", NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME) + vty_out(vty, " bgp default show-hostname\n"); } /* Display hostname in certain command outputs */ @@ -3321,9 +3458,10 @@ DEFUN (bgp_default_show_nexthop_hostname, "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./show-nexthop-hostname", NB_OP_MODIFY, + "true"); + + return nb_cli_apply_changes(vty, NULL); } DEFUN (no_bgp_default_show_nexthop_hostname, @@ -3334,26 +3472,31 @@ DEFUN (no_bgp_default_show_nexthop_hostname, "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./show-nexthop-hostname", NB_OP_MODIFY, + "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME) + vty_out(vty, " bgp default show-nexthop-hostname\n"); } /* "bgp network import-check" configuration. */ -DEFUN (bgp_network_import_check, - bgp_network_import_check_cmd, - "bgp network import-check", - "BGP specific commands\n" - "BGP network command\n" - "Check BGP network route exists in IGP\n") +DEFUN_YANG(bgp_network_import_check, + bgp_network_import_check_cmd, + "bgp network import-check", + "BGP specific commands\n" + "BGP network command\n" + "Check BGP network route exists in IGP\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) { - SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); - bgp_static_redo_import_check(bgp); - } + nb_cli_enqueue_change(vty, "./import-check", NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, @@ -3363,162 +3506,190 @@ ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, "Check BGP network route exists in IGP\n" "Match route precisely\n") -DEFUN (no_bgp_network_import_check, - no_bgp_network_import_check_cmd, - "no bgp network import-check", - NO_STR - "BGP specific commands\n" - "BGP network command\n" - "Check BGP network route exists in IGP\n") +DEFUN_YANG(no_bgp_network_import_check, + no_bgp_network_import_check_cmd, + "no bgp network import-check", + NO_STR + "BGP specific commands\n" + "BGP network command\n" + "Check BGP network route exists in IGP\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); - bgp_static_redo_import_check(bgp); - } + nb_cli_enqueue_change(vty, "./import-check", NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (bgp_default_local_preference, - bgp_default_local_preference_cmd, - "bgp default local-preference (0-4294967295)", - "BGP specific commands\n" - "Configure BGP defaults\n" - "local preference (higher=more preferred)\n" - "Configure default local preference value\n") +void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_number = 3; - uint32_t local_pref; + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_IMPORT_CHECK) + vty_out(vty, " bgp network import-check\n"); +} - local_pref = strtoul(argv[idx_number]->arg, NULL, 10); +DEFUN_YANG(bgp_default_local_preference, + bgp_default_local_preference_cmd, + "bgp default local-preference (0-4294967295)", + "BGP specific commands\n" + "Configure BGP defaults\n" + "local preference (higher=more preferred)\n" + "Configure default local preference value\n") +{ + int idx_number = 3; - bgp_default_local_preference_set(bgp, local_pref); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./local-pref", NB_OP_MODIFY, + argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_local_preference, - no_bgp_default_local_preference_cmd, - "no bgp default local-preference [(0-4294967295)]", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "local preference (higher=more preferred)\n" - "Configure default local preference value\n") +DEFUN_YANG(no_bgp_default_local_preference, + no_bgp_default_local_preference_cmd, + "no bgp default local-preference [(0-4294967295)]", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "local preference (higher=more preferred)\n" + "Configure default local preference value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_default_local_preference_unset(bgp); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./local-pref", NB_OP_MODIFY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp default local-preference %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} -DEFUN (bgp_default_subgroup_pkt_queue_max, - bgp_default_subgroup_pkt_queue_max_cmd, - "bgp default subgroup-pkt-queue-max (20-100)", - "BGP specific commands\n" - "Configure BGP defaults\n" - "subgroup-pkt-queue-max\n" - "Configure subgroup packet queue max\n") + +DEFUN_YANG(bgp_default_subgroup_pkt_queue_max, + bgp_default_subgroup_pkt_queue_max_cmd, + "bgp default subgroup-pkt-queue-max (20-100)", + "BGP specific commands\n" + "Configure BGP defaults\n" + "subgroup-pkt-queue-max\n" + "Configure subgroup packet queue max\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - uint32_t max_size; - max_size = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change( + vty, "./global-update-group-config/subgroup-pkt-queue-size", + NB_OP_MODIFY, argv[idx_number]->arg); - bgp_default_subgroup_pkt_queue_max_set(bgp, max_size); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_subgroup_pkt_queue_max, - no_bgp_default_subgroup_pkt_queue_max_cmd, - "no bgp default subgroup-pkt-queue-max [(20-100)]", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "subgroup-pkt-queue-max\n" - "Configure subgroup packet queue max\n") +DEFUN_YANG(no_bgp_default_subgroup_pkt_queue_max, + no_bgp_default_subgroup_pkt_queue_max_cmd, + "no bgp default subgroup-pkt-queue-max [(20-100)]", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "subgroup-pkt-queue-max\n" + "Configure subgroup packet queue max\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_default_subgroup_pkt_queue_max_unset(bgp); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global-update-group-config/subgroup-pkt-queue-size", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_global_update_group_config_subgroup_pkt_queue_size( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} -DEFUN (bgp_rr_allow_outbound_policy, - bgp_rr_allow_outbound_policy_cmd, - "bgp route-reflector allow-outbound-policy", - "BGP specific commands\n" - "Allow modifications made by out route-map\n" - "on ibgp neighbors\n") +DEFUN_YANG(bgp_rr_allow_outbound_policy, + bgp_rr_allow_outbound_policy_cmd, + "bgp route-reflector allow-outbound-policy", + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, "./route-reflector/allow-outbound-policy", + NB_OP_MODIFY, "true"); - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { - SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); - update_group_announce_rrclients(bgp); - bgp_clear_star_soft_out(vty, bgp->name); - } + return nb_cli_apply_changes(vty, NULL); +} - return CMD_SUCCESS; +DEFUN_YANG(no_bgp_rr_allow_outbound_policy, + no_bgp_rr_allow_outbound_policy_cmd, + "no bgp route-reflector allow-outbound-policy", + NO_STR + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") +{ + nb_cli_enqueue_change(vty, "./route-reflector/allow-outbound-policy", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_rr_allow_outbound_policy, - no_bgp_rr_allow_outbound_policy_cmd, - "no bgp route-reflector allow-outbound-policy", - NO_STR - "BGP specific commands\n" - "Allow modifications made by out route-map\n" - "on ibgp neighbors\n") + +void cli_show_router_global_neighbor_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + uint32_t write_quanta, read_quanta; + + if (yang_dnode_get_bool(dnode, "./log-neighbor-changes")) + vty_out(vty, " bgp log-neighbor-changes\n"); - if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); - update_group_announce_rrclients(bgp); - bgp_clear_star_soft_out(vty, bgp->name); + if (yang_dnode_exists(dnode, "./dynamic-neighbors-limit")) { + uint32_t listen_limit = yang_dnode_get_uint32( + dnode, "./dynamic-neighbors-limit"); + vty_out(vty, " bgp listen limit %u\n", listen_limit); } - return CMD_SUCCESS; + write_quanta = yang_dnode_get_uint32( + dnode, "./packet-quanta-config/wpkt-quanta"); + if (write_quanta != BGP_WRITE_PACKET_MAX) + vty_out(vty, " write-quanta %d\n", write_quanta); + + read_quanta = yang_dnode_get_uint32( + dnode, "./packet-quanta-config/rpkt-quanta"); + + if (read_quanta != BGP_READ_PACKET_MAX) + vty_out(vty, " read-quanta %d\n", read_quanta); } -DEFUN (bgp_listen_limit, - bgp_listen_limit_cmd, - "bgp listen limit (1-5000)", - "BGP specific commands\n" - "BGP Dynamic Neighbors listen commands\n" - "Maximum number of BGP Dynamic Neighbors that can be created\n" - "Configure Dynamic Neighbors listen limit value\n") +DEFUN_YANG(bgp_listen_limit, + bgp_listen_limit_cmd, + "bgp listen limit (1-5000)", + "BGP specific commands\n" + "BGP Dynamic Neighbors listen commands\n" + "Maximum number of BGP Dynamic Neighbors that can be created\n" + "Configure Dynamic Neighbors listen limit value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - int listen_limit; - listen_limit = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change( + vty, "./global-neighbor-config/dynamic-neighbors-limit", + NB_OP_MODIFY, argv[idx_number]->arg); - bgp_listen_limit_set(bgp, listen_limit); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_listen_limit, - no_bgp_listen_limit_cmd, - "no bgp listen limit [(1-5000)]", - NO_STR - "BGP specific commands\n" - "BGP Dynamic Neighbors listen commands\n" - "Maximum number of BGP Dynamic Neighbors that can be created\n" - "Configure Dynamic Neighbors listen limit value\n") +DEFUN_YANG(no_bgp_listen_limit, + no_bgp_listen_limit_cmd, + "no bgp listen limit [(1-5000)]", + NO_STR + "BGP specific commands\n" + "BGP Dynamic Neighbors listen commands\n" + "Maximum number of BGP Dynamic Neighbors that can be created\n" + "Configure Dynamic Neighbors listen limit value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_listen_limit_unset(bgp); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global-neighbor-config/dynamic-neighbors-limit", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } @@ -3700,33 +3871,37 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp) } -DEFUN (bgp_disable_connected_route_check, - bgp_disable_connected_route_check_cmd, - "bgp disable-ebgp-connected-route-check", - "BGP specific commands\n" - "Disable checking if nexthop is connected on ebgp sessions\n") +DEFUN_YANG(bgp_disable_connected_route_check, + bgp_disable_connected_route_check_cmd, + "bgp disable-ebgp-connected-route-check", + "BGP specific commands\n" + "Disable checking if nexthop is connected on ebgp sessions\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./ebgp-multihop-connected-route-check", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_disable_connected_route_check, - no_bgp_disable_connected_route_check_cmd, - "no bgp disable-ebgp-connected-route-check", - NO_STR - "BGP specific commands\n" - "Disable checking if nexthop is connected on ebgp sessions\n") +DEFUN_YANG(no_bgp_disable_connected_route_check, + no_bgp_disable_connected_route_check_cmd, + "no bgp disable-ebgp-connected-route-check", + NO_STR + "BGP specific commands\n" + "Disable checking if nexthop is connected on ebgp sessions\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./ebgp-multihop-connected-route-check", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_global_ebgp_multihop_connected_route_check( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp disable-ebgp-connected-route-check\n"); +} static int peer_remote_as_vty(struct vty *vty, const char *peer_str, const char *as_str, afi_t afi, safi_t safi) @@ -3792,17 +3967,25 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str, return bgp_vty_return(vty, ret); } -DEFUN (bgp_default_shutdown, - bgp_default_shutdown_cmd, - "[no] bgp default shutdown", - NO_STR - BGP_STR - "Configure BGP defaults\n" - "Apply administrative shutdown to newly configured peers\n") +DEFUN_YANG(bgp_default_shutdown, + bgp_default_shutdown_cmd, + "[no] bgp default shutdown", + NO_STR BGP_STR + "Configure BGP defaults\n" + "Apply administrative shutdown to newly configured peers\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->autoshutdown = !strmatch(argv[0]->text, "no"); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./default-shutdown", NB_OP_MODIFY, + strmatch(argv[0]->text, "no") ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_default_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp default shutdown\n"); } DEFPY(bgp_shutdown_msg, bgp_shutdown_msg_cmd, "bgp shutdown message MSG...", @@ -8603,6 +8786,8 @@ DEFUN (clear_ip_bgp_all, char *clr_arg = NULL; int idx = 0; + char errmsg[BUFSIZ] = {'\0'}; + int ret; /* clear [ip] bgp */ if (argv_find(argv, argc, "ip", &idx)) @@ -8667,7 +8852,12 @@ DEFUN (clear_ip_bgp_all, } else clr_type = BGP_CLEAR_SOFT_NONE; - return bgp_clear_vty(vty, vrf, afi, safi, clr_sort, clr_type, clr_arg); + ret = bgp_clear_vty(vrf, afi, safi, clr_sort, clr_type, clr_arg, errmsg, + sizeof(errmsg)); + if (ret != NB_OK) + vty_out(vty, "Error description: %s\n", errmsg); + + return ret; } DEFUN (clear_ip_bgp_prefix, diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 95eefbc36..a9e86ec09 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -180,5 +180,12 @@ int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv, extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, safi_t safi, bool show_failed, bool show_established, bool use_json); +extern int bgp_clear_star_soft_in(const char *name, char *errmsg, + size_t errmsg_len); +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); + #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 426097054..30566b2c1 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -397,10 +397,6 @@ int bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) struct peer *peer; struct listnode *node, *nnode; - if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID) - && IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id)) - return 0; - IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id); bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID); @@ -473,14 +469,14 @@ void bgp_timers_unset(struct bgp *bgp) } /* BGP confederation configuration. */ -int bgp_confederation_id_set(struct bgp *bgp, as_t as) +void bgp_confederation_id_set(struct bgp *bgp, as_t as) { struct peer *peer; struct listnode *node, *nnode; int already_confed; if (as == 0) - return BGP_ERR_INVALID_AS; + return; /* Remember - were we doing confederation before? */ already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION); @@ -528,7 +524,7 @@ int bgp_confederation_id_set(struct bgp *bgp, as_t as) } } } - return 0; + return; } int bgp_confederation_id_unset(struct bgp *bgp) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9f72a3e19..3e3c6fc9e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -391,8 +391,9 @@ struct bgp { *t_maxmed_onstartup; /* non-null when max-med onstartup is on */ uint8_t maxmed_onstartup_over; /* Flag to make it effective only once */ - uint8_t v_maxmed_admin; /* 1/0 if max-med administrative is on/off */ -#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ + bool v_maxmed_admin; /* true/false if max-med administrative is on/off + */ +#define BGP_MAXMED_ADMIN_UNCONFIGURED false /* Off by default */ uint32_t maxmed_admin_value; /* Max-med value when administrative in on */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ @@ -1827,7 +1828,7 @@ extern void bgp_router_id_static_set(struct bgp *, struct in_addr); extern int bgp_cluster_id_set(struct bgp *, struct in_addr *); extern int bgp_cluster_id_unset(struct bgp *); -extern int bgp_confederation_id_set(struct bgp *, as_t); +extern void bgp_confederation_id_set(struct bgp *, as_t); extern int bgp_confederation_id_unset(struct bgp *); extern bool bgp_confederation_peers_check(struct bgp *, as_t); |