2 * Zebra EVPN for VxLAN interface handling
4 * Copyright (C) 2021 Cumulus Networks, Inc.
5 * Vivek Venkatraman, Stephen Worley, Sharath Ramamurthy
7 * This file is part of FRR.
9 * FRR is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
14 * FRR is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
34 #include <linux/neighbour.h>
37 #include "zebra/zebra_router.h"
38 #include "zebra/debug.h"
39 #include "zebra/interface.h"
40 #include "zebra/rib.h"
42 #include "zebra/rt_netlink.h"
43 #include "zebra/zebra_errors.h"
44 #include "zebra/zebra_l2.h"
45 #include "zebra/zebra_ns.h"
46 #include "zebra/zebra_vrf.h"
47 #include "zebra/zebra_vxlan.h"
48 #include "zebra/zebra_vxlan_if.h"
49 #include "zebra/zebra_evpn.h"
50 #include "zebra/zebra_evpn_mac.h"
51 #include "zebra/zebra_evpn_neigh.h"
52 #include "zebra/zebra_vxlan_private.h"
53 #include "zebra/zebra_evpn_mh.h"
54 #include "zebra/zebra_evpn_vxlan.h"
55 #include "zebra/zebra_router.h"
57 static unsigned int zebra_vxlan_vni_hash_keymake(const void *p
)
59 const struct zebra_vxlan_vni
*vni
;
61 vni
= (const struct zebra_vxlan_vni
*)p
;
62 return jhash_1word(vni
->vni
, 0);
65 static bool zebra_vxlan_vni_hash_cmp(const void *p1
, const void *p2
)
67 const struct zebra_vxlan_vni
*vni1
;
68 const struct zebra_vxlan_vni
*vni2
;
70 vni1
= (const struct zebra_vxlan_vni
*)p1
;
71 vni2
= (const struct zebra_vxlan_vni
*)p2
;
73 return (vni1
->vni
== vni2
->vni
);
76 static int zebra_vxlan_if_vni_walk_callback(struct hash_bucket
*bucket
,
80 struct zebra_vxlan_vni
*vni
;
81 struct zebra_vxlan_if_ctx
*ctx
;
83 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
84 ctx
= (struct zebra_vxlan_if_ctx
*)ctxt
;
86 ret
= ctx
->func(ctx
->zif
, vni
, ctx
->arg
);
90 static void zebra_vxlan_if_vni_iterate_callback(struct hash_bucket
*bucket
,
93 struct zebra_vxlan_vni
*vni
;
94 struct zebra_vxlan_if_ctx
*ctx
;
96 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
97 ctx
= (struct zebra_vxlan_if_ctx
*)ctxt
;
99 ctx
->func(ctx
->zif
, vni
, ctx
->arg
);
102 static int zebra_vxlan_if_del_vni(struct interface
*ifp
,
103 struct zebra_vxlan_vni
*vnip
)
106 struct zebra_if
*zif
;
107 struct zebra_evpn
*zevpn
;
108 struct zebra_l3vni
*zl3vni
;
109 struct interface
*br_if
;
111 /* Check if EVPN is enabled. */
112 if (!is_evpn_enabled())
119 zl3vni
= zl3vni_lookup(vni
);
122 if (IS_ZEBRA_DEBUG_VXLAN
)
123 zlog_debug("Del L3-VNI %u intf %s(%u)", vni
, ifp
->name
,
126 /* process oper-down for l3-vni */
127 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
129 /* remove the association with vxlan_if */
130 memset(&zl3vni
->local_vtep_ip
, 0, sizeof(struct in_addr
));
131 zl3vni
->vxlan_if
= NULL
;
133 br_if
= zif
->brslave_info
.br_if
;
134 zl3vni_bridge_if_set(zl3vni
, br_if
, false /* unset */);
137 /* process if-del for l2-vni*/
138 if (IS_ZEBRA_DEBUG_VXLAN
)
139 zlog_debug("Del L2-VNI %u intf %s(%u)", vni
, ifp
->name
,
142 /* Locate hash entry; it is expected to exist. */
143 zevpn
= zebra_evpn_lookup(vni
);
146 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
147 ifp
->name
, ifp
->ifindex
, vni
);
151 /* remove from l3-vni list */
152 zl3vni
= zl3vni_from_vrf(zevpn
->vrf_id
);
154 listnode_delete(zl3vni
->l2vnis
, zevpn
);
155 /* Delete VNI from BGP. */
156 zebra_evpn_send_del_to_client(zevpn
);
158 /* Free up all neighbors and MAC, if any. */
159 zebra_evpn_neigh_del_all(zevpn
, 1, 0, DEL_ALL_NEIGH
);
160 zebra_evpn_mac_del_all(zevpn
, 1, 0, DEL_ALL_MAC
);
162 /* Free up all remote VTEPs, if any. */
163 zebra_evpn_vtep_del_all(zevpn
, 1);
165 /* Delete the hash entry. */
166 if (zebra_evpn_vxlan_del(zevpn
)) {
167 flog_err(EC_ZEBRA_VNI_DEL_FAILED
,
168 "Failed to del EVPN hash %p, IF %s(%u) VNI %u",
169 zevpn
, ifp
->name
, ifp
->ifindex
, zevpn
->vni
);
176 static int zebra_vxlan_if_update_vni(struct interface
*ifp
,
177 struct zebra_vxlan_vni
*vnip
,
181 struct zebra_if
*zif
;
182 struct zebra_l2info_vxlan
*vxl
;
183 struct zebra_evpn
*zevpn
;
184 struct zebra_l3vni
*zl3vni
;
185 struct interface
*vlan_if
;
186 struct interface
*br_if
;
188 /* Check if EVPN is enabled. */
189 if (!is_evpn_enabled())
194 vxl
= &zif
->l2info
.vxl
;
197 zl3vni
= zl3vni_lookup(vni
);
200 if (IS_ZEBRA_DEBUG_VXLAN
)
202 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
203 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
204 &vxl
->vtep_ip
, zif
->brslave_info
.bridge_ifindex
,
207 /* Removed from bridge? Cleanup and return */
208 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
209 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
210 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
214 if ((chgflags
& ZEBRA_VXLIF_MASTER_MAC_CHANGE
)
215 && if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
)) {
216 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
217 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
221 /* access-vlan change - process oper down, associate with new
222 * svi_if and then process oper up again
224 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
225 if (if_is_operative(ifp
)) {
226 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
227 zl3vni
->svi_if
= NULL
;
228 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
229 zl3vni
->mac_vlan_if
=
230 zl3vni_map_to_mac_vlan_if(zl3vni
);
231 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
232 if (is_l3vni_oper_up(zl3vni
))
233 zebra_vxlan_process_l3vni_oper_up(
239 * local-ip change - process oper down, associate with new
240 * local-ip and then process oper up again
242 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
243 if (if_is_operative(ifp
)) {
244 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
245 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
246 if (is_l3vni_oper_up(zl3vni
))
247 zebra_vxlan_process_l3vni_oper_up(
252 /* Update local tunnel IP. */
253 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
255 zl3vni
->vid
= (zl3vni
->vid
!= vnip
->access_vlan
)
258 br_if
= zif
->brslave_info
.br_if
;
259 zl3vni_bridge_if_set(zl3vni
, br_if
, true /* set */);
261 /* if we have a valid new master, process l3-vni oper up */
262 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
263 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
264 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
268 /* Update VNI hash. */
269 zevpn
= zebra_evpn_lookup(vni
);
272 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
273 ifp
->name
, ifp
->ifindex
, vni
);
277 if (IS_ZEBRA_DEBUG_VXLAN
)
279 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
280 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
281 &vxl
->vtep_ip
, zif
->brslave_info
.bridge_ifindex
,
284 /* Removed from bridge? Cleanup and return */
285 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
286 && (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
287 /* Delete from client, remove all remote VTEPs */
288 /* Also, free up all MACs and neighbors. */
289 zevpn
->svi_if
= NULL
;
290 zebra_evpn_send_del_to_client(zevpn
);
291 zebra_evpn_neigh_del_all(zevpn
, 1, 0, DEL_ALL_NEIGH
);
292 zebra_evpn_mac_del_all(zevpn
, 1, 0, DEL_ALL_MAC
);
293 zebra_evpn_vtep_del_all(zevpn
, 1);
297 /* Handle other changes. */
298 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
299 /* Remove all existing local neigh and MACs for this VNI
300 * (including from BGP)
302 zebra_evpn_neigh_del_all(zevpn
, 0, 1, DEL_LOCAL_MAC
);
303 zebra_evpn_mac_del_all(zevpn
, 0, 1, DEL_LOCAL_MAC
);
306 if (zevpn
->local_vtep_ip
.s_addr
!= vxl
->vtep_ip
.s_addr
307 || zevpn
->mcast_grp
.s_addr
!= vnip
->mcast_grp
.s_addr
) {
308 zebra_vxlan_sg_deref(zevpn
->local_vtep_ip
,
310 zebra_vxlan_sg_ref(vxl
->vtep_ip
, vnip
->mcast_grp
);
311 zevpn
->local_vtep_ip
= vxl
->vtep_ip
;
312 zevpn
->mcast_grp
= vnip
->mcast_grp
;
313 /* on local vtep-ip check if ES orig-ip
314 * needs to be updated
316 zebra_evpn_es_set_base_evpn(zevpn
);
318 zevpn_vxlan_if_set(zevpn
, ifp
, true /* set */);
319 zevpn
->vid
= (zevpn
->vid
!= vnip
->access_vlan
)
322 br_if
= zif
->brslave_info
.br_if
;
323 zevpn_bridge_if_set(zevpn
, br_if
, true /* set */);
325 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
, br_if
);
327 zevpn
->svi_if
= vlan_if
;
329 /* Take further actions needed.
330 * Note that if we are here, there is a change of interest.
332 /* If down or not mapped to a bridge, we're done. */
333 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
336 /* Inform BGP, if there is a change of interest. */
338 (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
|
339 ZEBRA_VXLIF_MCAST_GRP_CHANGE
| ZEBRA_VXLIF_VLAN_CHANGE
))
340 zebra_evpn_send_add_to_client(zevpn
);
342 /* If there is a valid new master or a VLAN mapping change,
343 * read and populate local MACs and neighbors.
344 * Also, reinstall any remote MACs and neighbors
345 * for this VNI (based on new VLAN).
347 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
348 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
349 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
350 struct mac_walk_ctx m_wctx
;
351 struct neigh_walk_ctx n_wctx
;
353 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
355 memset(&m_wctx
, 0, sizeof(m_wctx
));
356 m_wctx
.zevpn
= zevpn
;
357 hash_iterate(zevpn
->mac_table
,
358 zebra_evpn_install_mac_hash
, &m_wctx
);
360 memset(&n_wctx
, 0, sizeof(n_wctx
));
361 n_wctx
.zevpn
= zevpn
;
362 hash_iterate(zevpn
->neigh_table
,
363 zebra_evpn_install_neigh_hash
, &n_wctx
);
370 static int zebra_vxlan_if_add_vni(struct interface
*ifp
,
371 struct zebra_vxlan_vni
*vnip
)
374 struct zebra_if
*zif
;
375 struct zebra_l2info_vxlan
*vxl
;
376 struct zebra_evpn
*zevpn
;
377 struct zebra_l3vni
*zl3vni
;
378 struct interface
*br_if
;
380 /* Check if EVPN is enabled. */
381 if (!is_evpn_enabled())
386 vxl
= &zif
->l2info
.vxl
;
389 zl3vni
= zl3vni_lookup(vni
);
392 /* process if-add for l3-vni*/
393 if (IS_ZEBRA_DEBUG_VXLAN
)
395 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
396 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
398 zif
->brslave_info
.bridge_ifindex
);
400 /* associate with vxlan_if */
401 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
402 zl3vni
->vxlan_if
= ifp
;
405 * Associate with SVI, if any. We can associate with svi-if only
406 * after association with vxlan_if is complete
408 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
410 zl3vni
->mac_vlan_if
= zl3vni_map_to_mac_vlan_if(zl3vni
);
412 zl3vni
->vid
= vnip
->access_vlan
;
413 br_if
= zif
->brslave_info
.br_if
;
414 zl3vni_bridge_if_set(zl3vni
, br_if
, true /* set */);
416 if (is_l3vni_oper_up(zl3vni
))
417 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
420 /* process if-add for l2-vni */
421 struct interface
*vlan_if
= NULL
;
423 /* Create or update EVPN hash. */
424 zevpn
= zebra_evpn_lookup(vni
);
426 zevpn
= zebra_evpn_add(vni
);
428 if (zevpn
->local_vtep_ip
.s_addr
!= vxl
->vtep_ip
.s_addr
429 || zevpn
->mcast_grp
.s_addr
!= vnip
->mcast_grp
.s_addr
) {
430 zebra_vxlan_sg_deref(zevpn
->local_vtep_ip
,
432 zebra_vxlan_sg_ref(vxl
->vtep_ip
, vnip
->mcast_grp
);
433 zevpn
->local_vtep_ip
= vxl
->vtep_ip
;
434 zevpn
->mcast_grp
= vnip
->mcast_grp
;
435 /* on local vtep-ip check if ES orig-ip
436 * needs to be updated
438 zebra_evpn_es_set_base_evpn(zevpn
);
440 zevpn_vxlan_if_set(zevpn
, ifp
, true /* set */);
441 br_if
= zif
->brslave_info
.br_if
;
442 zevpn_bridge_if_set(zevpn
, br_if
, true /* set */);
443 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
, br_if
);
445 zevpn
->vid
= vnip
->access_vlan
;
446 zevpn
->svi_if
= vlan_if
;
447 zevpn
->vrf_id
= vlan_if
->vrf
->vrf_id
;
448 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf
->vrf_id
);
450 listnode_add_sort_nodup(zl3vni
->l2vnis
, zevpn
);
453 if (IS_ZEBRA_DEBUG_VXLAN
)
455 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
457 vlan_if
? vlan_if
->vrf
->name
: VRF_DEFAULT_NAME
,
458 ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
459 &vxl
->vtep_ip
, &vnip
->mcast_grp
,
460 zif
->brslave_info
.bridge_ifindex
);
462 /* If down or not mapped to a bridge, we're done. */
463 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
467 zebra_evpn_send_add_to_client(zevpn
);
469 /* Read and populate local MACs and neighbors */
470 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
476 static void zebra_vxlan_if_vni_entry_del(struct zebra_if
*zif
,
477 struct zebra_vxlan_vni
*vni
)
480 zebra_evpn_vl_vxl_deref(vni
->access_vlan
, vni
->vni
, zif
);
481 zebra_vxlan_if_del_vni(zif
->ifp
, vni
);
485 static int zebra_vxlan_if_vni_entry_add(struct zebra_if
*zif
,
486 struct zebra_vxlan_vni
*vni
)
488 zebra_evpn_vl_vxl_ref(vni
->access_vlan
, vni
->vni
, zif
);
489 return zebra_vxlan_if_add_vni(zif
->ifp
, vni
);
492 static int zebra_vxlan_if_add_update_vni(struct zebra_if
*zif
,
493 struct zebra_vxlan_vni
*vni
,
496 struct hash
*old_vni_table
;
497 struct zebra_vxlan_vni vni_tmp
;
498 struct zebra_vxlan_vni
*old_vni
= NULL
;
500 old_vni_table
= (struct hash
*)ctxt
;
501 memcpy(&vni_tmp
, vni
, sizeof(*vni
));
503 old_vni
= hash_release(old_vni_table
, &vni_tmp
);
505 if (IS_ZEBRA_DEBUG_VXLAN
)
506 zlog_debug("vxlan %s adding vni(%d, %d)",
507 zif
->ifp
->name
, vni
->vni
, vni
->access_vlan
);
509 zebra_vxlan_if_vni_entry_add(zif
, &vni_tmp
);
513 /* copy mcast group from old_vni as thats not being changed here */
514 vni
->mcast_grp
= old_vni
->mcast_grp
;
516 if (old_vni
->access_vlan
!= vni
->access_vlan
) {
517 if (IS_ZEBRA_DEBUG_VXLAN
)
519 "vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
520 zif
->ifp
->name
, old_vni
->vni
,
521 old_vni
->access_vlan
, vni
->vni
,
524 zebra_evpn_vl_vxl_deref(old_vni
->access_vlan
, old_vni
->vni
,
526 zebra_evpn_vl_vxl_ref(vni
->access_vlan
, vni
->vni
, zif
);
527 zebra_vxlan_if_update_vni(zif
->ifp
, vni
,
528 ZEBRA_VXLIF_VLAN_CHANGE
);
529 zebra_vxlan_vni_free(old_vni
);
535 static int zebra_vxlan_if_vni_entry_update_callback(struct zebra_if
*zif
,
536 struct zebra_vxlan_vni
*vni
,
541 chgflags
= (uint16_t *)ctxt
;
542 return zebra_vxlan_if_update_vni(zif
->ifp
, vni
, *chgflags
);
545 static int zebra_vxlan_if_vni_entry_del_callback(struct zebra_if
*zif
,
546 struct zebra_vxlan_vni
*vni
,
549 zebra_vxlan_if_vni_entry_del(zif
, vni
);
553 static int zebra_vxlan_if_vni_entry_down_callback(struct zebra_if
*zif
,
554 struct zebra_vxlan_vni
*vni
,
557 return zebra_vxlan_if_vni_down(zif
->ifp
, vni
);
560 static int zebra_vxlan_if_vni_entry_up_callback(struct zebra_if
*zif
,
561 struct zebra_vxlan_vni
*vni
,
564 return zebra_vxlan_if_vni_up(zif
->ifp
, vni
);
567 static void zebra_vxlan_if_vni_clean(struct hash_bucket
*bucket
, void *arg
)
569 struct zebra_if
*zif
;
570 struct zebra_vxlan_vni
*vni
;
572 zif
= (struct zebra_if
*)arg
;
573 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
574 zebra_vxlan_if_vni_entry_del(zif
, vni
);
577 void zebra_vxlan_vni_free(void *arg
)
579 struct zebra_vxlan_vni
*vni
;
581 vni
= (struct zebra_vxlan_vni
*)arg
;
583 XFREE(MTYPE_TMP
, vni
);
586 void *zebra_vxlan_vni_alloc(void *p
)
588 struct zebra_vxlan_vni
*vni
;
589 const struct zebra_vxlan_vni
*vnip
;
591 vnip
= (const struct zebra_vxlan_vni
*)p
;
592 vni
= XCALLOC(MTYPE_TMP
, sizeof(*vni
));
593 vni
->vni
= vnip
->vni
;
594 vni
->access_vlan
= vnip
->access_vlan
;
595 vni
->mcast_grp
= vnip
->mcast_grp
;
600 struct hash
*zebra_vxlan_vni_table_create(void)
602 return hash_create(zebra_vxlan_vni_hash_keymake
,
603 zebra_vxlan_vni_hash_cmp
, "Zebra Vxlan VNI Table");
606 void zebra_vxlan_vni_table_destroy(struct hash
*vni_table
)
609 hash_clean(vni_table
, zebra_vxlan_vni_free
);
610 hash_free(vni_table
);
614 int zebra_vxlan_if_vni_table_destroy(struct zebra_if
*zif
)
616 struct zebra_vxlan_vni_info
*vni_info
;
618 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
619 if (vni_info
->vni_table
) {
620 zebra_vxlan_if_vni_iterate(
621 zif
, zebra_vxlan_if_vni_entry_del_callback
, NULL
);
622 zebra_vxlan_vni_table_destroy(vni_info
->vni_table
);
623 vni_info
->vni_table
= NULL
;
628 int zebra_vxlan_if_vni_table_create(struct zebra_if
*zif
)
630 struct zebra_vxlan_vni_info
*vni_info
;
632 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
635 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
636 vni_info
->vni_table
= zebra_vxlan_vni_table_create();
637 if (!vni_info
->vni_table
)
643 struct zebra_vxlan_vni
*zebra_vxlan_if_vni_find(const struct zebra_if
*zif
,
646 struct zebra_vxlan_vni
*vnip
= NULL
;
647 const struct zebra_vxlan_vni_info
*vni_info
;
648 struct zebra_vxlan_vni vni_tmp
;
650 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
651 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
652 vnip
= (struct zebra_vxlan_vni
*)&vni_info
->vni
;
654 if (vni
&& (vnip
->vni
!= vni
))
660 /* For SVD, the VNI value is a required parameter. */
663 memset(&vni_tmp
, 0, sizeof(vni_tmp
));
665 vnip
= (struct zebra_vxlan_vni
*)hash_lookup(vni_info
->vni_table
,
668 /* TODO: For debugging. Remove later */
670 assert(vnip
->vni
== vni
);
675 void zebra_vxlan_if_vni_iterate(struct zebra_if
*zif
,
676 int (*func
)(struct zebra_if
*zif
,
677 struct zebra_vxlan_vni
*, void *),
680 struct zebra_vxlan_vni_info
*vni_info
;
681 struct zebra_vxlan_vni
*vni
= NULL
;
682 struct zebra_vxlan_if_ctx ctx
;
684 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
685 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
686 vni
= zebra_vxlan_if_vni_find(zif
, 0);
691 memset(&ctx
, 0, sizeof(ctx
));
695 hash_iterate(vni_info
->vni_table
, zebra_vxlan_if_vni_iterate_callback
,
699 void zebra_vxlan_if_vni_walk(struct zebra_if
*zif
,
700 int (*func
)(struct zebra_if
*zif
,
701 struct zebra_vxlan_vni
*, void *),
704 struct zebra_vxlan_vni_info
*vni_info
;
705 struct zebra_vxlan_vni
*vni
= NULL
;
706 struct zebra_vxlan_if_ctx ctx
;
708 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
709 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
710 vni
= zebra_vxlan_if_vni_find(zif
, 0);
715 memset(&ctx
, 0, sizeof(ctx
));
719 hash_walk(vni_info
->vni_table
, zebra_vxlan_if_vni_walk_callback
, &ctx
);
722 vni_t
zebra_vxlan_if_access_vlan_vni_find(struct zebra_if
*zif
,
723 struct interface
*br_if
)
725 struct zebra_vxlan_vni
*vni
= NULL
;
727 /* Expected to be called only for vlan-unware bridges. In this case,
728 * we only support a per-VNI VXLAN interface model.
730 if (!IS_ZEBRA_VXLAN_IF_VNI(zif
))
733 vni
= zebra_vxlan_if_vni_find(zif
, 0);
739 int zebra_vxlan_if_vni_table_add_update(struct interface
*ifp
,
740 struct hash
*vni_table
)
742 struct zebra_if
*zif
;
743 struct hash
*old_vni_table
= NULL
;
744 struct zebra_vxlan_vni_info
*vni_info
;
746 zif
= (struct zebra_if
*)ifp
->info
;
748 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
750 old_vni_table
= vni_info
->vni_table
;
751 vni_info
->vni_table
= vni_table
;
753 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_add_update_vni
,
756 /* release kernel deleted vnis */
758 if (hashcount(old_vni_table
))
759 hash_iterate(old_vni_table
, zebra_vxlan_if_vni_clean
,
761 zebra_vxlan_vni_table_destroy(old_vni_table
);
767 int zebra_vxlan_if_vni_mcast_group_update(struct interface
*ifp
, vni_t vni_id
,
768 struct in_addr
*mcast_group
)
770 struct zebra_if
*zif
;
771 struct zebra_vxlan_vni
*vni
;
773 zif
= (struct zebra_if
*)ifp
->info
;
775 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
778 vni
= zebra_vxlan_if_vni_find(zif
, vni_id
);
783 vni
->mcast_grp
= *mcast_group
;
785 memset(&vni
->mcast_grp
, 0, sizeof(vni
->mcast_grp
));
787 return zebra_vxlan_if_update_vni(ifp
, vni
,
788 ZEBRA_VXLIF_MCAST_GRP_CHANGE
);
791 int zebra_vxlan_if_vni_down(struct interface
*ifp
, struct zebra_vxlan_vni
*vnip
)
794 struct zebra_if
*zif
;
795 struct zebra_l3vni
*zl3vni
;
796 struct zebra_evpn
*zevpn
;
798 /* Check if EVPN is enabled. */
799 if (!is_evpn_enabled())
806 zl3vni
= zl3vni_lookup(vni
);
808 /* process-if-down for l3-vni */
809 if (IS_ZEBRA_DEBUG_VXLAN
)
810 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
813 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
815 /* process if-down for l2-vni */
816 if (IS_ZEBRA_DEBUG_VXLAN
)
817 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
820 /* Locate hash entry; it is expected to exist. */
821 zevpn
= zebra_evpn_lookup(vni
);
824 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
825 ifp
->name
, ifp
->ifindex
, vni
);
829 assert(zevpn
->vxlan_if
== ifp
);
831 /* remove from l3-vni list */
832 zl3vni
= zl3vni_from_vrf(zevpn
->vrf_id
);
834 listnode_delete(zl3vni
->l2vnis
, zevpn
);
836 /* Delete this VNI from BGP. */
837 zebra_evpn_send_del_to_client(zevpn
);
839 /* Free up all neighbors and MACs, if any. */
840 zebra_evpn_neigh_del_all(zevpn
, 1, 0, DEL_ALL_NEIGH
);
841 zebra_evpn_mac_del_all(zevpn
, 1, 0, DEL_ALL_MAC
);
843 /* Free up all remote VTEPs, if any. */
844 zebra_evpn_vtep_del_all(zevpn
, 1);
850 * Handle VxLAN interface down
852 int zebra_vxlan_if_down(struct interface
*ifp
)
854 struct zebra_if
*zif
;
855 struct zebra_vxlan_vni_info
*vni_info
;
857 /* Check if EVPN is enabled. */
858 if (!is_evpn_enabled())
864 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
865 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
866 return zebra_vxlan_if_vni_down(ifp
, &vni_info
->vni
);
869 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_vni_entry_down_callback
,
875 int zebra_vxlan_if_vni_up(struct interface
*ifp
, struct zebra_vxlan_vni
*vnip
)
878 struct zebra_if
*zif
;
879 struct zebra_evpn
*zevpn
;
880 struct zebra_l3vni
*zl3vni
;
882 /* Check if EVPN is enabled. */
883 if (!is_evpn_enabled())
890 zl3vni
= zl3vni_lookup(vni
);
892 /* we need to associate with SVI, if any, we can associate with
893 * svi-if only after association with vxlan-intf is complete
895 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
896 zl3vni
->mac_vlan_if
= zl3vni_map_to_mac_vlan_if(zl3vni
);
898 if (IS_ZEBRA_DEBUG_VXLAN
)
900 "Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s",
901 ifp
->name
, ifp
->ifindex
, vni
,
902 zl3vni
->svi_if
? zl3vni
->svi_if
->name
: "NIL",
903 zl3vni
->mac_vlan_if
? zl3vni
->mac_vlan_if
->name
906 if (is_l3vni_oper_up(zl3vni
))
907 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
909 /* Handle L2-VNI add */
910 struct interface
*vlan_if
= NULL
;
912 if (IS_ZEBRA_DEBUG_VXLAN
)
913 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
916 /* Locate hash entry; it is expected to exist. */
917 zevpn
= zebra_evpn_lookup(vni
);
920 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
921 ifp
->name
, ifp
->ifindex
, vni
);
925 assert(zevpn
->vxlan_if
== ifp
);
926 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
,
927 zif
->brslave_info
.br_if
);
929 zevpn
->svi_if
= vlan_if
;
930 zevpn
->vrf_id
= vlan_if
->vrf
->vrf_id
;
931 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf
->vrf_id
);
933 listnode_add_sort_nodup(zl3vni
->l2vnis
, zevpn
);
936 /* If part of a bridge, inform BGP about this VNI. */
937 /* Also, read and populate local MACs and neighbors. */
938 if (zif
->brslave_info
.br_if
) {
939 zebra_evpn_send_add_to_client(zevpn
);
940 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
948 * Handle VxLAN interface up - update BGP if required.
950 int zebra_vxlan_if_up(struct interface
*ifp
)
952 struct zebra_if
*zif
;
953 struct zebra_vxlan_vni_info
*vni_info
;
955 /* Check if EVPN is enabled. */
956 if (!is_evpn_enabled())
962 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
963 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
964 return zebra_vxlan_if_vni_up(ifp
, &vni_info
->vni
);
967 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_vni_entry_up_callback
,
973 int zebra_vxlan_if_vni_del(struct interface
*ifp
, vni_t vni
)
975 struct zebra_if
*zif
;
976 struct zebra_vxlan_vni
*vnip
;
977 struct zebra_vxlan_vni vni_tmp
;
978 struct zebra_vxlan_vni_info
*vni_info
;
983 /* This should be called in SVD context only */
984 assert(IS_ZEBRA_VXLAN_IF_SVD(zif
));
986 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
987 memset(&vni_tmp
, 0, sizeof(vni_tmp
));
990 vnip
= hash_release(vni_info
->vni_table
, &vni_tmp
);
992 zebra_vxlan_if_vni_entry_del(zif
, vnip
);
993 zebra_vxlan_vni_free(vnip
);
999 * Handle VxLAN interface delete. Locate and remove entry in hash table
1000 * and update BGP, if required.
1002 int zebra_vxlan_if_del(struct interface
*ifp
)
1004 struct zebra_if
*zif
;
1005 struct zebra_vxlan_vni_info
*vni_info
;
1010 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1011 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1012 zebra_evpn_vl_vxl_deref(vni_info
->vni
.access_vlan
,
1013 vni_info
->vni
.vni
, zif
);
1014 return zebra_vxlan_if_del_vni(ifp
, &vni_info
->vni
);
1017 zebra_vxlan_if_vni_table_destroy(zif
);
1023 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
1025 int zebra_vxlan_if_update(struct interface
*ifp
, uint16_t chgflags
)
1027 struct zebra_if
*zif
;
1028 struct zebra_vxlan_vni_info
*vni_info
;
1033 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1034 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1035 return zebra_vxlan_if_update_vni(ifp
, &vni_info
->vni
, chgflags
);
1038 zebra_vxlan_if_vni_iterate(
1039 zif
, zebra_vxlan_if_vni_entry_update_callback
, &chgflags
);
1044 int zebra_vxlan_if_vni_add(struct interface
*ifp
, struct zebra_vxlan_vni
*vni
)
1046 struct zebra_if
*zif
;
1047 struct zebra_vxlan_vni_info
*vni_info
;
1052 /* This should be called in SVD context only */
1053 assert(IS_ZEBRA_VXLAN_IF_SVD(zif
));
1055 /* First insert into the table */
1056 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1057 hash_get(vni_info
->vni_table
, (void *)vni
, zebra_vxlan_vni_alloc
);
1059 return zebra_vxlan_if_vni_entry_add(zif
, vni
);
1063 * Handle VxLAN interface add.
1065 int zebra_vxlan_if_add(struct interface
*ifp
)
1068 struct zebra_if
*zif
;
1069 struct zebra_vxlan_vni_info
*vni_info
;
1074 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1075 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1076 zebra_evpn_vl_vxl_ref(vni_info
->vni
.access_vlan
,
1077 vni_info
->vni
.vni
, zif
);
1078 return zebra_vxlan_if_add_vni(ifp
, &vni_info
->vni
);
1081 ret
= zebra_vxlan_if_vni_table_create(zif
);