diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index ff2c8ce93e..8ca7836a99 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -111,15 +111,24 @@ int bgp_router_create(struct nb_cb_create_args *args) is_new_bgp = (bgp_lookup_by_name(name) == NULL); ret = bgp_get_vty(&bgp, &as, name, inst_type); - switch (ret) { - case BGP_ERR_AS_MISMATCH: - snprintf(args->errmsg, args->errmsg_len, - "BGP instance is already running; AS is %u", - as); - return NB_ERR_INCONSISTENCY; - case BGP_ERR_INSTANCE_MISMATCH: - snprintf(args->errmsg, args->errmsg_len, - "BGP instance type mismatch"); + if (ret) { + switch (ret) { + case BGP_ERR_AS_MISMATCH: + snprintf( + args->errmsg, args->errmsg_len, + "BGP instance is already running; AS is %u", + as); + break; + case BGP_ERR_INSTANCE_MISMATCH: + snprintf(args->errmsg, args->errmsg_len, + "BGP instance type mismatch"); + break; + } + + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + + nb_running_set_entry(args->dnode, bgp); + return NB_ERR_INCONSISTENCY; } @@ -221,64 +230,26 @@ int bgp_router_destroy(struct nb_cb_destroy_args *args) int bgp_global_local_as_modify(struct nb_cb_modify_args *args) { struct bgp *bgp; - as_t as; - const struct lyd_node *vrf_dnode; - const char *vrf_name; - const char *name = NULL; - enum bgp_instance_type inst_type; - int ret; - bool is_view_inst = false; switch (args->event) { case NB_EV_VALIDATE: - as = yang_dnode_get_uint32(args->dnode, NULL); - - inst_type = BGP_INSTANCE_TYPE_DEFAULT; - - vrf_dnode = yang_dnode_get_parent(args->dnode, - "control-plane-protocol"); - vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); - - if (strmatch(vrf_name, VRF_DEFAULT_NAME)) { - name = NULL; - } else { - name = vrf_name; - inst_type = BGP_INSTANCE_TYPE_VRF; - } - - is_view_inst = yang_dnode_get_bool(args->dnode, - "../instance-type-view"); - if (is_view_inst) - inst_type = BGP_INSTANCE_TYPE_VIEW; - - ret = bgp_lookup_by_as_name_type(&bgp, &as, name, inst_type); - switch (ret) { - case BGP_ERR_AS_MISMATCH: + /* + * Changing AS number is not allowed, but we must allow it + * once, when the BGP instance is created the first time. + * If the instance already exists - return the validation + * error. + */ + bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent, + NULL, false); + if (bgp) { snprintf(args->errmsg, args->errmsg_len, - "BGP instance is already running; AS is %u", - as); - return NB_ERR_VALIDATION; - case BGP_ERR_INSTANCE_MISMATCH: - snprintf(args->errmsg, args->errmsg_len, - "BGP instance type mismatch"); + "Changing AS number is not allowed"); return NB_ERR_VALIDATION; } break; case NB_EV_PREPARE: case NB_EV_ABORT: - return NB_OK; case NB_EV_APPLY: - /* 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; } @@ -1514,12 +1485,27 @@ int bgp_global_global_config_timers_keepalive_modify( */ int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args) { + struct bgp *bgp; + switch (args->event) { case NB_EV_VALIDATE: + /* + * Changing instance type is not allowed, but we must allow it + * once, when the BGP instance is created the first time. + * If the instance already exists - return the validation + * error. + */ + bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent, + NULL, false); + if (bgp) { + snprintf(args->errmsg, args->errmsg_len, + "Changing instance type is not allowed"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 36aa3e1a3e..5b5f166e4b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1380,6 +1380,10 @@ DEFUN_YANG_NOSH(router_bgp, nb_cli_enqueue_change(vty, "./global/instance-type-view", NB_OP_MODIFY, "true"); + } else { + nb_cli_enqueue_change(vty, + "./global/instance-type-view", + NB_OP_MODIFY, "false"); } ret = nb_cli_apply_changes(vty, base_xpath); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 5e731eb5a0..9d2ff9c00e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3378,13 +3378,13 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name, bgp = bgp_get_default(); if (bgp) { + *bgp_val = bgp; if (bgp->as != *as) { *as = bgp->as; return BGP_ERR_AS_MISMATCH; } if (bgp->inst_type != inst_type) return BGP_ERR_INSTANCE_MISMATCH; - *bgp_val = bgp; return BGP_SUCCESS; } *bgp_val = NULL;