summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_route.c28
-rw-r--r--bgpd/bgp_vty.c34
-rw-r--r--bgpd/bgpd.c24
-rw-r--r--bgpd/bgpd.h9
4 files changed, 54 insertions, 41 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 8b94892b3..672c43b37 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4923,6 +4923,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bool force_evpn_import = false;
safi_t orig_safi = safi;
struct bgp_labels bgp_labels = {};
+ struct bgp_route_evpn *p_evpn = evpn;
uint8_t i;
if (frrtrace_enabled(frr_bgp, process_update)) {
@@ -4964,11 +4965,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
* will not be interned. In which case, it is ok to update the
* attr->evpn_overlay, so that, this can be stored in adj_in.
*/
- if (evpn) {
- if (afi == AFI_L2VPN)
- bgp_attr_set_evpn_overlay(attr, evpn);
- else
- evpn_overlay_free(evpn);
+ if (evpn && afi == AFI_L2VPN) {
+ bgp_attr_set_evpn_overlay(attr, evpn);
+ p_evpn = NULL;
}
bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels);
}
@@ -5141,11 +5140,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
* attr->evpn_overlay with evpn directly. Instead memcpy
* evpn to new_atr.evpn_overlay before it is interned.
*/
- if (soft_reconfig && evpn) {
- if (afi == AFI_L2VPN)
- bgp_attr_set_evpn_overlay(&new_attr, evpn);
- else
- evpn_overlay_free(evpn);
+ if (soft_reconfig && evpn && afi == AFI_L2VPN) {
+ bgp_attr_set_evpn_overlay(&new_attr, evpn);
+ p_evpn = NULL;
}
/* Apply incoming route-map.
@@ -5314,7 +5311,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_dest_unlock_node(dest);
bgp_attr_unintern(&attr_new);
-
+ if (p_evpn)
+ evpn_overlay_free(p_evpn);
return;
}
@@ -5479,6 +5477,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
ret = bgp_damp_update(pi, dest, afi, safi);
if (ret == BGP_DAMP_SUPPRESSED) {
bgp_dest_unlock_node(dest);
+ if (p_evpn)
+ evpn_overlay_free(p_evpn);
return;
}
}
@@ -5565,6 +5565,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
type, sub_type, NULL);
}
#endif
+ if (p_evpn)
+ evpn_overlay_free(p_evpn);
return;
} // End of implicit withdraw
@@ -5659,6 +5661,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
}
#endif
+ if (p_evpn)
+ evpn_overlay_free(p_evpn);
return;
/* This BGP update is filtered. Log the reason then update BGP
@@ -5722,6 +5726,8 @@ filtered:
}
#endif
+ if (p_evpn)
+ evpn_overlay_free(p_evpn);
return;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 33b220d3e..2b3e11929 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,35 +1566,40 @@ 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",
- bgp->as_pretty);
+ bgp ? bgp->as_pretty : "unknown");
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 %s\n",
- bgp->as_pretty);
+ vty_out(vty, "BGP instance is already running; AS is %s\n",
+ bgp ? bgp->as_pretty : "unknown");
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!bgp) {
+ vty_out(vty, "BGP instance not found\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
/*
* 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)
+ if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vpn_leak_postchange_all();
- if (inst_type == BGP_INSTANCE_TYPE_VRF ||
- IS_BGP_INSTANCE_HIDDEN(bgp)) {
+ if (inst_type == BGP_INSTANCE_TYPE_VRF || IS_BGP_INSTANCE_HIDDEN(bgp)) {
bgp_vpn_leak_export(bgp);
UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN);
UNSET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS);
@@ -10559,7 +10563,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN);
}
- vrf_bgp = bgp_lookup_by_name(import_name);
+ vrf_bgp = bgp_lookup_by_name_filter(import_name, false);
if (!vrf_bgp) {
if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) {
vrf_bgp = bgp_default;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index c2254ae79..d5463f3d0 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)
+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 c72072852..96a78e666 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2285,6 +2285,7 @@ extern void bgp_zclient_reset(void);
extern struct bgp *bgp_get_default(void);
extern struct bgp *bgp_lookup(as_t, const char *);
extern struct bgp *bgp_lookup_by_name(const char *);
+extern struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto);
extern struct bgp *bgp_lookup_by_vrf_id(vrf_id_t);
extern struct bgp *bgp_get_evpn(void);
extern void bgp_set_evpn(struct bgp *bgp);
@@ -2859,11 +2860,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),