forked from Mirror/frr
bgpd: VRF-Lite fix default bgp delete
1. bgp coredump is observed when we delete default bgp instance when we have multi-vrf; and route-leaking is enabled between default, non-default vrfs. Removing default router bgp when routes leaked between non-default vrfs. - Routes are leaked from VRF-A to VRF-B - VPN table is created with auto RD/RT in default instance. - Default instance is deleted, we try to unimport the routes from all VRFs - non-default VRF schedules a work-queue to process deleted routes. - Meanwhile default bgp instance clears VPN tables and free the route entries as well, which are still referenced by non-default VRFs which have imported routes. - When work queue process starts to delete imported route in VRF-A it cores as it accesses freed memory. - Whenever we delete bgp in default vrf, we skip deleting routes in the vpn table, import and export lists. - The default hidden bgp instance will not be listed in any of the show commands. - Whenever we create new default instance, handle it with AS number change i.e. old hidden default bgp's AS number is updated and also changing local_as for all peers. 2. A default instance is created with ASN of the vrf with the import statement. This may not be the ASN desired for the default table - First problem with current behavior. Define two vrfs with different ASNs and then add import between. starting without any bgp config (no default instance) A default instance is created with ASN of the vrf with the import statement. This may not be the ASN desired for the default table - Second related problem. Start with a default instance and a vrf in a different ASN. Do an import statement in the vrf for a bgp vrf instance not yet defined and it auto-creates that bgp/vrf instance and it inherits the ASN of the importing vrf - Handle bgp instances with different ASNs and handle ASN for auto created BGP instance Signed-off-by: Kantesh Mundaragi <kmundaragi@vmware.com>
This commit is contained in:
parent
6109043c54
commit
4d0e7a49cf
|
@ -779,7 +779,8 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi,
|
|||
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (bgp == NULL) {
|
||||
|
||||
if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "No BGP process is configured\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
|
|
@ -3866,7 +3866,8 @@ void bgp_vpn_leak_unimport(struct bgp *from_bgp)
|
|||
bool is_vrf_leak_bind;
|
||||
int debug;
|
||||
|
||||
if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
|
||||
if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF &&
|
||||
from_bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
|
||||
return;
|
||||
|
||||
debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
|
||||
|
|
|
@ -3618,7 +3618,16 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|
|||
struct bgp_path_info_pair old_and_new;
|
||||
int debug = 0;
|
||||
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
|
||||
/*
|
||||
* For default bgp instance, which is deleted i.e. marked hidden
|
||||
* we are skipping SAFI_MPLS_VPN route table deletion
|
||||
* in bgp_cleanup_routes.
|
||||
* So, we need to delete routes from VPNV4 table.
|
||||
* Here for !IS_BGP_INSTANCE_HIDDEN,
|
||||
* !(SAFI_MPLS_VPN && AF_IP/AF_IP6),
|
||||
* we ignore the event for the prefix.
|
||||
*/
|
||||
if (BGP_INSTANCE_HIDDEN_DELETE_IN_PROGRESS(bgp, afi, safi)) {
|
||||
if (dest)
|
||||
debug = bgp_debug_bestpath(dest);
|
||||
if (debug)
|
||||
|
@ -6444,18 +6453,23 @@ void bgp_cleanup_routes(struct bgp *bgp)
|
|||
if (afi != AFI_L2VPN) {
|
||||
safi_t safi;
|
||||
safi = SAFI_MPLS_VPN;
|
||||
for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
|
||||
dest = bgp_route_next(dest)) {
|
||||
table = bgp_dest_get_bgp_table_info(dest);
|
||||
if (!IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
for (dest = bgp_table_top(bgp->rib[afi][safi]);
|
||||
dest; dest = bgp_route_next(dest)) {
|
||||
table = bgp_dest_get_bgp_table_info(
|
||||
dest);
|
||||
if (table != NULL) {
|
||||
bgp_cleanup_table(bgp, table, afi, safi);
|
||||
bgp_cleanup_table(bgp, table,
|
||||
afi, safi);
|
||||
bgp_table_finish(&table);
|
||||
bgp_dest_set_bgp_table_info(dest, NULL);
|
||||
dest = bgp_dest_unlock_node(dest);
|
||||
|
||||
bgp_dest_set_bgp_table_info(dest,
|
||||
NULL);
|
||||
dest = bgp_dest_unlock_node(
|
||||
dest);
|
||||
assert(dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
safi = SAFI_ENCAP;
|
||||
for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
|
||||
dest = bgp_route_next(dest)) {
|
||||
|
@ -12157,7 +12171,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
|||
bgp = bgp_get_default();
|
||||
}
|
||||
|
||||
if (bgp == NULL) {
|
||||
if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
if (!use_json)
|
||||
vty_out(vty, "No BGP process is configured\n");
|
||||
else
|
||||
|
@ -12203,6 +12217,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
|
|||
vty_out(vty, "{\n");
|
||||
|
||||
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
continue;
|
||||
route_output = true;
|
||||
if (use_json) {
|
||||
if (!is_first)
|
||||
|
@ -12721,7 +12737,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
|
|||
{
|
||||
if (!bgp) {
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp) {
|
||||
if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
if (!use_json)
|
||||
vty_out(vty, "No BGP process is configured\n");
|
||||
else
|
||||
|
@ -14379,7 +14395,7 @@ DEFUN (show_ip_bgp_vpn_all_route_prefix,
|
|||
int idx = 0;
|
||||
char *network = NULL;
|
||||
struct bgp *bgp = bgp_get_default();
|
||||
if (!bgp) {
|
||||
if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "Can't find default instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -15881,7 +15897,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
|
|||
/* BGP structure lookup. */
|
||||
if (view_name) {
|
||||
bgp = bgp_lookup_by_name(view_name);
|
||||
if (bgp == NULL) {
|
||||
if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "%% Can't find BGP instance %s\n",
|
||||
view_name);
|
||||
return CMD_WARNING;
|
||||
|
|
|
@ -879,6 +879,7 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
|
|||
switch (ret) {
|
||||
case BGP_SUCCESS:
|
||||
case BGP_CREATED:
|
||||
case BGP_INSTANCE_EXISTS:
|
||||
case BGP_GR_NO_OPERATION:
|
||||
break;
|
||||
case BGP_ERR_INVALID_VALUE:
|
||||
|
@ -1418,7 +1419,7 @@ DEFUN_HIDDEN (bgp_local_mac,
|
|||
seq = strtoul(argv[7]->arg, NULL, 10);
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp) {
|
||||
if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "Default BGP instance is not there\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -1458,7 +1459,7 @@ DEFUN_HIDDEN (no_bgp_local_mac,
|
|||
memset(&ip, 0, sizeof(ip));
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp) {
|
||||
if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "Default BGP instance is not there\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -1601,8 +1602,12 @@ DEFUN_NOSH (router_bgp,
|
|||
if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
|
||||
vpn_leak_postchange_all();
|
||||
|
||||
if (inst_type == BGP_INSTANCE_TYPE_VRF)
|
||||
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);
|
||||
}
|
||||
/* Pending: handle when user tries to change a view to vrf n vv.
|
||||
*/
|
||||
/* for pre-existing bgp instance,
|
||||
|
@ -1674,7 +1679,7 @@ DEFUN (no_router_bgp,
|
|||
argv[idx_asn]->arg);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
if (argc > 4) {
|
||||
if (argc > 4 && strncmp(argv[4]->arg, "vrf", 3) == 0) {
|
||||
name = argv[idx_vrf]->arg;
|
||||
if (strmatch(argv[idx_vrf - 1]->text, "vrf")
|
||||
&& strmatch(name, VRF_DEFAULT_NAME))
|
||||
|
@ -10444,9 +10449,9 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
|
|||
bgp_default = bgp_get_default();
|
||||
if (!bgp_default) {
|
||||
int32_t ret;
|
||||
as_t as = bgp->as;
|
||||
as_t as = AS_UNSPECIFIED;
|
||||
|
||||
/* Auto-create assuming the same AS */
|
||||
/* Auto-create with AS_UNSPECIFIED, to be filled in later */
|
||||
ret = bgp_get_vty(&bgp_default, &as, NULL,
|
||||
BGP_INSTANCE_TYPE_DEFAULT, NULL,
|
||||
ASNOTATION_UNDEFINED);
|
||||
|
@ -10456,6 +10461,8 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
|
|||
"VRF default is not configured as a bgp instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN);
|
||||
}
|
||||
|
||||
vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
|
||||
|
@ -10559,7 +10566,9 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
|
|||
|
||||
bgp_default = bgp_get_default();
|
||||
if (!bgp_default) {
|
||||
/* Auto-create assuming the same AS */
|
||||
as = AS_UNSPECIFIED;
|
||||
|
||||
/* Auto-create with AS_UNSPECIFIED, to be filled in later */
|
||||
ret = bgp_get_vty(&bgp_default, &as, NULL,
|
||||
BGP_INSTANCE_TYPE_DEFAULT, NULL,
|
||||
ASNOTATION_UNDEFINED);
|
||||
|
@ -10569,6 +10578,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
|
|||
"VRF default is not configured as a bgp instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN);
|
||||
}
|
||||
|
||||
vrf_bgp = bgp_lookup_by_name(import_name);
|
||||
|
@ -10576,9 +10587,19 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
|
|||
if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) {
|
||||
vrf_bgp = bgp_default;
|
||||
} else {
|
||||
/* Auto-create assuming the same AS */
|
||||
as = AS_UNSPECIFIED;
|
||||
|
||||
/* Auto-create with AS_UNSPECIFIED, fill in later */
|
||||
ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type,
|
||||
NULL, ASNOTATION_UNDEFINED);
|
||||
if (ret) {
|
||||
vty_out(vty,
|
||||
"VRF %s is not configured as a bgp instance\n",
|
||||
import_name);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
SET_FLAG(vrf_bgp->flags, BGP_FLAG_INSTANCE_HIDDEN);
|
||||
|
||||
/* Auto created VRF instances should be marked
|
||||
* properly, otherwise we have a state after bgpd
|
||||
|
@ -11549,7 +11570,7 @@ DEFUN(show_bgp_martian_nexthop_db, show_bgp_martian_nexthop_db_cmd,
|
|||
else
|
||||
bgp = bgp_get_default();
|
||||
|
||||
if (!bgp) {
|
||||
if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
vty_out(vty, "%% No BGP process is configured\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -12781,6 +12802,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
|
|||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
|
||||
continue;
|
||||
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
continue;
|
||||
|
||||
nbr_output = true;
|
||||
if (use_json) {
|
||||
if (!is_first)
|
||||
|
@ -16169,6 +16193,9 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
|
|||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
|
||||
continue;
|
||||
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
continue;
|
||||
|
||||
nbr_output = true;
|
||||
if (use_json) {
|
||||
if (!(json = json_object_new_object())) {
|
||||
|
@ -16824,6 +16851,9 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
|
|||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
|
||||
continue;
|
||||
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
continue;
|
||||
|
||||
if (!uj)
|
||||
vty_out(vty, "\nInstance %s:\n",
|
||||
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
|
||||
|
@ -16946,7 +16976,7 @@ DEFUN (show_bgp_updgrps_stats,
|
|||
struct bgp *bgp;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (bgp)
|
||||
if (bgp && !IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
update_group_show_stats(bgp, vty);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -18941,6 +18971,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||
char *addr;
|
||||
bool flag_scomm, flag_secomm, flag_slcomm;
|
||||
|
||||
/* skip hidden default vrf bgp instance */
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
return;
|
||||
|
||||
/* Skip dynamic neighbors. */
|
||||
if (peer_dynamic_neighbor(peer))
|
||||
return;
|
||||
|
@ -19246,6 +19280,9 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||
struct peer_group *group;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
/* skip hidden default vrf bgp instance */
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
return;
|
||||
|
||||
vty_frame(vty, " !\n address-family ");
|
||||
if (afi == AFI_IP) {
|
||||
|
@ -19428,6 +19465,10 @@ int bgp_config_write(struct vty *vty)
|
|||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
|
||||
continue;
|
||||
|
||||
/* skip hidden default vrf bgp instance */
|
||||
if (IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
continue;
|
||||
|
||||
/* Router bgp ASN */
|
||||
vty_out(vty, "router bgp %s", bgp->as_pretty);
|
||||
|
||||
|
|
99
bgpd/bgpd.c
99
bgpd/bgpd.c
|
@ -3421,12 +3421,18 @@ static void bgp_vrf_string_name_delete(void *data)
|
|||
static struct bgp *bgp_create(as_t *as, const char *name,
|
||||
enum bgp_instance_type inst_type,
|
||||
const char *as_pretty,
|
||||
enum asnotation_mode asnotation)
|
||||
enum asnotation_mode asnotation,
|
||||
struct bgp *bgp_old, bool hidden)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
if (hidden) {
|
||||
bgp = bgp_old;
|
||||
goto peer_init;
|
||||
}
|
||||
|
||||
bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
|
||||
bgp->as = *as;
|
||||
if (as_pretty)
|
||||
|
@ -3480,18 +3486,24 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp->peer_self->domainname =
|
||||
XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
|
||||
bgp->peer = list_new();
|
||||
|
||||
peer_init:
|
||||
bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
|
||||
bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
|
||||
"BGP Peer Hash");
|
||||
bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
|
||||
|
||||
if (!hidden)
|
||||
bgp->group = list_new();
|
||||
bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
|
||||
|
||||
FOREACH_AFI_SAFI (afi, safi) {
|
||||
if (!hidden) {
|
||||
bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi);
|
||||
bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, safi);
|
||||
bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi,
|
||||
safi);
|
||||
bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi);
|
||||
}
|
||||
|
||||
/* Enable maximum-paths */
|
||||
bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
|
||||
|
@ -3530,7 +3542,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp->rmap_def_originate_eval_timer = 0;
|
||||
|
||||
#ifdef ENABLE_BGP_VNC
|
||||
if (inst_type != BGP_INSTANCE_TYPE_VRF) {
|
||||
if (inst_type != BGP_INSTANCE_TYPE_VRF && !hidden) {
|
||||
bgp->rfapi = bgp_rfapi_new(bgp);
|
||||
assert(bgp->rfapi);
|
||||
assert(bgp->rfapi_cfg);
|
||||
|
@ -3547,9 +3559,11 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp->vpn_policy[afi].import_vrf = list_new();
|
||||
bgp->vpn_policy[afi].import_vrf->del =
|
||||
bgp_vrf_string_name_delete;
|
||||
if (!hidden) {
|
||||
bgp->vpn_policy[afi].export_vrf = list_new();
|
||||
bgp->vpn_policy[afi].export_vrf->del =
|
||||
bgp_vrf_string_name_delete;
|
||||
}
|
||||
SET_FLAG(bgp->af_flags[afi][SAFI_MPLS_VPN],
|
||||
BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL);
|
||||
}
|
||||
|
@ -3567,7 +3581,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp->restart_time, &bgp->t_startup);
|
||||
|
||||
/* printable name we can use in debug messages */
|
||||
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
|
||||
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !hidden) {
|
||||
bgp->name_pretty = XSTRDUP(MTYPE_BGP_NAME, "VRF default");
|
||||
} else {
|
||||
const char *n;
|
||||
|
@ -3595,10 +3609,12 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
|
||||
bgp->default_af[AFI_IP][SAFI_UNICAST] = true;
|
||||
|
||||
if (!hidden)
|
||||
QOBJ_REG(bgp, bgp);
|
||||
|
||||
update_bgp_group_init(bgp);
|
||||
|
||||
if (!hidden) {
|
||||
/* assign a unique rd id for auto derivation of vrf's RD */
|
||||
bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
|
||||
|
||||
|
@ -3606,6 +3622,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
bgp_evpn_vrf_es_init(bgp);
|
||||
bgp_pbr_init(bgp);
|
||||
bgp_srv6_init(bgp);
|
||||
}
|
||||
|
||||
/*initilize global GR FSM */
|
||||
bgp_global_gr_init(bgp);
|
||||
|
@ -3743,10 +3760,15 @@ 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 *name,
|
||||
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)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct peer *peer = NULL;
|
||||
struct listnode *node, *nnode;
|
||||
bool hidden = false;
|
||||
|
||||
/* Multiple instance check. */
|
||||
if (name)
|
||||
|
@ -3755,14 +3777,28 @@ 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 (IS_BGP_INSTANCE_HIDDEN(bgp) && *as != AS_UNSPECIFIED)
|
||||
hidden = true;
|
||||
/* Handle AS number change */
|
||||
if (bgp->as != *as) {
|
||||
*as = bgp->as;
|
||||
return BGP_ERR_AS_MISMATCH;
|
||||
if (hidden)
|
||||
bgp_create(as, name, inst_type, as_pretty,
|
||||
asnotation, bgp, hidden);
|
||||
|
||||
/* Set all peer's local as number with this ASN */
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
|
||||
peer->local_as = *as;
|
||||
UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN);
|
||||
*bgp_val = bgp;
|
||||
return BGP_INSTANCE_EXISTS;
|
||||
}
|
||||
if (bgp->inst_type != inst_type)
|
||||
return BGP_ERR_INSTANCE_MISMATCH;
|
||||
return BGP_SUCCESS;
|
||||
if (hidden)
|
||||
bgp_create(as, name, inst_type, as_pretty, asnotation,
|
||||
bgp, hidden);
|
||||
*bgp_val = bgp;
|
||||
return BGP_INSTANCE_EXISTS;
|
||||
}
|
||||
*bgp_val = NULL;
|
||||
|
||||
|
@ -3778,11 +3814,13 @@ 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, name, inst_type);
|
||||
ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation,
|
||||
name, inst_type);
|
||||
if (ret || *bgp_val)
|
||||
return ret;
|
||||
|
||||
bgp = bgp_create(as, name, inst_type, as_pretty, asnotation);
|
||||
bgp = bgp_create(as, name, inst_type, as_pretty, asnotation, NULL,
|
||||
false);
|
||||
|
||||
/*
|
||||
* view instances will never work inside of a vrf
|
||||
|
@ -4022,6 +4060,15 @@ int bgp_delete(struct bgp *bgp)
|
|||
bgp_damp_disable(bgp, afi, safi);
|
||||
}
|
||||
|
||||
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT &&
|
||||
(bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]) ||
|
||||
bgp_table_top(bgp->rib[AFI_IP6][SAFI_MPLS_VPN]))) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug(
|
||||
"Marking the deleting default bgp instance as hidden");
|
||||
SET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN);
|
||||
}
|
||||
|
||||
if (BGP_DEBUG(zebra, ZEBRA)) {
|
||||
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
|
||||
zlog_debug("Deleting Default VRF");
|
||||
|
@ -4066,7 +4113,7 @@ int bgp_delete(struct bgp *bgp)
|
|||
peer_delete(peer);
|
||||
}
|
||||
|
||||
if (bgp->peer_self) {
|
||||
if (bgp->peer_self && !IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
peer_delete(bgp->peer_self);
|
||||
bgp->peer_self = NULL;
|
||||
}
|
||||
|
@ -4076,6 +4123,7 @@ int bgp_delete(struct bgp *bgp)
|
|||
/* TODO - Other memory may need to be freed - e.g., NHT */
|
||||
|
||||
#ifdef ENABLE_BGP_VNC
|
||||
if (!IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
rfapi_delete(bgp);
|
||||
#endif
|
||||
|
||||
|
@ -4118,7 +4166,7 @@ int bgp_delete(struct bgp *bgp)
|
|||
}
|
||||
|
||||
/* Deregister from Zebra, if needed */
|
||||
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
|
||||
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) && !IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug(
|
||||
"%s: deregistering this bgp %s instance from zebra",
|
||||
|
@ -4126,17 +4174,19 @@ int bgp_delete(struct bgp *bgp)
|
|||
bgp_zebra_instance_deregister(bgp);
|
||||
}
|
||||
|
||||
/* Remove visibility via the master list - there may however still be
|
||||
* routes to be processed still referencing the struct bgp.
|
||||
if (!IS_BGP_INSTANCE_HIDDEN(bgp)) {
|
||||
/* Remove visibility via the master list -
|
||||
* there may however still be routes to be processed
|
||||
* still referencing the struct bgp.
|
||||
*/
|
||||
listnode_delete(bm->bgp, bgp);
|
||||
|
||||
/* Free interfaces in this instance. */
|
||||
bgp_if_finish(bgp);
|
||||
}
|
||||
|
||||
vrf = bgp_vrf_lookup_by_instance_type(bgp);
|
||||
bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
|
||||
if (vrf)
|
||||
if (vrf && !IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
bgp_vrf_unlink(bgp, vrf);
|
||||
|
||||
/* Update EVPN VRF pointer */
|
||||
|
@ -4151,7 +4201,22 @@ int bgp_delete(struct bgp *bgp)
|
|||
work_queue_free_and_null(&bgp->process_queue);
|
||||
|
||||
event_master_free_unused(bm->master);
|
||||
|
||||
if (!IS_BGP_INSTANCE_HIDDEN(bgp))
|
||||
bgp_unlock(bgp); /* initial reference */
|
||||
else {
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
enum vpn_policy_direction dir;
|
||||
|
||||
if (bgp->vpn_policy[afi].import_vrf)
|
||||
list_delete(&bgp->vpn_policy[afi].import_vrf);
|
||||
|
||||
dir = BGP_VPN_POLICY_DIR_FROMVPN;
|
||||
if (bgp->vpn_policy[afi].rtlist[dir])
|
||||
ecommunity_free(
|
||||
&bgp->vpn_policy[afi].rtlist[dir]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
17
bgpd/bgpd.h
17
bgpd/bgpd.h
|
@ -550,6 +550,7 @@ struct bgp {
|
|||
#define BGP_FLAG_ENFORCE_FIRST_AS (1ULL << 36)
|
||||
#define BGP_FLAG_DYNAMIC_CAPABILITY (1ULL << 37)
|
||||
#define BGP_FLAG_VNI_DOWN (1ULL << 38)
|
||||
#define BGP_FLAG_INSTANCE_HIDDEN (1ULL << 39)
|
||||
|
||||
/* BGP default address-families.
|
||||
* New peers inherit enabled afi/safis from bgp instance.
|
||||
|
@ -2152,6 +2153,7 @@ enum bgp_clear_type {
|
|||
enum bgp_create_error_code {
|
||||
BGP_SUCCESS = 0,
|
||||
BGP_CREATED = 1,
|
||||
BGP_INSTANCE_EXISTS = 2,
|
||||
BGP_ERR_INVALID_VALUE = -1,
|
||||
BGP_ERR_INVALID_FLAG = -2,
|
||||
BGP_ERR_INVALID_AS = -3,
|
||||
|
@ -2822,6 +2824,8 @@ 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);
|
||||
|
||||
|
@ -2863,4 +2867,17 @@ extern void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode);
|
|||
/* clang-format on */
|
||||
#endif
|
||||
|
||||
/* Macro to check if default bgp instance is hidden */
|
||||
#define IS_BGP_INSTANCE_HIDDEN(_bgp) \
|
||||
(CHECK_FLAG(_bgp->flags, BGP_FLAG_INSTANCE_HIDDEN) && \
|
||||
(_bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT || \
|
||||
_bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
|
||||
|
||||
/* Macro to check if bgp instance delete in-progress and !hidden */
|
||||
#define BGP_INSTANCE_HIDDEN_DELETE_IN_PROGRESS(_bgp, _afi, _safi) \
|
||||
(CHECK_FLAG(_bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) && \
|
||||
!IS_BGP_INSTANCE_HIDDEN(_bgp) && \
|
||||
!(_afi == AFI_IP && _safi == SAFI_MPLS_VPN) && \
|
||||
!(_afi == AFI_IP6 && _safi == SAFI_MPLS_VPN))
|
||||
|
||||
#endif /* _QUAGGA_BGPD_H */
|
||||
|
|
Loading…
Reference in a new issue