summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c16
-rw-r--r--bgpd/bgp_evpn.h3
-rw-r--r--bgpd/bgp_evpn_private.h4
-rw-r--r--bgpd/bgp_evpn_vty.c7
-rw-r--r--bgpd/bgp_zebra.c13
-rw-r--r--zebra/zebra_evpn.c26
-rw-r--r--zebra/zebra_evpn.h3
-rw-r--r--zebra/zebra_vxlan.c12
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)