mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 05:21:31 +00:00
bgpd, zebra: Add svi_interface to zebra VNI and bgp EVPN structures
SVI ifindex for L2VNI is required in BGP to perform EVPN type-5 to type-2 recusrsive resolution using gateway IP overlay index. Program this svi_ifindex in struct zebra_vni_t as well as in struct bgpevpn Changes include: 1. Add svi_if field to struct zebra_evpn_t 2. Add svi_ifindex field to struct bgpevpn 3. When SVI (bridge or VLAN) is bound to a VxLAN interface, store it in the zebra_evpn_t structure. 4. Add this SVI ifindex to ZEBRA_VNI_ADD 5. Store svi_ifindex in struct bgpevpn Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
This commit is contained in:
parent
a2299abae8
commit
9daa5d471a
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user