diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 33b220d3ec70..8fefbeb49378 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1499,13 +1499,12 @@ DEFUN_NOSH (router_bgp, int idx_asn = 2; int idx_view_vrf = 3; int idx_vrf = 4; - int is_new_bgp = 0; int idx_asnotation = 3; int idx_asnotation_kind = 4; enum asnotation_mode asnotation = ASNOTATION_UNDEFINED; int ret; as_t as; - struct bgp *bgp; + struct bgp *bgp = NULL; const char *name = NULL; enum bgp_instance_type inst_type; @@ -1567,11 +1566,14 @@ DEFUN_NOSH (router_bgp, asnotation = ASNOTATION_PLAIN; } - if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) - is_new_bgp = (bgp_lookup(as, name) == NULL); - - ret = bgp_get_vty(&bgp, &as, name, inst_type, - argv[idx_asn]->arg, asnotation); + ret = bgp_lookup_by_as_name_type(&bgp, &as, argv[idx_asn]->arg, asnotation, name, + inst_type, true); + if (bgp && ret == BGP_INSTANCE_EXISTS) + ret = CMD_SUCCESS; + else if (bgp == NULL && ret == CMD_SUCCESS) + /* SUCCESS and bgp is NULL */ + ret = bgp_get_vty(&bgp, &as, name, inst_type, argv[idx_asn]->arg, + asnotation); switch (ret) { case BGP_ERR_AS_MISMATCH: vty_out(vty, "BGP is already running; AS is %s\n", @@ -1591,7 +1593,7 @@ DEFUN_NOSH (router_bgp, * 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) + if (bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) vpn_leak_postchange_all(); if (inst_type == BGP_INSTANCE_TYPE_VRF || diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c2254ae791e9..c45690a79261 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3634,13 +3634,13 @@ struct bgp *bgp_lookup(as_t as, const char *name) } /* Lookup BGP structure by view name. */ -struct bgp *bgp_lookup_by_name(const char *name) +static struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto) { struct bgp *bgp; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { - if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + if (filter_auto && CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; if ((bgp->name == NULL && name == NULL) || (bgp->name && name && strcmp(bgp->name, name) == 0)) @@ -3649,6 +3649,11 @@ struct bgp *bgp_lookup_by_name(const char *name) return NULL; } +struct bgp *bgp_lookup_by_name(const char *name) +{ + return bgp_lookup_by_name_filter(name, true); +} + /* Lookup BGP instance based on VRF id. */ /* Note: Only to be used for incoming messages from Zebra. */ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id) @@ -3734,10 +3739,9 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, return bgp_check_main_socket(create, bgp); } -int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, - const char *as_pretty, +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty, enum asnotation_mode asnotation, const char *name, - enum bgp_instance_type inst_type) + enum bgp_instance_type inst_type, bool force_config) { struct bgp *bgp; struct peer *peer = NULL; @@ -3746,7 +3750,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, /* Multiple instance check. */ if (name) - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name_filter(name, !force_config); else bgp = bgp_get_default(); @@ -3756,7 +3760,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, /* Handle AS number change */ if (bgp->as != *as) { if (hidden || CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) { - if (hidden) { + if (force_config == false && hidden) { bgp_create(as, name, inst_type, as_pretty, asnotation, bgp, hidden); @@ -3764,7 +3768,8 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, BGP_FLAG_INSTANCE_HIDDEN); } else { bgp->as = *as; - UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + if (force_config == false) + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); } /* Set all peer's local AS with this ASN */ @@ -3801,8 +3806,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, struct vrf *vrf = NULL; int ret = 0; - ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, - name, inst_type); + ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, name, inst_type, false); if (ret || *bgp_val) return ret; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c72072852d1b..9a1ac6cc786f 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2859,11 +2859,9 @@ extern struct peer *peer_new(struct bgp *bgp); extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, const char *ip_str, bool use_json); -extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, - const char *as_pretty, - enum asnotation_mode asnotation, - const char *name, - enum bgp_instance_type inst_type); +extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty, + enum asnotation_mode asnotation, const char *name, + enum bgp_instance_type inst_type, bool force_config); /* Hooks */ DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),