diff options
-rw-r--r-- | bgpd/bgp_evpn.c | 16 | ||||
-rw-r--r-- | bgpd/bgp_evpn.h | 3 | ||||
-rw-r--r-- | bgpd/bgp_evpn_private.h | 4 | ||||
-rw-r--r-- | bgpd/bgp_evpn_vty.c | 7 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 13 | ||||
-rw-r--r-- | zebra/zebra_evpn.c | 26 | ||||
-rw-r--r-- | zebra/zebra_evpn.h | 3 | ||||
-rw-r--r-- | zebra/zebra_vxlan.c | 12 |
8 files changed, 67 insertions, 17 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index d00a882c1..6fb704529 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5230,7 +5230,8 @@ struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni) struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, struct in_addr originator_ip, vrf_id_t tenant_vrf_id, - struct in_addr mcast_grp) + struct in_addr mcast_grp, + ifindex_t svi_ifindex) { struct bgpevpn *vpn; @@ -5244,6 +5245,7 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, vpn->originator_ip = originator_ip; vpn->tenant_vrf_id = tenant_vrf_id; vpn->mcast_grp = mcast_grp; + vpn->svi_ifindex = svi_ifindex; /* Initialize route-target import and export lists */ vpn->import_rtl = list_new(); @@ -5699,6 +5701,7 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni) */ delete_routes_for_vni(bgp, vpn); + vpn->svi_ifindex = 0; /* * tunnel is no longer active, del tunnel ip address from tip_hash */ @@ -5719,8 +5722,8 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni) int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, struct in_addr originator_ip, vrf_id_t tenant_vrf_id, - struct in_addr mcast_grp) - + struct in_addr mcast_grp, + ifindex_t svi_ifindex) { struct bgpevpn *vpn; struct prefix_evpn p; @@ -5732,13 +5735,16 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, if (is_vni_live(vpn) && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip) && IPV4_ADDR_SAME(&vpn->mcast_grp, &mcast_grp) - && vpn->tenant_vrf_id == tenant_vrf_id) + && vpn->tenant_vrf_id == tenant_vrf_id + && vpn->svi_ifindex == svi_ifindex) /* Probably some other param has changed that we don't * care about. */ return 0; bgp_evpn_mcast_grp_change(bgp, vpn, mcast_grp); + vpn->svi_ifindex = svi_ifindex; + /* Update tenant_vrf_id if it has changed. */ if (vpn->tenant_vrf_id != tenant_vrf_id) { bgpevpn_unlink_from_l3vni(vpn); @@ -5762,7 +5768,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, tenant_vrf_id, - mcast_grp); + mcast_grp, svi_ifindex); if (!vpn) { flog_err( EC_BGP_VNI, diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 90e088c3e..617ed31be 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -202,7 +202,8 @@ 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, vrf_id_t tenant_vrf_id, - struct in_addr mcast_grp); + struct in_addr mcast_grp, + ifindex_t svi_ifindex); extern void bgp_evpn_flood_control_change(struct bgp *bgp); extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp); extern void bgp_evpn_cleanup(struct bgp *bgp); diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index debed9f68..3983f35e5 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -62,6 +62,7 @@ RB_PROTOTYPE(bgp_es_evi_rb_head, bgp_evpn_es_evi, rb_node, struct bgpevpn { vni_t vni; vrf_id_t tenant_vrf_id; + ifindex_t svi_ifindex; uint32_t flags; #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */ #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */ @@ -612,7 +613,8 @@ 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, vrf_id_t tenant_vrf_id, - struct in_addr mcast_grp); + struct in_addr mcast_grp, + ifindex_t svi_ifindex); extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn); extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni); extern int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index fccaf9166..4c6225be9 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -531,6 +531,9 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) else json_object_string_add(json, "advertiseSviMacIp", "Disabled"); + json_object_string_add( + json, "sviInterface", + ifindex2ifname(vpn->svi_ifindex, vpn->tenant_vrf_id)); } else { vty_out(vty, "VNI: %d", vpn->vni); if (is_vni_live(vpn)) @@ -564,6 +567,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) else vty_out(vty, " Advertise-svi-macip : %s\n", "Disabled"); + vty_out(vty, " SVI interface : %s\n", + ifindex2ifname(vpn->svi_ifindex, vpn->tenant_vrf_id)); } if (!json) @@ -2290,7 +2295,7 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) /* tenant vrf will be updated when we get local_vni_add from * zebra */ - vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0, mcast_grp); + vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0, mcast_grp, 0); if (!vpn) { flog_err( EC_BGP_VNI, diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index b32f31965..73ce2d9ae 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2830,6 +2830,7 @@ static int bgp_zebra_process_local_vni(ZAPI_CALLBACK_ARGS) struct in_addr vtep_ip = {INADDR_ANY}; vrf_id_t tenant_vrf_id = VRF_DEFAULT; struct in_addr mcast_grp = {INADDR_ANY}; + ifindex_t svi_ifindex = 0; s = zclient->ibuf; vni = stream_getl(s); @@ -2837,6 +2838,7 @@ static int bgp_zebra_process_local_vni(ZAPI_CALLBACK_ARGS) vtep_ip.s_addr = stream_get_ipv4(s); stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t)); mcast_grp.s_addr = stream_get_ipv4(s); + stream_get(&svi_ifindex, s, sizeof(ifindex_t)); } bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -2844,16 +2846,17 @@ static int bgp_zebra_process_local_vni(ZAPI_CALLBACK_ARGS) return 0; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s", - (cmd == ZEBRA_VNI_ADD) ? "add" : "del", - vrf_id_to_name(vrf_id), vni, - vrf_id_to_name(tenant_vrf_id)); + zlog_debug( + "Rx VNI %s VRF %s VNI %u tenant-vrf %s SVI ifindex %u", + (cmd == ZEBRA_VNI_ADD) ? "add" : "del", + vrf_id_to_name(vrf_id), vni, + vrf_id_to_name(tenant_vrf_id), svi_ifindex); if (cmd == ZEBRA_VNI_ADD) return bgp_evpn_local_vni_add( bgp, vni, vtep_ip.s_addr != INADDR_ANY ? vtep_ip : bgp->router_id, - tenant_vrf_id, mcast_grp); + tenant_vrf_id, mcast_grp, svi_ifindex); else return bgp_evpn_local_vni_del(bgp, vni); } diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 30f4a4476..816f46bac 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -134,6 +134,10 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) if (json == NULL) { vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name); vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex); + vty_out(vty, " SVI interface: %s\n", + (zevpn->svi_if ? zevpn->svi_if->name : "")); + vty_out(vty, " SVI ifIndex: %u\n", + (zevpn->svi_if ? zevpn->svi_if->ifindex : 0)); vty_out(vty, " Local VTEP IP: %pI4\n", &zevpn->local_vtep_ip); vty_out(vty, " Mcast group: %pI4\n", @@ -142,6 +146,12 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) json_object_string_add(json, "vxlanInterface", zevpn->vxlan_if->name); json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex); + if (zevpn->svi_if) { + json_object_string_add(json, "sviInterface", + zevpn->svi_if->name); + json_object_int_add(json, "sviIfindex", + zevpn->svi_if->ifindex); + } json_object_string_add(json, "vtepIp", inet_ntop(AF_INET, &zevpn->local_vtep_ip, buf, sizeof(buf))); @@ -1048,6 +1058,8 @@ int zebra_evpn_del(zebra_evpn_t *zevpn) zvrf = zebra_vrf_get_evpn(); assert(zvrf); + zevpn->svi_if = NULL; + /* Free the neighbor hash table. */ hash_free(zevpn->neigh_table); zevpn->neigh_table = NULL; @@ -1075,6 +1087,7 @@ int zebra_evpn_send_add_to_client(zebra_evpn_t *zevpn) { struct zserv *client; struct stream *s; + ifindex_t svi_index; int rc; client = zserv_find_client(ZEBRA_ROUTE_BGP, 0); @@ -1082,6 +1095,8 @@ int zebra_evpn_send_add_to_client(zebra_evpn_t *zevpn) if (!client) return 0; + svi_index = zevpn->svi_if ? zevpn->svi_if->ifindex : 0; + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id()); @@ -1089,15 +1104,18 @@ int zebra_evpn_send_add_to_client(zebra_evpn_t *zevpn) stream_put_in_addr(s, &zevpn->local_vtep_ip); stream_put(s, &zevpn->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */ stream_put_in_addr(s, &zevpn->mcast_grp); + stream_put(s, &svi_index, sizeof(ifindex_t)); /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Send EVPN_ADD %u %pI4 tenant vrf %s to %s", zevpn->vni, - &zevpn->local_vtep_ip, - vrf_id_to_name(zevpn->vrf_id), - zebra_route_string(client->proto)); + zlog_debug( + "Send EVPN_ADD %u %pI4 tenant vrf %s(%u) SVI index %u to %s", + zevpn->vni, &zevpn->local_vtep_ip, + vrf_id_to_name(zevpn->vrf_id), zevpn->vrf_id, + (zevpn->svi_if ? zevpn->svi_if->ifindex : 0), + zebra_route_string(client->proto)); client->vniadd_cnt++; rc = zserv_send_message(client, s); diff --git a/zebra/zebra_evpn.h b/zebra/zebra_evpn.h index 27392ec85..ee9e1406e 100644 --- a/zebra/zebra_evpn.h +++ b/zebra/zebra_evpn.h @@ -98,6 +98,9 @@ struct zebra_evpn_t_ { /* Corresponding VxLAN interface. */ struct interface *vxlan_if; + /* Corresponding SVI interface. */ + struct interface *svi_if; + /* List of remote VTEPs */ zebra_vtep_t *vteps; diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 09eb78917..99df49a46 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1012,6 +1012,7 @@ static int zevpn_build_hash_table_zns(struct ns *ns, vxl->access_vlan, zif->brslave_info.br_if); if (vlan_if) { + zevpn->svi_if = vlan_if; zevpn->vrf_id = vlan_if->vrf_id; zl3vni = zl3vni_from_vrf( vlan_if->vrf_id); @@ -4527,6 +4528,7 @@ int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) zevpn = zebra_evpn_from_svi(ifp, link_if); if (zevpn) { + zevpn->svi_if = NULL; zevpn->vrf_id = VRF_DEFAULT; /* update the tenant vrf in BGP */ @@ -4582,6 +4584,7 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) vrf_id_to_name(ifp->vrf_id)); /* update the vrf information for l2-vni and inform bgp */ + zevpn->svi_if = ifp; zevpn->vrf_id = ifp->vrf_id; if (if_is_operative(zevpn->vxlan_if)) @@ -4792,6 +4795,7 @@ int zebra_vxlan_if_up(struct interface *ifp) vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (vlan_if) { + zevpn->svi_if = vlan_if; zevpn->vrf_id = vlan_if->vrf_id; zl3vni = zl3vni_from_vrf(vlan_if->vrf_id); if (zl3vni) @@ -4894,6 +4898,7 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) struct zebra_l2info_vxlan *vxl = NULL; zebra_evpn_t *zevpn = NULL; zebra_l3vni_t *zl3vni = NULL; + struct interface *vlan_if = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -4983,6 +4988,7 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { /* Delete from client, remove all remote VTEPs */ /* Also, free up all MACs and neighbors. */ + zevpn->svi_if = NULL; zebra_evpn_send_del_to_client(zevpn); zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH); zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC); @@ -5012,6 +5018,11 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) zebra_evpn_es_set_base_evpn(zevpn); } zevpn_vxlan_if_set(zevpn, ifp, true /* set */); + vlan_if = zvni_map_to_svi(vxl->access_vlan, + zif->brslave_info.br_if); + if (vlan_if) + zevpn->svi_if = vlan_if; + /* Take further actions needed. * Note that if we are here, there is a change of interest. */ @@ -5131,6 +5142,7 @@ int zebra_vxlan_if_add(struct interface *ifp) vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (vlan_if) { + zevpn->svi_if = vlan_if; zevpn->vrf_id = vlan_if->vrf_id; zl3vni = zl3vni_from_vrf(vlan_if->vrf_id); if (zl3vni) |