From e2f3a930c54c13c3174d6641fe4e6ee159966bd1 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:09:25 +0100 Subject: [PATCH 01/16] bgpd: Allow non-default instance to be EVPN one This makes the instance bearing the advertise-all-vni config option register to zebra as the EVPN one, forwarding it the option. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.h | 2 +- bgpd/bgp_evpn_vty.c | 11 +++++++++++ bgpd/bgp_main.c | 7 +++++-- bgpd/bgp_zebra.c | 14 ++++++-------- bgpd/bgpd.c | 37 +++++++++++++++++++++++++++++++++++++ bgpd/bgpd.h | 5 +++++ 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index fbf30083e1..bcc524d5aa 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -31,7 +31,7 @@ static inline int is_evpn_enabled(void) { struct bgp *bgp = NULL; - bgp = bgp_get_default(); + bgp = bgp_get_evpn(); return bgp ? bgp->advertise_all_vni : 0; } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 8437c4024e..9ac1af046a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -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); } @@ -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; } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 47e7c1686f..697889cc6b 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 5f0b20e029..398735d7a4 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1632,7 +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 + if (bgp->advertise_all_vni && type == ZEBRA_ROUTE_VNC_DIRECT) { vnc_export_bgp_enable( bgp, afi); /* only enables if mode bits cfg'd */ @@ -1794,7 +1794,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 (bgp->advertise_all_vni && type == ZEBRA_ROUTE_VNC_DIRECT) { vnc_export_bgp_disable(bgp, afi); } #endif @@ -1861,9 +1861,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); @@ -1881,9 +1880,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 d99b402e28..8fcf417b3a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2872,6 +2872,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; @@ -3070,6 +3076,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 */ @@ -3354,6 +3383,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 c7d137c76c..f9c269e3e6 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -150,6 +150,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 }; @@ -1506,6 +1509,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 *); From 150971b5ecc3416496a2ffaf2a35c108c970553c Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Tue, 19 Feb 2019 20:37:59 +0000 Subject: [PATCH 02/16] zebra: Store the EVPN VRF in the default VRF The EVPN VRF is defined by bgpd, and is the one vrf where `advertise-all-vni` is present. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vrf.h | 22 +++++++++++++++++++--- zebra/zebra_vxlan.c | 19 ++++++++++++------- zebra/zebra_vxlan.h | 2 +- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index e35101d833..3574f4b67c 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -107,23 +107,28 @@ 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; int advertise_svi_macip; + /* + * The EVPN instance, if any + */ + vrf_id_t evpn_vrf_id; + /* l3-vni info */ vni_t l3vni; @@ -196,6 +201,17 @@ extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *); extern struct zebra_vrf *zebra_vrf_alloc(void); extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); +static inline vrf_id_t zebra_vrf_get_evpn_id(void) +{ + struct zebra_vrf *zvrf = NULL; + zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + return zvrf ? zvrf->evpn_vrf_id : VRF_DEFAULT; +} +static inline struct zebra_vrf *zebra_vrf_get_evpn(void) +{ + return zebra_vrf_lookup_by_id(zebra_vrf_get_evpn_id()); +} + extern struct route_table * zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, vrf_id_t vrf_id); extern int zebra_vrf_has_config(struct zebra_vrf *zvrf); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 9a7d20bc49..fe7391f740 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; @@ -9041,19 +9041,19 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) struct stream *s = NULL; int advertise = 0; enum vxlan_flood_control flood_ctrl; + struct zebra_vrf *zvrf_default = NULL; - if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_debug("EVPN VNI Adv for non-default VRF %u", - zvrf_id(zvrf)); + zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT); + if (!zvrf_default) 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); @@ -9062,7 +9062,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) return; zvrf->advertise_all_vni = advertise; - if (is_evpn_enabled()) { + if (zvrf->advertise_all_vni) { + zvrf_default->evpn_vrf_id = zvrf_id(zvrf); + /* Note BUM handling */ zvrf->vxlan_flood_ctrl = flood_ctrl; @@ -9086,6 +9088,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) /* cleanup all l3vnis */ hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL); + + /* Fallback to the default VRF. */ + zvrf_default->evpn_vrf_id = VRF_DEFAULT; } stream_failure: diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 2cf21ff90b..38fef4b988 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -40,7 +40,7 @@ static inline int is_evpn_enabled(void) { struct zebra_vrf *zvrf = NULL; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + zvrf = zebra_vrf_get_evpn(); return zvrf ? zvrf->advertise_all_vni : 0; } From 530db8dc0398fabe8a88a2c614e14a1f3ccc1ba4 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:15:10 +0100 Subject: [PATCH 03/16] bgpd, zebra: Scope EVPN commands to EVPN VRF If the EVPN VRF is not the default one (i.e. with advertise-all-vni), this allows showing its information with `show bgp l2evpn evpn ...` commands. They do not require adding `vrf VRFNAME` since we only support a single EVPN VRF. The same is true for zebra-specific commands (e.g. `show evpn ...`). Configuration commands are not restricted to the default VRF but to the EVPN one, that is to the one bearing `advertise-all-vni`. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn_vty.c | 82 ++++++++++++++++++++++----------------------- zebra/zebra_vty.c | 38 ++++++++++----------- zebra/zebra_vxlan.c | 8 ++--- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 9ac1af046a..7f74ad48f2 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"); @@ -2917,9 +2917,9 @@ DEFUN (bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { 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; } @@ -2939,9 +2939,9 @@ DEFUN (no_bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { 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; } @@ -3066,9 +3066,9 @@ DEFPY (dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!bgp_vrf->advertise_all_vni) { 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; } @@ -3098,9 +3098,9 @@ DEFPY (dup_addr_detection_auto_recovery, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!bgp_vrf->advertise_all_vni) { 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; } @@ -3133,9 +3133,9 @@ DEFPY (no_dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (bgp_vrf->vrf_id != VRF_DEFAULT) { + if (!bgp_vrf->advertise_all_vni) { 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; } @@ -3205,9 +3205,9 @@ DEFPY(bgp_evpn_advertise_svi_ip, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -3464,7 +3464,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, uj = use_json(argc, argv); - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return CMD_WARNING; @@ -3559,7 +3559,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; @@ -3642,7 +3642,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; @@ -3703,7 +3703,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; @@ -3779,7 +3779,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; @@ -3843,7 +3843,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; @@ -3896,7 +3896,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; @@ -3968,7 +3968,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; @@ -4036,7 +4036,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; @@ -4092,7 +4092,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; @@ -4141,7 +4141,7 @@ DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt, struct bgp *bgp_def = NULL; json_object *json = NULL; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return CMD_WARNING; @@ -4177,7 +4177,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; @@ -4208,9 +4208,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; } @@ -4242,9 +4242,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; } @@ -4522,9 +4522,9 @@ DEFUN (bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4558,9 +4558,9 @@ DEFUN (no_bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4598,9 +4598,9 @@ DEFUN (no_bgp_evpn_vni_rd_without_val, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4927,9 +4927,9 @@ DEFUN (bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -4995,9 +4995,9 @@ DEFUN (no_bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { vty_out(vty, - "This command is only supported under Default VRF\n"); + "This command is only supported under EVPN VRF\n"); return CMD_WARNING; } @@ -5094,9 +5094,9 @@ DEFUN (no_bgp_evpn_vni_rt_without_val, if (!bgp) return CMD_WARNING; - if (bgp->vrf_id != VRF_DEFAULT) { + if (!bgp->advertise_all_vni) { 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/zebra/zebra_vty.c b/zebra/zebra_vty.c index 537820f7ea..b88a05afa4 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1797,7 +1797,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; } @@ -1813,7 +1813,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; } @@ -1832,7 +1832,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; } @@ -1976,7 +1976,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; } @@ -1994,7 +1994,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; } @@ -2012,7 +2012,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; } @@ -2038,7 +2038,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; @@ -2068,7 +2068,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; } @@ -2097,7 +2097,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; } @@ -2116,7 +2116,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; } @@ -2138,7 +2138,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); @@ -2161,7 +2161,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; } @@ -2180,7 +2180,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; } @@ -2201,7 +2201,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; } @@ -2219,7 +2219,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; } @@ -2236,7 +2236,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; } @@ -2264,7 +2264,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; } @@ -2293,7 +2293,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; } @@ -2358,7 +2358,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 fe7391f740..4debf5f2dc 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3801,7 +3801,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; @@ -3819,7 +3819,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; @@ -3845,7 +3845,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; @@ -6924,7 +6924,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; From 8f2ff1b5b0d23c57941c3ba4933b14863bec7545 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Mon, 4 Mar 2019 11:44:19 +0100 Subject: [PATCH 04/16] zebra/vty: Don't hide VNI config for default VRF Since the EVPN session and underlay can be in a non-default VRF, the default VRF can be an overlay VRF. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index b88a05afa4..899ba21171 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1609,7 +1609,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" @@ -1639,7 +1639,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 From 43779a1127ca4a97b538edbf4d90f57665aa23e3 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Tue, 19 Feb 2019 20:45:38 +0000 Subject: [PATCH 05/16] zebra/vxlan: Send type-2/3 to EVPN BGP instance This sends local VNIs and local MAC addresses to the BGP instance responsible for EVPN rather than the default one. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vxlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 4debf5f2dc..d4bae6d133 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -2076,7 +2076,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) { @@ -3880,7 +3880,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 */ @@ -3914,7 +3914,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. */ From cffe977c32cd9f73f00f43d9f0627e9c6813e259 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:19:42 +0100 Subject: [PATCH 06/16] bgpd/evpn: Send type-5 to EVPN BGP instance This sends local routes in overlay VRFs to the EPVN VRF when redistribute configurations are present, rather than to the default VRF. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 84f3649758..6c1da4f924 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1504,7 +1504,7 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, struct bgp *bgp_def = NULL; int route_changed = 0; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return 0; @@ -1926,7 +1926,7 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) struct bgp_path_info *pi = NULL; struct bgp *bgp_def = NULL; /* default bgp instance */ - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return 0; From 2118e6a9b4e875214fed275f628d4fa410d6f784 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:21:32 +0100 Subject: [PATCH 07/16] zebra/vxlan: Associate L3VNIs to EVPN VRF This uses the EPVN VRF to store L3VNIs hashes, and looks up L2VNIs in this VRF as they are stored there. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index d4bae6d133..bf12422466 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -8583,7 +8583,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, zebra_l3vni_t *zl3vni = NULL; struct zebra_vrf *zvrf_default = NULL; - zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT); + zvrf_default = zebra_vrf_get_evpn(); if (!zvrf_default) return -1; From a0b0b5c86603f863d46597779b10dc08777e2ac2 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Thu, 21 Feb 2019 18:08:36 +0100 Subject: [PATCH 08/16] zebra/vxlan: Filter zapi messages with EVPN VRF Since the EVPN VRF may not be the default one, compare received messages' VRF agains the EVPN VRF and not the Default. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vxlan.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index bf12422466..33e4655a1d 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -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; @@ -7761,9 +7761,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_debug("Recv MACIP DEL for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -7845,9 +7845,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_debug("Recv MACIP ADD for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8733,8 +8733,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_err("EVPN flood control for non-EVPN VRF %u", zvrf_id(zvrf)); return; } @@ -8773,9 +8773,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8872,9 +8872,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -8935,8 +8935,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 (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); return; } From 3621ebc54be4f69d635a39f53d8962f25f763f21 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:30:00 +0100 Subject: [PATCH 09/16] bgpd/evpn: Associate L2VNIs to L3VNI in EVPN VRF This change stores the mapping in the hash table of the EVPN VRF rather than the one of the default VRF. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 6c1da4f924..5e957e26cd 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5379,7 +5379,7 @@ static void link_l2vni_hash_to_l3vni(struct hash_bucket *bucket, struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; struct bgp *bgp_def = NULL; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); assert(bgp_def); if (vpn->tenant_vrf_id == bgp_vrf->vrf_id) @@ -5396,27 +5396,28 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, 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(); + bgp_def = bgp_get_evpn(); if (!bgp_def) { 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; /* 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, @@ -5498,11 +5499,11 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) return -1; } - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) { 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; } From f9b8094e3b2e608cc926e94eea443b406b60791b Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:35:03 +0100 Subject: [PATCH 10/16] bgpd/evpn: Compute {im,ex}port RT from EVPN VRF For default RT, this uses the correct ASN to derive the RT (ASN of the EVPN VRF). It also stores them in the EVPN VRF's hash tables rather than in the default's one. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 5e957e26cd..caba9647da 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -168,17 +168,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 vrf_irt_node *irt; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) { 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; } @@ -204,10 +204,10 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) { struct bgp *bgp_def = NULL; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) { 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; } @@ -226,10 +226,11 @@ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) struct vrf_irt_node *irt; struct vrf_irt_node tmp; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) { - flog_err(EC_BGP_NO_DFLT, - "vrf import rt lookup - def instance not created yet"); + flog_err( + EC_BGP_NO_DFLT, + "vrf import rt lookup - evpn instance not created yet"); return NULL; } @@ -2956,7 +2957,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) afi = AFI_L2VPN; safi = SAFI_EVPN; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return -1; @@ -4117,7 +4118,7 @@ static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf) UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD); /* Map RT to VRF */ - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return; bgp_evpn_map_vrf_to_its_rts(bgp_vrf); @@ -4154,7 +4155,7 @@ static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) struct listnode *node = NULL; struct bgpevpn *vpn = NULL; - bgp_def = bgp_get_default(); + bgp_def = bgp_get_evpn(); if (!bgp_def) return; From 5e53dce31eff6dbc1455cdd22a5ce006cbaa8c4a Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 6 Mar 2019 19:10:02 +0100 Subject: [PATCH 11/16] bgpd, zebra: Rename variables of EVPN instance Rename {bgp,zvrf}_def{ault} to {bgp,zvrf}_evpn where it makes sense, i.e. when they contain the EVPN instance. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.c | 102 ++++++++++++++++++++++---------------------- bgpd/bgp_evpn_vty.c | 36 ++++++++-------- zebra/zebra_vxlan.c | 8 ++-- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index caba9647da..ca13ee951e 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -172,11 +172,11 @@ static bool vrf_import_rt_hash_cmp(const void *p1, const void *p2) */ 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_evpn(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err(EC_BGP_NO_DFLT, "vrf import rt new - evpn instance not created yet"); return NULL; @@ -189,7 +189,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; } @@ -202,16 +202,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_evpn(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err(EC_BGP_NO_DFLT, "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); } @@ -222,12 +222,12 @@ 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_evpn(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err( EC_BGP_NO_DFLT, "vrf import rt lookup - evpn instance not created yet"); @@ -236,7 +236,7 @@ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) 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 +1421,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 +1436,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 +1456,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 +1502,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_evpn(); - 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 +1528,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 +1925,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_evpn(); - 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; } @@ -2953,19 +2953,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_evpn(); - 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) @@ -4112,14 +4112,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_evpn(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return; bgp_evpn_map_vrf_to_its_rts(bgp_vrf); } @@ -4151,12 +4151,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_evpn(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return; /* update all type-5 routes */ @@ -4164,7 +4164,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); } /* @@ -5378,10 +5378,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_evpn(); - 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); @@ -5392,7 +5392,7 @@ 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; @@ -5400,15 +5400,15 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, /* get the EVPN instance - required to get the AS number for VRF * auto-creatio */ - bgp_def = bgp_get_evpn(); - if (!bgp_def) { + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) { flog_err( EC_BGP_NO_DFLT, "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_vrf_id(vrf_id); @@ -5461,7 +5461,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); @@ -5471,7 +5471,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); @@ -5486,7 +5486,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; @@ -5500,8 +5500,8 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) return -1; } - bgp_def = bgp_get_evpn(); - 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 EVPN BGP instance", @@ -5542,7 +5542,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_vty.c b/bgpd/bgp_evpn_vty.c index 7f74ad48f2..08f487e497 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -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); @@ -3451,7 +3451,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; @@ -3464,8 +3464,8 @@ DEFUN(show_bgp_l2vpn_evpn_vni, uj = use_json(argc, argv); - bgp_def = bgp_get_evpn(); - if (!bgp_def) + bgp_evpn = bgp_get_evpn(); + if (!bgp_evpn) return CMD_WARNING; if (!argv_find(argv, argc, "evpn", &idx)) @@ -3476,7 +3476,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) @@ -3485,7 +3485,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", @@ -3493,7 +3493,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"); @@ -3502,22 +3502,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; @@ -3526,7 +3526,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) { @@ -4138,18 +4138,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_evpn(); - 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( diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 33e4655a1d..9b7eadf728 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -8581,10 +8581,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_get_evpn(); - if (!zvrf_default) + zvrf_evpn = zebra_vrf_get_evpn(); + if (!zvrf_evpn) return -1; if (IS_ZEBRA_DEBUG_VXLAN) @@ -8638,7 +8638,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)) From cff8f33b613757461e43d7aad938446647982f96 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Fri, 22 Mar 2019 11:08:01 +0100 Subject: [PATCH 12/16] zebra: Lookup dad and replication settings from EVPN VRF Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vxlan.c | 7 ++++--- zebra/zebra_vxlan.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 9b7eadf728..88a4375238 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -704,11 +704,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) ? @@ -1152,7 +1151,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)); diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 38fef4b988..6ca33ae159 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -47,7 +47,7 @@ static inline int is_evpn_enabled(void) 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; From 77b998fbf070aa7a2363f48d13fde8e2505db813 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Fri, 22 Mar 2019 11:18:31 +0100 Subject: [PATCH 13/16] zebra: Fixes following srimohans' advice Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vrf.h | 4 +--- zebra/zebra_vxlan.c | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 3574f4b67c..115d2b9d01 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -203,9 +203,7 @@ extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); static inline vrf_id_t zebra_vrf_get_evpn_id(void) { - struct zebra_vrf *zvrf = NULL; - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - return zvrf ? zvrf->evpn_vrf_id : VRF_DEFAULT; + return zebra_vrf_lookup_by_id(VRF_DEFAULT)->evpn_vrf_id; } static inline struct zebra_vrf *zebra_vrf_get_evpn(void) { diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 88a4375238..0ceaed8d24 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -9045,7 +9045,10 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) struct zebra_vrf *zvrf_default = NULL; zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (!zvrf_default) + + /* Mismatch between EVPN VRF and current VRF (should be prevented by + * bgpd's cli) */ + if (is_evpn_enabled() && !zvrf->advertise_all_vni) return; s = msg; From f920dd6dc967f0d5c984387628b572d16431f38a Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Fri, 22 Mar 2019 13:37:06 +0100 Subject: [PATCH 14/16] bgpd, zebra: Redo checks to advertise_all_vni This replaces manual checks of the flag with a wrapper macro to convey the meaning "is evpn enabled on this vrf?" Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- bgpd/bgp_evpn.h | 3 ++- bgpd/bgp_evpn_vty.c | 24 ++++++++++++------------ bgpd/bgp_zebra.c | 5 ++--- zebra/zebra_vxlan.c | 4 ++-- zebra/zebra_vxlan.h | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index bcc524d5aa..7f88c1ebf0 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_evpn(); - return bgp ? bgp->advertise_all_vni : 0; + 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 08f487e497..f020483ebb 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2917,7 +2917,7 @@ DEFUN (bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; @@ -2939,7 +2939,7 @@ DEFUN (no_bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; @@ -3066,7 +3066,7 @@ DEFPY (dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (!bgp_vrf->advertise_all_vni) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; @@ -3098,7 +3098,7 @@ DEFPY (dup_addr_detection_auto_recovery, if (!bgp_vrf) return CMD_WARNING; - if (!bgp_vrf->advertise_all_vni) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; @@ -3133,7 +3133,7 @@ DEFPY (no_dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; - if (!bgp_vrf->advertise_all_vni) { + if (!EVPN_ENABLED(bgp_vrf)) { vty_out(vty, "This command is only supported under the EVPN VRF\n"); return CMD_WARNING; @@ -3205,7 +3205,7 @@ DEFPY(bgp_evpn_advertise_svi_ip, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -4522,7 +4522,7 @@ DEFUN (bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -4558,7 +4558,7 @@ DEFUN (no_bgp_evpn_vni_rd, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -4598,7 +4598,7 @@ DEFUN (no_bgp_evpn_vni_rd_without_val, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -4927,7 +4927,7 @@ DEFUN (bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -4995,7 +4995,7 @@ DEFUN (no_bgp_evpn_vni_rt, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; @@ -5094,7 +5094,7 @@ DEFUN (no_bgp_evpn_vni_rt_without_val, if (!bgp) return CMD_WARNING; - if (!bgp->advertise_all_vni) { + if (!EVPN_ENABLED(bgp)) { vty_out(vty, "This command is only supported under EVPN VRF\n"); return CMD_WARNING; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 398735d7a4..0c77f63335 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->advertise_all_vni - && 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->advertise_all_vni && type == ZEBRA_ROUTE_VNC_DIRECT) { + if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) { vnc_export_bgp_disable(bgp, afi); } #endif diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 0ceaed8d24..2934a2ecd5 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -9048,7 +9048,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) /* Mismatch between EVPN VRF and current VRF (should be prevented by * bgpd's cli) */ - if (is_evpn_enabled() && !zvrf->advertise_all_vni) + if (is_evpn_enabled() && !EVPN_ENABLED(zvrf)) return; s = msg; @@ -9066,7 +9066,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) return; zvrf->advertise_all_vni = advertise; - if (zvrf->advertise_all_vni) { + if (EVPN_ENABLED(zvrf)) { zvrf_default->evpn_vrf_id = zvrf_id(zvrf); /* Note BUM handling */ diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 6ca33ae159..46165cf4da 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -41,7 +41,7 @@ static inline int is_evpn_enabled(void) { struct zebra_vrf *zvrf = NULL; zvrf = zebra_vrf_get_evpn(); - return zvrf ? zvrf->advertise_all_vni : 0; + return zvrf ? EVPN_ENABLED(zvrf) : 0; } static inline int From 986512a3200bfc83f80b9f559917ece4f123e4a4 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 27 Mar 2019 02:13:16 +0100 Subject: [PATCH 15/16] zebra: Change checks for EVPN VRF to a macro A lot of checks relied on the VRF ID and the EVPN VRF ID to be the same. This patch changes those checks to the EVPN_ENABLED macro, which checks if the VRF is the EVPN one. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_vxlan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 2934a2ecd5..c7a5e1ad86 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -7762,7 +7762,7 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) return; } - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_debug("Recv MACIP DEL for non-EVPN VRF %u", zvrf_id(zvrf)); return; @@ -7846,7 +7846,7 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) return; } - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_debug("Recv MACIP ADD for non-EVPN VRF %u", zvrf_id(zvrf)); return; @@ -8734,7 +8734,7 @@ void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS) struct stream *s; enum vxlan_flood_control flood_ctrl; - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_err("EVPN flood control for non-EVPN VRF %u", zvrf_id(zvrf)); return; @@ -8774,7 +8774,7 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS) zebra_vni_t *zvni = NULL; struct interface *ifp = NULL; - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); return; @@ -8873,7 +8873,7 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) struct zebra_l2info_vxlan zl2_info; struct interface *vlan_if = NULL; - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); return; @@ -8936,7 +8936,7 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) zebra_vni_t *zvni = NULL; struct interface *ifp = NULL; - if (zvrf_id(zvrf) != zebra_vrf_get_evpn_id()) { + if (!EVPN_ENABLED(zvrf)) { zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); return; From 0fb2ad05d9e11a211915208e3fa648c8e170e31e Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Wed, 27 Mar 2019 02:16:27 +0100 Subject: [PATCH 16/16] zebra: Move the EVPN VRF pointer to zebra_router It had no logical reason to be in the default VRF. This moves it to the zebra_router, which is better suited to store global references. Signed-off-by: Tuetuopay Sponsored-by: Scaleway --- zebra/zebra_router.h | 15 +++++++++++++++ zebra/zebra_vrf.h | 14 -------------- zebra/zebra_vxlan.c | 10 ++++------ zebra/zebra_vxlan.h | 1 + 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index fb28495917..a60a0b7be9 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -104,6 +104,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; @@ -127,4 +132,14 @@ extern void zebra_router_sweep_route(void); 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); +} #endif diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 115d2b9d01..f6566d02ac 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -124,11 +124,6 @@ struct zebra_vrf { int advertise_svi_macip; - /* - * The EVPN instance, if any - */ - vrf_id_t evpn_vrf_id; - /* l3-vni info */ vni_t l3vni; @@ -201,15 +196,6 @@ extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *); extern struct zebra_vrf *zebra_vrf_alloc(void); extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); -static inline vrf_id_t zebra_vrf_get_evpn_id(void) -{ - return zebra_vrf_lookup_by_id(VRF_DEFAULT)->evpn_vrf_id; -} -static inline struct zebra_vrf *zebra_vrf_get_evpn(void) -{ - return zebra_vrf_lookup_by_id(zebra_vrf_get_evpn_id()); -} - extern struct route_table * zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, vrf_id_t vrf_id); extern int zebra_vrf_has_config(struct zebra_vrf *zvrf); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index c7a5e1ad86..70c5aa7c8a 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -9042,9 +9042,6 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) struct stream *s = NULL; int advertise = 0; enum vxlan_flood_control flood_ctrl; - struct zebra_vrf *zvrf_default = NULL; - - zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT); /* Mismatch between EVPN VRF and current VRF (should be prevented by * bgpd's cli) */ @@ -9067,7 +9064,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) zvrf->advertise_all_vni = advertise; if (EVPN_ENABLED(zvrf)) { - zvrf_default->evpn_vrf_id = zvrf_id(zvrf); + zrouter.evpn_vrf = zvrf; /* Note BUM handling */ zvrf->vxlan_flood_ctrl = flood_ctrl; @@ -9093,8 +9090,8 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) /* cleanup all l3vnis */ hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL); - /* Fallback to the default VRF. */ - zvrf_default->evpn_vrf_id = VRF_DEFAULT; + /* Mark as "no EVPN VRF" */ + zrouter.evpn_vrf = NULL; } stream_failure: @@ -9135,6 +9132,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 46165cf4da..409f1c3f7f 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"