diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 3a61c0cd74..732cc6d2bb 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -169,17 +169,17 @@ static bool vrf_import_rt_hash_cmp(const void *p1, const void *p2) } /* - * Create a new vrf import_rt in default instance + * Create a new vrf import_rt in evpn instance */ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) { - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; struct vrf_irt_node *irt; - bgp_def = bgp_get_default(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err(EC_BGP_NO_DFLT, - "vrf import rt new - def instance not created yet"); + "vrf import rt new - evpn instance not created yet"); return NULL; } @@ -190,7 +190,7 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) irt->vrfs = list_new(); /* Add to hash */ - if (!hash_get(bgp_def->vrf_import_rt_hash, irt, hash_alloc_intern)) { + if (!hash_get(bgp_evpn->vrf_import_rt_hash, irt, hash_alloc_intern)) { XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt); return NULL; } @@ -203,16 +203,16 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) */ static void vrf_import_rt_free(struct vrf_irt_node *irt) { - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; - bgp_def = bgp_get_default(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err(EC_BGP_NO_DFLT, - "vrf import rt free - def instance not created yet"); + "vrf import rt free - evpn instance not created yet"); return; } - hash_release(bgp_def->vrf_import_rt_hash, irt); + hash_release(bgp_evpn->vrf_import_rt_hash, irt); list_delete(&irt->vrfs); XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt); } @@ -223,20 +223,21 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) */ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) { - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; struct vrf_irt_node *irt; struct vrf_irt_node tmp; - bgp_def = bgp_get_default(); - if (!bgp_def) { - flog_err(EC_BGP_NO_DFLT, - "vrf import rt lookup - def instance not created yet"); + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { + flog_err( + EC_BGP_NO_DFLT, + "vrf import rt lookup - evpn instance not created yet"); return NULL; } memset(&tmp, 0, sizeof(struct vrf_irt_node)); memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE); - irt = hash_lookup(bgp_def->vrf_import_rt_hash, &tmp); + irt = hash_lookup(bgp_evpn->vrf_import_rt_hash, &tmp); return irt; } @@ -1421,7 +1422,7 @@ static int update_evpn_type4_route(struct bgp *bgp, return 0; } -static int update_evpn_type5_route_entry(struct bgp *bgp_def, +static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, struct bgp *bgp_vrf, afi_t afi, safi_t safi, struct bgp_node *rn, struct attr *attr, int *route_changed) @@ -1436,7 +1437,7 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def, /* locate the local route entry if any */ for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi; tmp_pi = tmp_pi->next) { - if (tmp_pi->peer == bgp_def->peer_self + if (tmp_pi->peer == bgp_evpn->peer_self && tmp_pi->type == ZEBRA_ROUTE_BGP && tmp_pi->sub_type == BGP_ROUTE_STATIC) local_pi = tmp_pi; @@ -1456,7 +1457,7 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def, /* create the route info from attribute */ pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, - bgp_def->peer_self, attr_new, rn); + bgp_evpn->peer_self, attr_new, rn); SET_FLAG(pi->flags, BGP_PATH_VALID); /* Type-5 routes advertise the L3-VNI */ @@ -1502,11 +1503,11 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, safi_t safi = SAFI_EVPN; struct attr attr; struct bgp_node *rn = NULL; - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; int route_changed = 0; - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return 0; /* Build path attribute for this route - use the source attr, if @@ -1528,17 +1529,17 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, build_evpn_type5_route_extcomm(bgp_vrf, &attr); /* get the route node in global table */ - rn = bgp_afi_node_get(bgp_def->rib[afi][safi], afi, safi, + rn = bgp_afi_node_get(bgp_evpn->rib[afi][safi], afi, safi, (struct prefix *)evp, &bgp_vrf->vrf_prd); assert(rn); /* create or update the route entry within the route node */ - update_evpn_type5_route_entry(bgp_def, bgp_vrf, afi, safi, rn, &attr, + update_evpn_type5_route_entry(bgp_evpn, bgp_vrf, afi, safi, rn, &attr, &route_changed); /* schedule for processing and unlock node */ if (route_changed) { - bgp_process(bgp_def, rn, afi, safi); + bgp_process(bgp_evpn, rn, afi, safi); bgp_unlock_node(rn); } @@ -1925,21 +1926,21 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) safi_t safi = SAFI_EVPN; struct bgp_node *rn = NULL; struct bgp_path_info *pi = NULL; - struct bgp *bgp_def = NULL; /* default bgp instance */ + struct bgp *bgp_evpn = NULL; /* evpn bgp instance */ - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return 0; /* locate the global route entry for this type-5 prefix */ - rn = bgp_afi_node_lookup(bgp_def->rib[afi][safi], afi, safi, + rn = bgp_afi_node_lookup(bgp_evpn->rib[afi][safi], afi, safi, (struct prefix *)evp, &bgp_vrf->vrf_prd); if (!rn) return 0; - delete_evpn_route_entry(bgp_def, afi, safi, rn, &pi); + delete_evpn_route_entry(bgp_evpn, afi, safi, rn, &pi); if (pi) - bgp_process(bgp_def, rn, afi, safi); + bgp_process(bgp_evpn, rn, afi, safi); bgp_unlock_node(rn); return 0; } @@ -2994,19 +2995,19 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) struct bgp_path_info *pi; int ret; char buf[PREFIX_STRLEN]; - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; afi = AFI_L2VPN; safi = SAFI_EVPN; - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return -1; /* Walk entire global routing table and evaluate routes which could be * imported into this VRF. Note that we need to loop through all global * routes to determine which route matches the import rt on vrf */ - for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn; + for (rd_rn = bgp_table_top(bgp_evpn->rib[afi][safi]); rd_rn; rd_rn = bgp_route_next(rd_rn)) { table = bgp_node_get_bgp_table_info(rd_rn); if (!table) @@ -4157,14 +4158,14 @@ static void free_vni_entry(struct hash_bucket *bucket, struct bgp *bgp) */ static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf) { - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl); UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD); /* Map RT to VRF */ - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return; bgp_evpn_map_vrf_to_its_rts(bgp_vrf); } @@ -4196,12 +4197,12 @@ static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf) static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) { - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; struct listnode *node = NULL; struct bgpevpn *vpn = NULL; - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return; /* update all type-5 routes */ @@ -4209,7 +4210,7 @@ static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) /* update all type-2 routes */ for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) - update_routes_for_vni(bgp_def, vpn); + update_routes_for_vni(bgp_evpn, vpn); } /* @@ -5429,10 +5430,10 @@ static void link_l2vni_hash_to_l3vni(struct hash_bucket *bucket, struct bgp *bgp_vrf) { struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; - bgp_def = bgp_get_default(); - assert(bgp_def); + bgp_evpn = bgp_get_evpn(); + assert(bgp_evpn); if (vpn->tenant_vrf_id == bgp_vrf->vrf_id) bgpevpn_link_to_l3vni(vpn); @@ -5443,32 +5444,33 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, ifindex_t svi_ifindex) { struct bgp *bgp_vrf = NULL; /* bgp VRF instance */ - struct bgp *bgp_def = NULL; /* default bgp instance */ + struct bgp *bgp_evpn = NULL; /* EVPN bgp instance */ struct listnode *node = NULL; struct bgpevpn *vpn = NULL; as_t as = 0; - /* get the default instance - required to get the AS number for VRF + /* get the EVPN instance - required to get the AS number for VRF * auto-creatio */ - bgp_def = bgp_get_default(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err( EC_BGP_NO_DFLT, - "Cannot process L3VNI %u ADD - default BGP instance not yet created", + "Cannot process L3VNI %u ADD - EVPN BGP instance not yet created", l3vni); return -1; } - as = bgp_def->as; + as = bgp_evpn->as; /* if the BGP vrf instance doesn't exist - create one */ - bgp_vrf = bgp_lookup_by_name(vrf_id_to_name(vrf_id)); + bgp_vrf = bgp_lookup_by_vrf_id(vrf_id); if (!bgp_vrf) { int ret = 0; ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id), - BGP_INSTANCE_TYPE_VRF); + vrf_id == VRF_DEFAULT ? BGP_INSTANCE_TYPE_DEFAULT + : BGP_INSTANCE_TYPE_VRF); switch (ret) { case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET: flog_err(EC_BGP_MULTI_INSTANCE, @@ -5511,7 +5513,7 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf); /* link all corresponding l2vnis */ - hash_iterate(bgp_def->vnihash, + hash_iterate(bgp_evpn->vnihash, (void (*)(struct hash_bucket *, void *))link_l2vni_hash_to_l3vni, bgp_vrf); @@ -5521,7 +5523,7 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, */ if (!filter) for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) - update_routes_for_vni(bgp_def, vpn); + update_routes_for_vni(bgp_evpn, vpn); /* advertise type-5 routes if needed */ update_advertise_vrf_routes(bgp_vrf); @@ -5536,7 +5538,7 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) { struct bgp *bgp_vrf = NULL; /* bgp vrf instance */ - struct bgp *bgp_def = NULL; /* default bgp instance */ + struct bgp *bgp_evpn = NULL; /* EVPN bgp instance */ struct listnode *node = NULL; struct listnode *next = NULL; struct bgpevpn *vpn = NULL; @@ -5550,11 +5552,11 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) return -1; } - bgp_def = bgp_get_default(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err( EC_BGP_NO_DFLT, - "Cannot process L3VNI %u Del - Could not find default BGP instance", + "Cannot process L3VNI %u Del - Could not find EVPN BGP instance", l3vni); return -1; } @@ -5592,7 +5594,7 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) { for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) { UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); - update_routes_for_vni(bgp_def, vpn); + update_routes_for_vni(bgp_evpn, vpn); } } diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 22fb0939c9..f5802fa894 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -27,12 +27,13 @@ #define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */ #define EVPN_AUTORT_VXLAN 0x10000000 +#define EVPN_ENABLED(bgp) (bgp)->advertise_all_vni static inline int is_evpn_enabled(void) { struct bgp *bgp = NULL; - bgp = bgp_get_default(); - return bgp ? bgp->advertise_all_vni : 0; + bgp = bgp_get_evpn(); + return bgp ? EVPN_ENABLED(bgp) : 0; } static inline void vni2label(vni_t vni, mpls_label_t *label) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index ba72761003..0454fc2212 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1006,7 +1006,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, json_object *json_scode = NULL; json_object *json_ocode = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (bgp == NULL) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); @@ -1958,9 +1958,9 @@ static int evpn_delete_vni(struct bgp *bgp, struct bgpevpn *vpn) /* * Display import RT mapping to VRFs (vty handler) - * bgp_def: default bgp instance + * bgp_evpn: evpn bgp instance */ -static void evpn_show_vrf_import_rts(struct vty *vty, struct bgp *bgp_def, +static void evpn_show_vrf_import_rts(struct vty *vty, struct bgp *bgp_evpn, json_object *json) { void *args[2]; @@ -1968,7 +1968,7 @@ static void evpn_show_vrf_import_rts(struct vty *vty, struct bgp *bgp_def, args[0] = vty; args[1] = json; - hash_iterate(bgp_def->vrf_import_rt_hash, + hash_iterate(bgp_evpn->vrf_import_rt_hash, (void (*)(struct hash_bucket *, void *))show_vrf_import_rt_entry, args); @@ -2757,6 +2757,7 @@ static void evpn_unset_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn) static void evpn_set_advertise_all_vni(struct bgp *bgp) { bgp->advertise_all_vni = 1; + bgp_set_evpn(bgp); bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni); } @@ -2767,6 +2768,7 @@ static void evpn_set_advertise_all_vni(struct bgp *bgp) static void evpn_unset_advertise_all_vni(struct bgp *bgp) { bgp->advertise_all_vni = 0; + bgp_set_evpn(bgp_get_default()); bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni); bgp_evpn_cleanup_on_disable(bgp); } @@ -2915,9 +2917,9 @@ DEFUN (bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; } @@ -2937,9 +2939,9 @@ DEFUN (no_bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; } @@ -2954,9 +2956,18 @@ DEFUN (bgp_evpn_advertise_all_vni, "Advertise All local VNIs\n") { struct bgp *bgp = VTY_GET_CONTEXT(bgp); + struct bgp *bgp_evpn = NULL; if (!bgp) return CMD_WARNING; + + bgp_evpn = bgp_get_evpn(); + if (bgp_evpn && bgp_evpn != bgp) { + vty_out(vty, "%% Please unconfigure EVPN in VRF %s\n", + bgp_evpn->name); + return CMD_WARNING_CONFIG_FAILED; + } + evpn_set_advertise_all_vni(bgp); return CMD_SUCCESS; } @@ -3055,9 +3066,9 @@ DEFPY (dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; } @@ -3087,9 +3098,9 @@ DEFPY (dup_addr_detection_auto_recovery, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; } @@ -3122,9 +3133,9 @@ DEFPY (no_dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; } @@ -3194,9 +3205,9 @@ DEFPY(bgp_evpn_advertise_svi_ip, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -3441,7 +3452,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, "VNI number\n" JSON_STR) { - struct bgp *bgp_def; + struct bgp *bgp_evpn; vni_t vni; int idx = 0; bool uj = false; @@ -3454,8 +3465,8 @@ DEFUN(show_bgp_l2vpn_evpn_vni, uj = use_json(argc, argv); - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return CMD_WARNING; if (!argv_find(argv, argc, "evpn", &idx)) @@ -3466,7 +3477,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, if ((uj && argc == ((idx + 1) + 2)) || (!uj && argc == (idx + 1) + 1)) { - num_l2vnis = hashcount(bgp_def->vnihash); + num_l2vnis = hashcount(bgp_evpn->vnihash); for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp)) { if (bgp_temp->l3vni) @@ -3475,7 +3486,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, num_vnis = num_l2vnis + num_l3vnis; if (uj) { json_object_string_add(json, "advertiseGatewayMacip", - bgp_def->advertise_gw_macip + bgp_evpn->advertise_gw_macip ? "Enabled" : "Disabled"); json_object_string_add(json, "advertiseAllVnis", @@ -3483,7 +3494,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, : "Disabled"); json_object_string_add( json, "flooding", - bgp_def->vxlan_flood_ctrl + bgp_evpn->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL ? "Head-end replication" : "Disabled"); @@ -3492,22 +3503,22 @@ DEFUN(show_bgp_l2vpn_evpn_vni, json_object_int_add(json, "numL3Vnis", num_l3vnis); } else { vty_out(vty, "Advertise Gateway Macip: %s\n", - bgp_def->advertise_gw_macip ? "Enabled" + bgp_evpn->advertise_gw_macip ? "Enabled" : "Disabled"); vty_out(vty, "Advertise SVI Macip: %s\n", - bgp_def->evpn_info->advertise_svi_macip ? "Enabled" + bgp_evpn->evpn_info->advertise_svi_macip ? "Enabled" : "Disabled"); vty_out(vty, "Advertise All VNI flag: %s\n", is_evpn_enabled() ? "Enabled" : "Disabled"); vty_out(vty, "BUM flooding: %s\n", - bgp_def->vxlan_flood_ctrl + bgp_evpn->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL ? "Head-end replication" : "Disabled"); vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis); vty_out(vty, "Number of L3 VNIs: %u\n", num_l3vnis); } - evpn_show_all_vnis(vty, bgp_def, json); + evpn_show_all_vnis(vty, bgp_evpn, json); } else { int vni_idx = 0; @@ -3516,7 +3527,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, /* Display specific VNI */ vni = strtoul(argv[vni_idx + 1]->arg, NULL, 10); - evpn_show_vni(vty, bgp_def, vni, json); + evpn_show_vni(vty, bgp_evpn, vni, json); } if (uj) { @@ -3549,7 +3560,7 @@ DEFUN(show_bgp_l2vpn_evpn_es, memset(&esi, 0, sizeof(esi)); uj = use_json(argc, argv); - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3632,7 +3643,7 @@ DEFUN(show_bgp_l2vpn_evpn_route, uj = use_json(argc, argv); - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3693,7 +3704,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3769,7 +3780,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip, memset(&mac, 0, sizeof(struct ethaddr)); memset(&ip, 0, sizeof(struct ipaddr)); - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3833,7 +3844,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi, json_object *json = NULL; memset(&esi, 0, sizeof(esi)); - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3886,7 +3897,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -3958,7 +3969,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -4026,7 +4037,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -4082,7 +4093,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -4128,18 +4139,18 @@ DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt, JSON_STR) { bool uj = false; - struct bgp *bgp_def = NULL; + struct bgp *bgp_evpn = NULL; json_object *json = NULL; - bgp_def = bgp_get_default(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return CMD_WARNING; uj = use_json(argc, argv); if (uj) json = json_object_new_object(); - evpn_show_vrf_import_rts(vty, bgp_def, json); + evpn_show_vrf_import_rts(vty, bgp_evpn, json); if (uj) { vty_out(vty, "%s\n", json_object_to_json_string_ext( @@ -4167,7 +4178,7 @@ DEFUN(show_bgp_l2vpn_evpn_import_rt, bool uj = false; json_object *json = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) return CMD_WARNING; @@ -4198,9 +4209,9 @@ DEFUN(test_adv_evpn_type4_route, struct bgp *bgp; struct ipaddr vtep_ip; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) { - vty_out(vty, "%%Default BGP instance not yet created\n"); + vty_out(vty, "%%EVPN BGP instance not yet created\n"); return CMD_WARNING; } @@ -4232,9 +4243,9 @@ DEFUN(test_withdraw_evpn_type4_route, struct bgp *bgp; struct ipaddr vtep_ip; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); if (!bgp) { - vty_out(vty, "%%Default BGP instance not yet created\n"); + vty_out(vty, "%%EVPN BGP instance not yet created\n"); return CMD_WARNING; } @@ -4512,9 +4523,9 @@ DEFUN (bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4548,9 +4559,9 @@ DEFUN (no_bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4588,9 +4599,9 @@ DEFUN (no_bgp_evpn_vni_rd_without_val, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4917,9 +4928,9 @@ DEFUN (bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4985,9 +4996,9 @@ DEFUN (no_bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -5084,9 +5095,9 @@ DEFUN (no_bgp_evpn_vni_rt_without_val, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index ac579b1bf0..e42bc44115 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -171,7 +171,7 @@ void sigusr1(void) */ static __attribute__((__noreturn__)) void bgp_exit(int status) { - struct bgp *bgp, *bgp_default; + struct bgp *bgp, *bgp_default, *bgp_evpn; struct listnode *node, *nnode; /* it only makes sense for this to be called on a clean exit */ @@ -184,13 +184,16 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) bgp_close(); bgp_default = bgp_get_default(); + bgp_evpn = bgp_get_evpn(); /* reverse bgp_master_init */ for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { - if (bgp_default == bgp) + if (bgp_default == bgp || bgp_evpn == bgp) continue; bgp_delete(bgp); } + if (bgp_evpn && bgp_evpn != bgp_default) + bgp_delete(bgp_evpn); if (bgp_default) bgp_delete(bgp_default); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index d9749863ec..66fcbb3f3a 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1632,8 +1632,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, return CMD_WARNING; #if ENABLE_BGP_VNC - if (bgp->vrf_id == VRF_DEFAULT - && type == ZEBRA_ROUTE_VNC_DIRECT) { + if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) { vnc_export_bgp_enable( bgp, afi); /* only enables if mode bits cfg'd */ } @@ -1794,7 +1793,7 @@ int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type, * status. red lookup fails if there is no zebra connection. */ #if ENABLE_BGP_VNC - if (bgp->vrf_id == VRF_DEFAULT && type == ZEBRA_ROUTE_VNC_DIRECT) { + if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) { vnc_export_bgp_disable(bgp, afi); } #endif @@ -1880,9 +1879,8 @@ void bgp_zebra_instance_register(struct bgp *bgp) /* Register for router-id, interfaces, redistributed routes. */ zclient_send_reg_requests(zclient, bgp->vrf_id); - /* For default instance, register to learn about VNIs, if appropriate. - */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) + /* For EVPN instance, register to learn about VNIs, if appropriate. */ + if (bgp->advertise_all_vni) bgp_zebra_advertise_all_vni(bgp, 1); bgp_nht_register_nexthops(bgp); @@ -1900,9 +1898,8 @@ void bgp_zebra_instance_deregister(struct bgp *bgp) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Deregistering VRF %u", bgp->vrf_id); - /* For default instance, unregister learning about VNIs, if appropriate. - */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) + /* For EVPN instance, unregister learning about VNIs, if appropriate. */ + if (bgp->advertise_all_vni) bgp_zebra_advertise_all_vni(bgp, 0); /* Deregister for router-id, interfaces, redistributed routes. */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 298418b113..225f119908 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2885,6 +2885,12 @@ static struct bgp *bgp_create(as_t *as, const char *name, name, *as); } + /* Default the EVPN VRF to the default one */ + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) { + bgp_lock(bgp); + bm->bgp_evpn = bgp; + } + bgp_lock(bgp); bgp->heuristic_coalesce = true; bgp->inst_type = inst_type; @@ -3083,6 +3089,29 @@ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id) return (vrf->info) ? (struct bgp *)vrf->info : NULL; } +/* Sets the BGP instance where EVPN is enabled */ +void bgp_set_evpn(struct bgp *bgp) +{ + if (bm->bgp_evpn == bgp) + return; + + /* First, release the reference count we hold on the instance */ + if (bm->bgp_evpn) + bgp_unlock(bm->bgp_evpn); + + bm->bgp_evpn = bgp; + + /* Increase the reference count on this new VRF */ + if (bm->bgp_evpn) + bgp_lock(bm->bgp_evpn); +} + +/* Returns the BGP instance where EVPN is enabled, if any */ +struct bgp *bgp_get_evpn(void) +{ + return bm->bgp_evpn; +} + /* handle socket creation or deletion, if necessary * this is called for all new BGP instances */ @@ -3367,6 +3396,14 @@ int bgp_delete(struct bgp *bgp) if (vrf) bgp_vrf_unlink(bgp, vrf); + /* Update EVPN VRF pointer */ + if (bm->bgp_evpn == bgp) { + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) + bgp_set_evpn(NULL); + else + bgp_set_evpn(bgp_get_default()); + } + thread_master_free_unused(bm->master); bgp_unlock(bgp); /* initial reference */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 91666fb374..b0f6567534 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -153,6 +153,9 @@ struct bgp_master { /* dynamic mpls label allocation pool */ struct labelpool labelpool; + /* BGP-EVPN VRF ID. Defaults to default VRF (if any) */ + struct bgp* bgp_evpn; + bool terminating; /* global flag that sigint terminate seen */ QOBJ_FIELDS }; @@ -1512,6 +1515,8 @@ 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_vrf_id(vrf_id_t); +extern struct bgp *bgp_get_evpn(void); +extern void bgp_set_evpn(struct bgp *bgp); extern struct peer *peer_lookup(struct bgp *, union sockunion *); extern struct peer *peer_lookup_by_conf_if(struct bgp *, const char *); extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *); diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 61f2902233..72b5e9b9b1 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -108,6 +108,11 @@ struct zebra_router { /* Mlag information for the router */ struct zebra_mlag_info mlag_info; + + /* + * The EVPN instance, if any + */ + struct zebra_vrf *evpn_vrf; }; extern struct zebra_router zrouter; @@ -134,6 +139,16 @@ extern void zebra_router_show_table_summary(struct vty *vty); extern uint32_t zebra_router_get_next_sequence(void); +static inline vrf_id_t zebra_vrf_get_evpn_id(void) +{ + return zrouter.evpn_vrf ? zvrf_id(zrouter.evpn_vrf) : VRF_DEFAULT; +} +static inline struct zebra_vrf *zebra_vrf_get_evpn(void) +{ + return zrouter.evpn_vrf ? zrouter.evpn_vrf + : zebra_vrf_lookup_by_id(VRF_DEFAULT); +} + #ifdef __cplusplus } #endif diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 502fc343c5..524c175b79 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -111,18 +111,18 @@ struct zebra_vrf { #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) /* - * VNI hash table (for EVPN). Only in default instance. + * VNI hash table (for EVPN). Only in the EVPN instance. */ struct hash *vni_table; /* - * Whether EVPN is enabled or not. Only in default instance. + * Whether EVPN is enabled or not. Only in the EVPN instance. */ int advertise_all_vni; /* * Whether we are advertising g/w macip in EVPN or not. - * Only in default instance. + * Only in the EVPN instance. */ int advertise_gw_macip; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 97e841692b..ad61842005 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1608,7 +1608,7 @@ DEFUN (show_vrf, return CMD_SUCCESS; } -DEFUN_HIDDEN (default_vrf_vni_mapping, +DEFUN (default_vrf_vni_mapping, default_vrf_vni_mapping_cmd, "vni " CMD_VNI_RANGE "[prefix-routes-only]", "VNI corresponding to the DEFAULT VRF\n" @@ -1638,7 +1638,7 @@ DEFUN_HIDDEN (default_vrf_vni_mapping, return CMD_SUCCESS; } -DEFUN_HIDDEN (no_default_vrf_vni_mapping, +DEFUN (no_default_vrf_vni_mapping, no_default_vrf_vni_mapping_cmd, "no vni " CMD_VNI_RANGE, NO_STR @@ -1796,7 +1796,7 @@ DEFUN (show_evpn_vni, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_vnis(vty, zvrf, uj); return CMD_SUCCESS; } @@ -1812,7 +1812,7 @@ DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_vnis_detail(vty, zvrf, uj); return CMD_SUCCESS; } @@ -1831,7 +1831,7 @@ DEFUN (show_evpn_vni_vni, bool uj = use_json(argc, argv); vni = strtoul(argv[3]->arg, NULL, 10); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_vni(vty, zvrf, vni, uj); return CMD_SUCCESS; } @@ -1975,7 +1975,7 @@ DEFUN (show_evpn_mac_vni, bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj); return CMD_SUCCESS; } @@ -1993,7 +1993,7 @@ DEFUN (show_evpn_mac_vni_all, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj); return CMD_SUCCESS; } @@ -2011,7 +2011,7 @@ DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj); return CMD_SUCCESS; } @@ -2037,7 +2037,7 @@ DEFUN (show_evpn_mac_vni_all_vtep, vty_out(vty, "%% Malformed VTEP IP address\n"); return CMD_WARNING; } - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj); return CMD_SUCCESS; @@ -2067,7 +2067,7 @@ DEFUN (show_evpn_mac_vni_mac, vty_out(vty, "%% Malformed MAC address"); return CMD_WARNING; } - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj); return CMD_SUCCESS; } @@ -2096,7 +2096,7 @@ DEFUN (show_evpn_mac_vni_vtep, return CMD_WARNING; } - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj); return CMD_SUCCESS; } @@ -2115,7 +2115,7 @@ DEFPY (show_evpn_mac_vni_all_dad, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj); return CMD_SUCCESS; } @@ -2137,7 +2137,7 @@ DEFPY (show_evpn_mac_vni_dad, bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj); @@ -2160,7 +2160,7 @@ DEFPY (show_evpn_neigh_vni_dad, bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj); return CMD_SUCCESS; } @@ -2179,7 +2179,7 @@ DEFPY (show_evpn_neigh_vni_all_dad, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj); return CMD_SUCCESS; } @@ -2200,7 +2200,7 @@ DEFUN (show_evpn_neigh_vni, bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj); return CMD_SUCCESS; } @@ -2218,7 +2218,7 @@ DEFUN (show_evpn_neigh_vni_all, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj); return CMD_SUCCESS; } @@ -2235,7 +2235,7 @@ DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd, struct zebra_vrf *zvrf; bool uj = use_json(argc, argv); - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj); return CMD_SUCCESS; } @@ -2263,7 +2263,7 @@ DEFUN (show_evpn_neigh_vni_neigh, vty_out(vty, "%% Malformed Neighbor address\n"); return CMD_WARNING; } - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj); return CMD_SUCCESS; } @@ -2292,7 +2292,7 @@ DEFUN (show_evpn_neigh_vni_vtep, return CMD_WARNING; } - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj); return CMD_SUCCESS; } @@ -2357,7 +2357,7 @@ DEFPY (clear_evpn_dup_addr, struct ethaddr mac_addr; int ret = CMD_SUCCESS; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); if (vni_val) { vni = strtoul(vni_val, NULL, 10); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 0a6db1c99a..3a8426e772 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -324,7 +324,7 @@ static int advertise_gw_macip_enabled(zebra_vni_t *zvni) { struct zebra_vrf *zvrf; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); if (zvrf && zvrf->advertise_gw_macip) return 1; @@ -338,7 +338,7 @@ static int advertise_svi_macip_enabled(zebra_vni_t *zvni) { struct zebra_vrf *zvrf; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); if (zvrf && zvrf->advertise_svi_macip) return 1; @@ -707,11 +707,10 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct zebra_vrf *zvrf = NULL; struct timeval detect_start_time = {0, 0}; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); if (!zvrf) return; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); ipaddr2str(&n->ip, buf2, sizeof(buf2)); prefix_mac2str(&n->emac, buf1, sizeof(buf1)); type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? @@ -1155,7 +1154,9 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) struct zebra_vrf *zvrf; struct timeval detect_start_time = {0, 0}; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); + if (!zvrf) + return; vty = (struct vty *)ctxt; prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)); @@ -2079,7 +2080,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, s = stream_new(ZEBRA_MAX_PACKET_SIZ); - zclient_create_header(s, cmd, VRF_DEFAULT); + zclient_create_header(s, cmd, zebra_vrf_get_evpn_id()); stream_putl(s, vni); stream_put(s, macaddr->octet, ETH_ALEN); if (ip) { @@ -3832,7 +3833,7 @@ static zebra_vni_t *zvni_lookup(vni_t vni) zebra_vni_t tmp_vni; zebra_vni_t *zvni = NULL; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); assert(zvrf); memset(&tmp_vni, 0, sizeof(zebra_vni_t)); tmp_vni.vni = vni; @@ -3850,7 +3851,7 @@ static zebra_vni_t *zvni_add(vni_t vni) zebra_vni_t tmp_zvni; zebra_vni_t *zvni = NULL; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); assert(zvrf); memset(&tmp_zvni, 0, sizeof(zebra_vni_t)); tmp_zvni.vni = vni; @@ -3876,7 +3877,7 @@ static int zvni_del(zebra_vni_t *zvni) struct zebra_vrf *zvrf; zebra_vni_t *tmp_zvni; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); assert(zvrf); zvni->vxlan_if = NULL; @@ -3911,7 +3912,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni) s = stream_new(ZEBRA_MAX_PACKET_SIZ); - zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT); + zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id()); stream_putl(s, zvni->vni); stream_put_in_addr(s, &zvni->local_vtep_ip); stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */ @@ -3945,7 +3946,7 @@ static int zvni_send_del_to_client(vni_t vni) s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); - zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT); + zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id()); stream_putl(s, vni); /* Write packet size. */ @@ -6955,7 +6956,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) if (!is_evpn_enabled()) return; - zvrf = vrf_info_lookup(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); if (!zvrf) return; @@ -7797,9 +7798,9 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) return; } - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("Recv MACIP DEL for non-default VRF %u", - zvrf_id(zvrf)); + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("Recv MACIP DEL for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -7881,9 +7882,9 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) return; } - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("Recv MACIP ADD for non-default VRF %u", - zvrf_id(zvrf)); + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("Recv MACIP ADD for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8617,10 +8618,10 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, int add) { zebra_l3vni_t *zl3vni = NULL; - struct zebra_vrf *zvrf_default = NULL; + struct zebra_vrf *zvrf_evpn = NULL; - zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (!zvrf_default) + zvrf_evpn = zebra_vrf_get_evpn(); + if (!zvrf_evpn) return -1; if (IS_ZEBRA_DEBUG_VXLAN) @@ -8674,7 +8675,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); /* formulate l2vni list */ - hash_iterate(zvrf_default->vni_table, zvni_add_to_l3vni_list, + hash_iterate(zvrf_evpn->vni_table, zvni_add_to_l3vni_list, zl3vni); if (is_l3vni_oper_up(zl3vni)) @@ -8769,8 +8770,8 @@ void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS) struct stream *s; enum vxlan_flood_control flood_ctrl; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("EVPN flood control for non-default VRF %u", + if (!EVPN_ENABLED(zvrf)) { + zlog_err("EVPN flood control for non-EVPN VRF %u", zvrf_id(zvrf)); return; } @@ -8809,9 +8810,9 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS) zebra_vni_t *zvni = NULL; struct interface *ifp = NULL; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u", - zvrf_id(zvrf)); + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8908,9 +8909,9 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) struct zebra_l2info_vxlan zl2_info; struct interface *vlan_if = NULL; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u", - zvrf_id(zvrf)); + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8971,8 +8972,8 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) zebra_vni_t *zvni = NULL; struct interface *ifp = NULL; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u", + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); return; } @@ -9078,18 +9079,18 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) int advertise = 0; enum vxlan_flood_control flood_ctrl; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("EVPN VNI Adv for non-default VRF %u", - zvrf_id(zvrf)); + /* Mismatch between EVPN VRF and current VRF (should be prevented by + * bgpd's cli) */ + if (is_evpn_enabled() && !EVPN_ENABLED(zvrf)) return; - } s = msg; STREAM_GETC(s, advertise); STREAM_GETC(s, flood_ctrl); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("EVPN VNI Adv %s, currently %s, flood control %u", + zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u", + zvrf_name(zvrf), zvrf_id(zvrf), advertise ? "enabled" : "disabled", is_evpn_enabled() ? "enabled" : "disabled", flood_ctrl); @@ -9098,7 +9099,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) return; zvrf->advertise_all_vni = advertise; - if (is_evpn_enabled()) { + if (EVPN_ENABLED(zvrf)) { + zrouter.evpn_vrf = zvrf; + /* Note BUM handling */ zvrf->vxlan_flood_ctrl = flood_ctrl; @@ -9122,6 +9125,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) /* cleanup all l3vnis */ hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL); + + /* Mark as "no EVPN VRF" */ + zrouter.evpn_vrf = NULL; } stream_failure: @@ -9162,6 +9168,7 @@ void zebra_vxlan_init(void) { zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp, "Zebra VRF L3 VNI table"); + zrouter.evpn_vrf = NULL; } /* free l3vni table */ diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 206f65044a..2ff92970d7 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -25,6 +25,7 @@ #define _ZEBRA_VXLAN_H #include +#include #include "linklist.h" #include "if.h" @@ -44,14 +45,14 @@ extern "C" { static inline int is_evpn_enabled(void) { struct zebra_vrf *zvrf = NULL; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - return zvrf ? zvrf->advertise_all_vni : 0; + zvrf = zebra_vrf_get_evpn(); + return zvrf ? EVPN_ENABLED(zvrf) : 0; } static inline int is_vxlan_flooding_head_end(void) { - struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + struct zebra_vrf *zvrf = zebra_vrf_get_evpn(); if (!zvrf) return 0;