diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 182a6c64f2..7c87c9b3b3 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -2564,7 +2564,8 @@ struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni) * Create a new vpn - invoked upon configuration or zebra notification. */ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, - struct in_addr originator_ip) + struct in_addr originator_ip, + vrf_id_t tenant_vrf_id) { struct bgpevpn *vpn; @@ -2578,6 +2579,7 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, /* Set values - RD and RT set to defaults. */ vpn->vni = vni; vpn->originator_ip = originator_ip; + vpn->tenant_vrf_id = tenant_vrf_id; /* Initialize route-target import and export lists */ vpn->import_rtl = list_new(); @@ -2813,7 +2815,8 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni) * about is change to local-tunnel-ip. */ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, - struct in_addr originator_ip) + struct in_addr originator_ip, + vrf_id_t tenant_vrf_id) { struct bgpevpn *vpn; struct prefix_evpn p; @@ -2826,6 +2829,11 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, /* Lookup VNI. If present and no change, exit. */ vpn = bgp_evpn_lookup_vni(bgp, vni); if (vpn) { + + /* update tenant_vrf_id if required */ + if (vpn->tenant_vrf_id != tenant_vrf_id) + vpn->tenant_vrf_id = tenant_vrf_id; + if (is_vni_live(vpn) && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)) /* Probably some other param has changed that we don't @@ -2838,7 +2846,7 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, /* Create or update as appropriate. */ if (!vpn) { - vpn = bgp_evpn_new(bgp, vni, originator_ip); + vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id); if (!vpn) { zlog_err( "%u: Failed to allocate VNI entry for VNI %u - at Add", diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 985f41f586..829dbfa4e1 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -47,7 +47,8 @@ extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, u_char flags); extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni); extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, - struct in_addr originator_ip); + struct in_addr originator_ip, + vrf_id_t tenant_vrf_id); extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp); extern void bgp_evpn_cleanup(struct bgp *bgp); extern void bgp_evpn_init(struct bgp *bgp); diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index a58f73f4bc..2a3e98ce4f 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -53,6 +53,7 @@ typedef enum { */ struct bgpevpn { vni_t vni; + vrf_id_t tenant_vrf_id; u_int32_t flags; #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */ #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */ @@ -213,6 +214,7 @@ extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn); extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni); extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, - struct in_addr originator_ip); + struct in_addr originator_ip, + vrf_id_t tenant_vrf_id); extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn); #endif /* _BGP_EVPN_PRIVATE_H */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index f473b4604a..91d54d78e6 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -252,6 +252,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) vty_out(vty, " (known to the kernel)"); vty_out(vty, "\n"); + vty_out(vty, " Tenant-Vrf: %s\n", + vrf_id_to_name(vpn->tenant_vrf_id)); vty_out(vty, " RD: %s\n", prefix_rd2str(&vpn->prd, buf1, sizeof(buf1))); vty_out(vty, " Originator IP: %s\n", @@ -448,9 +450,10 @@ static void show_vni_entry(struct hash_backet *backet, void *args[]) json_vni, "rd", prefix_rd2str(&vpn->prd, buf2, sizeof(buf2))); } else { - vty_out(vty, "%-1s %-10u %-15s %-21s", buf1, vpn->vni, + vty_out(vty, "%-1s %-10u %-15s %-37s %-21s", buf1, vpn->vni, inet_ntoa(vpn->originator_ip), - prefix_rd2str(&vpn->prd, buf2, sizeof(buf2))); + vrf_id_to_name(vpn->tenant_vrf_id), + prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN)); } for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) { @@ -1403,7 +1406,9 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) vpn = bgp_evpn_lookup_vni(bgp, vni); if (!vpn) { - vpn = bgp_evpn_new(bgp, vni, bgp->router_id); + /* tenant vrf will be updated when we get local_vni_add from + * zebra */ + vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0); if (!vpn) { zlog_err( "%u: Failed to allocate VNI entry for VNI %u - at Config", @@ -2014,8 +2019,9 @@ static void evpn_show_all_vnis(struct vty *vty, struct bgp *bgp, } else { vty_out(vty, "Number of VNIs: %u\n", num_vnis); vty_out(vty, "Flags: * - Kernel\n"); - vty_out(vty, " %-10s %-15s %-21s %-25s %-25s\n", "VNI", - "Orig IP", "RD", "Import RT", "Export RT"); + vty_out(vty, " %-10s %-15s %-37s %-21s %-25s %-25s\n", "VNI", + "Orig IP", "Tenant-Vrf", "RD", "Import RT", + "Export RT"); } args[0] = vty; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 1cf04abfce..bd5312ad46 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1682,23 +1682,29 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient, vni_t vni; struct bgp *bgp; struct in_addr vtep_ip; + vrf_id_t tenant_vrf_id = VRF_DEFAULT; s = zclient->ibuf; vni = stream_getl(s); - if (command == ZEBRA_VNI_ADD) + if (command == ZEBRA_VNI_ADD) { vtep_ip.s_addr = stream_get_ipv4(s); + stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t)); + } + bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) return 0; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx VNI %s VRF %u VNI %u", - (command == ZEBRA_VNI_ADD) ? "add" : "del", vrf_id, - vni); + zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s", + (command == ZEBRA_VNI_ADD) ? "add" : "del", + vrf_id_to_name(vrf_id), + vni, vrf_id_to_name(tenant_vrf_id)); if (command == ZEBRA_VNI_ADD) return bgp_evpn_local_vni_add( - bgp, vni, vtep_ip.s_addr ? vtep_ip : bgp->router_id); + bgp, vni, vtep_ip.s_addr ? vtep_ip : bgp->router_id, + tenant_vrf_id); else return bgp_evpn_local_vni_del(bgp, vni); }