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
,
178 struct zebra_vxlan_if_update_ctx
*ctx
)
182 vlanid_t access_vlan
;
183 struct zebra_if
*zif
;
184 struct zebra_l2info_vxlan
*vxl
;
185 struct zebra_evpn
*zevpn
;
186 struct zebra_l3vni
*zl3vni
;
187 struct interface
*vlan_if
;
188 struct interface
*br_if
;
190 /* Check if EVPN is enabled. */
191 if (!is_evpn_enabled())
196 vxl
= &zif
->l2info
.vxl
;
198 chgflags
= ctx
->chgflags
;
200 zl3vni
= zl3vni_lookup(vni
);
203 if (IS_ZEBRA_DEBUG_VXLAN
)
205 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
206 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
207 &vxl
->vtep_ip
, zif
->brslave_info
.bridge_ifindex
,
210 /* Removed from bridge? Cleanup and return */
211 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) &&
212 (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
213 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
217 if ((chgflags
& ZEBRA_VXLIF_MASTER_MAC_CHANGE
) &&
218 if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
)) {
219 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
220 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
224 /* access-vlan change - process oper down, associate with new
225 * svi_if and then process oper up again
227 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
228 if (if_is_operative(ifp
)) {
229 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
230 zl3vni
->svi_if
= NULL
;
231 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
232 zl3vni
->mac_vlan_if
=
233 zl3vni_map_to_mac_vlan_if(zl3vni
);
234 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
235 if (is_l3vni_oper_up(zl3vni
))
236 zebra_vxlan_process_l3vni_oper_up(
242 * local-ip change - process oper down, associate with new
243 * local-ip and then process oper up again
245 if (chgflags
& ZEBRA_VXLIF_LOCAL_IP_CHANGE
) {
246 if (if_is_operative(ifp
)) {
247 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
248 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
249 if (is_l3vni_oper_up(zl3vni
))
250 zebra_vxlan_process_l3vni_oper_up(
255 /* Update local tunnel IP. */
256 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
258 zl3vni
->vid
= (zl3vni
->vid
!= vnip
->access_vlan
)
261 br_if
= zif
->brslave_info
.br_if
;
262 zl3vni_bridge_if_set(zl3vni
, br_if
, true /* set */);
264 /* if we have a valid new master, process l3-vni oper up */
265 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) {
266 if (if_is_operative(ifp
) && is_l3vni_oper_up(zl3vni
))
267 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
271 /* Update VNI hash. */
272 zevpn
= zebra_evpn_lookup(vni
);
275 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
276 ifp
->name
, ifp
->ifindex
, vni
);
280 if (IS_ZEBRA_DEBUG_VXLAN
)
282 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
283 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
284 &vxl
->vtep_ip
, zif
->brslave_info
.bridge_ifindex
,
287 /* Removed from bridge? Cleanup and return */
288 if ((chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
) &&
289 (zif
->brslave_info
.bridge_ifindex
== IFINDEX_INTERNAL
)) {
290 /* Delete from client, remove all remote VTEPs */
291 /* Also, free up all MACs and neighbors. */
292 zevpn
->svi_if
= NULL
;
293 zebra_evpn_send_del_to_client(zevpn
);
294 zebra_evpn_neigh_del_all(zevpn
, 1, 0, DEL_ALL_NEIGH
);
295 zebra_evpn_mac_del_all(zevpn
, 1, 0, DEL_ALL_MAC
);
296 zebra_evpn_vtep_del_all(zevpn
, 1);
300 /* Handle other changes. */
301 if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
302 /* Remove all existing local neigh and MACs for this VNI
303 * (including from BGP)
305 access_vlan
= vnip
->access_vlan
;
306 vnip
->access_vlan
= ctx
->old_vni
.access_vlan
;
307 zebra_evpn_neigh_del_all(zevpn
, 0, 1, DEL_LOCAL_MAC
);
308 zebra_evpn_mac_del_all(zevpn
, 0, 1, DEL_LOCAL_MAC
);
309 zebra_evpn_rem_mac_uninstall_all(zevpn
);
310 vnip
->access_vlan
= access_vlan
;
313 if (zevpn
->local_vtep_ip
.s_addr
!= vxl
->vtep_ip
.s_addr
||
314 zevpn
->mcast_grp
.s_addr
!= vnip
->mcast_grp
.s_addr
) {
315 zebra_vxlan_sg_deref(zevpn
->local_vtep_ip
,
317 zebra_vxlan_sg_ref(vxl
->vtep_ip
, vnip
->mcast_grp
);
318 zevpn
->local_vtep_ip
= vxl
->vtep_ip
;
319 zevpn
->mcast_grp
= vnip
->mcast_grp
;
320 /* on local vtep-ip check if ES orig-ip
321 * needs to be updated
323 zebra_evpn_es_set_base_evpn(zevpn
);
325 zevpn_vxlan_if_set(zevpn
, ifp
, true /* set */);
326 zevpn
->vid
= (zevpn
->vid
!= vnip
->access_vlan
)
329 br_if
= zif
->brslave_info
.br_if
;
330 zevpn_bridge_if_set(zevpn
, br_if
, true /* set */);
332 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
, br_if
);
334 zevpn
->svi_if
= vlan_if
;
336 /* Take further actions needed.
337 * Note that if we are here, there is a change of interest.
339 /* If down or not mapped to a bridge, we're done. */
340 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
343 /* Inform BGP, if there is a change of interest. */
345 (ZEBRA_VXLIF_MASTER_CHANGE
| ZEBRA_VXLIF_LOCAL_IP_CHANGE
|
346 ZEBRA_VXLIF_MCAST_GRP_CHANGE
| ZEBRA_VXLIF_VLAN_CHANGE
))
347 zebra_evpn_send_add_to_client(zevpn
);
349 /* If there is a valid new master or a VLAN mapping change,
350 * read and populate local MACs and neighbors.
351 * Also, reinstall any remote MACs and neighbors
352 * for this VNI (based on new VLAN).
354 if (chgflags
& ZEBRA_VXLIF_MASTER_CHANGE
)
355 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
356 else if (chgflags
& ZEBRA_VXLIF_VLAN_CHANGE
) {
357 struct neigh_walk_ctx n_wctx
;
359 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
361 zebra_evpn_rem_mac_install_all(zevpn
);
363 memset(&n_wctx
, 0, sizeof(n_wctx
));
364 n_wctx
.zevpn
= zevpn
;
365 hash_iterate(zevpn
->neigh_table
,
366 zebra_evpn_install_neigh_hash
, &n_wctx
);
373 static int zebra_vxlan_if_add_vni(struct interface
*ifp
,
374 struct zebra_vxlan_vni
*vnip
)
377 struct zebra_if
*zif
;
378 struct zebra_l2info_vxlan
*vxl
;
379 struct zebra_evpn
*zevpn
;
380 struct zebra_l3vni
*zl3vni
;
381 struct interface
*br_if
;
383 /* Check if EVPN is enabled. */
384 if (!is_evpn_enabled())
389 vxl
= &zif
->l2info
.vxl
;
392 zl3vni
= zl3vni_lookup(vni
);
395 /* process if-add for l3-vni*/
396 if (IS_ZEBRA_DEBUG_VXLAN
)
398 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
399 vni
, ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
401 zif
->brslave_info
.bridge_ifindex
);
403 /* associate with vxlan_if */
404 zl3vni
->local_vtep_ip
= vxl
->vtep_ip
;
405 zl3vni
->vxlan_if
= ifp
;
408 * Associate with SVI, if any. We can associate with svi-if only
409 * after association with vxlan_if is complete
411 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
413 zl3vni
->mac_vlan_if
= zl3vni_map_to_mac_vlan_if(zl3vni
);
415 zl3vni
->vid
= vnip
->access_vlan
;
416 br_if
= zif
->brslave_info
.br_if
;
417 zl3vni_bridge_if_set(zl3vni
, br_if
, true /* set */);
419 if (is_l3vni_oper_up(zl3vni
))
420 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
423 /* process if-add for l2-vni */
424 struct interface
*vlan_if
= NULL
;
426 /* Create or update EVPN hash. */
427 zevpn
= zebra_evpn_lookup(vni
);
429 zevpn
= zebra_evpn_add(vni
);
431 if (zevpn
->local_vtep_ip
.s_addr
!= vxl
->vtep_ip
.s_addr
||
432 zevpn
->mcast_grp
.s_addr
!= vnip
->mcast_grp
.s_addr
) {
433 zebra_vxlan_sg_deref(zevpn
->local_vtep_ip
,
435 zebra_vxlan_sg_ref(vxl
->vtep_ip
, vnip
->mcast_grp
);
436 zevpn
->local_vtep_ip
= vxl
->vtep_ip
;
437 zevpn
->mcast_grp
= vnip
->mcast_grp
;
438 /* on local vtep-ip check if ES orig-ip
439 * needs to be updated
441 zebra_evpn_es_set_base_evpn(zevpn
);
443 zevpn_vxlan_if_set(zevpn
, ifp
, true /* set */);
444 br_if
= zif
->brslave_info
.br_if
;
445 zevpn_bridge_if_set(zevpn
, br_if
, true /* set */);
446 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
, br_if
);
448 zevpn
->vid
= vnip
->access_vlan
;
449 zevpn
->svi_if
= vlan_if
;
450 zevpn
->vrf_id
= vlan_if
->vrf
->vrf_id
;
451 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf
->vrf_id
);
453 listnode_add_sort_nodup(zl3vni
->l2vnis
, zevpn
);
456 if (IS_ZEBRA_DEBUG_VXLAN
)
458 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
460 vlan_if
? vlan_if
->vrf
->name
: VRF_DEFAULT_NAME
,
461 ifp
->name
, ifp
->ifindex
, vnip
->access_vlan
,
462 &vxl
->vtep_ip
, &vnip
->mcast_grp
,
463 zif
->brslave_info
.bridge_ifindex
);
465 /* If down or not mapped to a bridge, we're done. */
466 if (!if_is_operative(ifp
) || !zif
->brslave_info
.br_if
)
470 zebra_evpn_send_add_to_client(zevpn
);
472 /* Read and populate local MACs and neighbors */
473 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
479 static void zebra_vxlan_if_vni_entry_del(struct zebra_if
*zif
,
480 struct zebra_vxlan_vni
*vni
)
483 zebra_evpn_vl_vxl_deref(vni
->access_vlan
, vni
->vni
, zif
);
484 zebra_vxlan_if_del_vni(zif
->ifp
, vni
);
488 static int zebra_vxlan_if_vni_entry_add(struct zebra_if
*zif
,
489 struct zebra_vxlan_vni
*vni
)
491 zebra_evpn_vl_vxl_ref(vni
->access_vlan
, vni
->vni
, zif
);
492 return zebra_vxlan_if_add_vni(zif
->ifp
, vni
);
495 static int zebra_vxlan_if_add_update_vni(struct zebra_if
*zif
,
496 struct zebra_vxlan_vni
*vni
,
499 struct zebra_vxlan_vni vni_tmp
;
500 struct zebra_vxlan_if_update_ctx
*ctx
;
501 struct zebra_vxlan_vni
*old_vni
= NULL
;
503 ctx
= (struct zebra_vxlan_if_update_ctx
*)ctxt
;
504 memcpy(&vni_tmp
, vni
, sizeof(*vni
));
506 if ((hashcount(ctx
->old_vni_table
) == 0) ||
507 !(old_vni
= hash_release(ctx
->old_vni_table
, &vni_tmp
))) {
508 if (IS_ZEBRA_DEBUG_VXLAN
)
509 zlog_debug("vxlan %s adding vni(%d, %d)",
510 zif
->ifp
->name
, vni
->vni
, vni
->access_vlan
);
512 zebra_vxlan_if_vni_entry_add(zif
, &vni_tmp
);
516 ctx
->old_vni
= *old_vni
;
517 ctx
->chgflags
= ZEBRA_VXLIF_VLAN_CHANGE
;
519 /* copy mcast group from old_vni as thats not being changed here */
520 vni
->mcast_grp
= old_vni
->mcast_grp
;
522 if (old_vni
->access_vlan
!= vni
->access_vlan
) {
523 if (IS_ZEBRA_DEBUG_VXLAN
)
525 "vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
526 zif
->ifp
->name
, old_vni
->vni
,
527 old_vni
->access_vlan
, vni
->vni
,
530 zebra_evpn_vl_vxl_deref(old_vni
->access_vlan
, old_vni
->vni
,
532 zebra_evpn_vl_vxl_ref(vni
->access_vlan
, vni
->vni
, zif
);
533 zebra_vxlan_if_update_vni(zif
->ifp
, vni
, ctx
);
534 zebra_vxlan_vni_free(old_vni
);
540 static int zebra_vxlan_if_vni_entry_update_callback(struct zebra_if
*zif
,
541 struct zebra_vxlan_vni
*vni
,
544 struct zebra_vxlan_if_update_ctx
*ctx
;
546 ctx
= (struct zebra_vxlan_if_update_ctx
*)ctxt
;
547 return zebra_vxlan_if_update_vni(zif
->ifp
, vni
, ctx
);
550 static int zebra_vxlan_if_vni_entry_del_callback(struct zebra_if
*zif
,
551 struct zebra_vxlan_vni
*vni
,
554 zebra_vxlan_if_vni_entry_del(zif
, vni
);
558 static int zebra_vxlan_if_vni_entry_down_callback(struct zebra_if
*zif
,
559 struct zebra_vxlan_vni
*vni
,
562 return zebra_vxlan_if_vni_down(zif
->ifp
, vni
);
565 static int zebra_vxlan_if_vni_entry_up_callback(struct zebra_if
*zif
,
566 struct zebra_vxlan_vni
*vni
,
569 return zebra_vxlan_if_vni_up(zif
->ifp
, vni
);
572 static void zebra_vxlan_if_vni_clean(struct hash_bucket
*bucket
, void *arg
)
574 struct zebra_if
*zif
;
575 struct zebra_vxlan_vni
*vni
;
577 zif
= (struct zebra_if
*)arg
;
578 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
579 zebra_vxlan_if_vni_entry_del(zif
, vni
);
582 void zebra_vxlan_vni_free(void *arg
)
584 struct zebra_vxlan_vni
*vni
;
586 vni
= (struct zebra_vxlan_vni
*)arg
;
588 XFREE(MTYPE_TMP
, vni
);
591 void *zebra_vxlan_vni_alloc(void *p
)
593 struct zebra_vxlan_vni
*vni
;
594 const struct zebra_vxlan_vni
*vnip
;
596 vnip
= (const struct zebra_vxlan_vni
*)p
;
597 vni
= XCALLOC(MTYPE_TMP
, sizeof(*vni
));
598 vni
->vni
= vnip
->vni
;
599 vni
->access_vlan
= vnip
->access_vlan
;
600 vni
->mcast_grp
= vnip
->mcast_grp
;
605 struct hash
*zebra_vxlan_vni_table_create(void)
607 return hash_create(zebra_vxlan_vni_hash_keymake
,
608 zebra_vxlan_vni_hash_cmp
, "Zebra Vxlan VNI Table");
611 void zebra_vxlan_vni_table_destroy(struct hash
*vni_table
)
614 hash_clean(vni_table
, zebra_vxlan_vni_free
);
615 hash_free(vni_table
);
619 int zebra_vxlan_if_vni_table_destroy(struct zebra_if
*zif
)
621 struct zebra_vxlan_vni_info
*vni_info
;
623 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
624 if (vni_info
->vni_table
) {
625 zebra_vxlan_if_vni_iterate(
626 zif
, zebra_vxlan_if_vni_entry_del_callback
, NULL
);
627 zebra_vxlan_vni_table_destroy(vni_info
->vni_table
);
628 vni_info
->vni_table
= NULL
;
633 int zebra_vxlan_if_vni_table_create(struct zebra_if
*zif
)
635 struct zebra_vxlan_vni_info
*vni_info
;
637 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
640 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
641 vni_info
->vni_table
= zebra_vxlan_vni_table_create();
642 if (!vni_info
->vni_table
)
648 struct zebra_vxlan_vni
*zebra_vxlan_if_vni_find(const struct zebra_if
*zif
,
651 struct zebra_vxlan_vni
*vnip
= NULL
;
652 const struct zebra_vxlan_vni_info
*vni_info
;
653 struct zebra_vxlan_vni vni_tmp
;
655 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
656 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
657 vnip
= (struct zebra_vxlan_vni
*)&vni_info
->vni
;
659 if (vni
&& (vnip
->vni
!= vni
))
665 /* For SVD, the VNI value is a required parameter. */
668 memset(&vni_tmp
, 0, sizeof(vni_tmp
));
670 vnip
= (struct zebra_vxlan_vni
*)hash_lookup(vni_info
->vni_table
,
673 /* TODO: For debugging. Remove later */
675 assert(vnip
->vni
== vni
);
680 static int zif_vlanid_vni_walker(struct zebra_if
*zif
,
681 struct zebra_vxlan_vni
*vnip
, void *arg
)
683 struct zebra_vxlan_if_vlan_ctx
*ctx
;
685 ctx
= (struct zebra_vxlan_if_vlan_ctx
*)arg
;
687 if (vnip
->access_vlan
== ctx
->vid
) {
689 return HASHWALK_ABORT
;
692 return HASHWALK_CONTINUE
;
695 struct zebra_vxlan_vni
*zebra_vxlan_if_vlanid_vni_find(struct zebra_if
*zif
,
698 struct zebra_vxlan_if_vlan_ctx ctx
= {};
700 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
705 zebra_vxlan_if_vni_walk(zif
, zif_vlanid_vni_walker
, &ctx
);
710 void zebra_vxlan_if_vni_iterate(struct zebra_if
*zif
,
711 int (*func
)(struct zebra_if
*zif
,
712 struct zebra_vxlan_vni
*, void *),
715 struct zebra_vxlan_vni_info
*vni_info
;
716 struct zebra_vxlan_vni
*vni
= NULL
;
717 struct zebra_vxlan_if_ctx ctx
;
719 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
720 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
721 vni
= zebra_vxlan_if_vni_find(zif
, 0);
726 memset(&ctx
, 0, sizeof(ctx
));
730 hash_iterate(vni_info
->vni_table
, zebra_vxlan_if_vni_iterate_callback
,
734 void zebra_vxlan_if_vni_walk(struct zebra_if
*zif
,
735 int (*func
)(struct zebra_if
*zif
,
736 struct zebra_vxlan_vni
*, void *),
739 struct zebra_vxlan_vni_info
*vni_info
;
740 struct zebra_vxlan_vni
*vni
= NULL
;
741 struct zebra_vxlan_if_ctx ctx
;
743 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
744 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
745 vni
= zebra_vxlan_if_vni_find(zif
, 0);
750 memset(&ctx
, 0, sizeof(ctx
));
754 hash_walk(vni_info
->vni_table
, zebra_vxlan_if_vni_walk_callback
, &ctx
);
757 vni_t
zebra_vxlan_if_access_vlan_vni_find(struct zebra_if
*zif
,
758 struct interface
*br_if
)
760 struct zebra_vxlan_vni
*vni
= NULL
;
762 /* Expected to be called only for vlan-unware bridges. In this case,
763 * we only support a per-VNI VXLAN interface model.
765 if (!IS_ZEBRA_VXLAN_IF_VNI(zif
))
768 vni
= zebra_vxlan_if_vni_find(zif
, 0);
774 int zebra_vxlan_if_vni_table_add_update(struct interface
*ifp
,
775 struct hash
*vni_table
)
777 struct zebra_if
*zif
;
778 struct zebra_vxlan_vni_info
*vni_info
;
779 struct zebra_vxlan_if_update_ctx ctx
;
781 zif
= (struct zebra_if
*)ifp
->info
;
783 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
785 memset(&ctx
, 0, sizeof(ctx
));
786 ctx
.old_vni_table
= vni_info
->vni_table
;
787 vni_info
->vni_table
= vni_table
;
789 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_add_update_vni
, &ctx
);
791 /* release kernel deleted vnis */
792 if (ctx
.old_vni_table
) {
793 if (hashcount(ctx
.old_vni_table
)) {
794 /* UGLY HACK: Put back the old table so that delete of
795 * MACs goes through and then flip back.
797 vni_info
->vni_table
= ctx
.old_vni_table
;
798 hash_iterate(ctx
.old_vni_table
,
799 zebra_vxlan_if_vni_clean
, zif
);
800 vni_info
->vni_table
= vni_table
;
802 zebra_vxlan_vni_table_destroy(ctx
.old_vni_table
);
803 ctx
.old_vni_table
= NULL
;
809 int zebra_vxlan_if_vni_mcast_group_add_update(struct interface
*ifp
,
811 struct in_addr
*mcast_group
)
813 struct zebra_if
*zif
;
814 struct zebra_vxlan_vni
*vni
;
815 struct zebra_vxlan_if_update_ctx ctx
;
817 zif
= (struct zebra_if
*)ifp
->info
;
819 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
822 vni
= zebra_vxlan_if_vni_find(zif
, vni_id
);
826 memset(&ctx
, 0, sizeof(ctx
));
827 ctx
.old_vni
.mcast_grp
= vni
->mcast_grp
;
828 ctx
.chgflags
= ZEBRA_VXLIF_MCAST_GRP_CHANGE
;
830 vni
->mcast_grp
= *mcast_group
;
832 return zebra_vxlan_if_update_vni(ifp
, vni
, &ctx
);
835 int zebra_vxlan_if_vni_mcast_group_del(struct interface
*ifp
, vni_t vni_id
,
836 struct in_addr
*mcast_group
)
838 struct zebra_if
*zif
= NULL
;
839 struct zebra_vxlan_vni
*vni
;
840 struct zebra_vxlan_if_update_ctx ctx
;
842 zif
= (struct zebra_if
*)ifp
->info
;
844 if (!IS_ZEBRA_VXLAN_IF_SVD(zif
))
847 vni
= zebra_vxlan_if_vni_find(zif
, vni_id
);
851 if (memcmp(mcast_group
, &vni
->mcast_grp
, sizeof(*mcast_group
)))
854 memset(&ctx
, 0, sizeof(ctx
));
855 ctx
.old_vni
.mcast_grp
= vni
->mcast_grp
;
856 ctx
.chgflags
= ZEBRA_VXLIF_MCAST_GRP_CHANGE
;
858 memset(&vni
->mcast_grp
, 0, sizeof(vni
->mcast_grp
));
860 return zebra_vxlan_if_update_vni(ifp
, vni
, &ctx
);
863 int zebra_vxlan_if_vni_down(struct interface
*ifp
, struct zebra_vxlan_vni
*vnip
)
866 struct zebra_if
*zif
;
867 struct zebra_l3vni
*zl3vni
;
868 struct zebra_evpn
*zevpn
;
870 /* Check if EVPN is enabled. */
871 if (!is_evpn_enabled())
878 zl3vni
= zl3vni_lookup(vni
);
880 /* process-if-down for l3-vni */
881 if (IS_ZEBRA_DEBUG_VXLAN
)
882 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp
->name
,
885 zebra_vxlan_process_l3vni_oper_down(zl3vni
);
887 /* process if-down for l2-vni */
888 if (IS_ZEBRA_DEBUG_VXLAN
)
889 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp
->name
,
892 /* Locate hash entry; it is expected to exist. */
893 zevpn
= zebra_evpn_lookup(vni
);
896 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
897 ifp
->name
, ifp
->ifindex
, vni
);
901 assert(zevpn
->vxlan_if
== ifp
);
903 /* remove from l3-vni list */
904 zl3vni
= zl3vni_from_vrf(zevpn
->vrf_id
);
906 listnode_delete(zl3vni
->l2vnis
, zevpn
);
908 zebra_evpn_vl_vxl_deref(vnip
->access_vlan
, vnip
->vni
, zif
);
910 /* Delete this VNI from BGP. */
911 zebra_evpn_send_del_to_client(zevpn
);
913 /* Free up all neighbors and MACs, if any. */
914 zebra_evpn_neigh_del_all(zevpn
, 1, 0, DEL_ALL_NEIGH
);
915 zebra_evpn_mac_del_all(zevpn
, 1, 0, DEL_ALL_MAC
);
917 /* Free up all remote VTEPs, if any. */
918 zebra_evpn_vtep_del_all(zevpn
, 1);
924 * Handle VxLAN interface down
926 int zebra_vxlan_if_down(struct interface
*ifp
)
928 struct zebra_if
*zif
;
929 struct zebra_vxlan_vni_info
*vni_info
;
931 /* Check if EVPN is enabled. */
932 if (!is_evpn_enabled())
938 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
939 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
940 return zebra_vxlan_if_vni_down(ifp
, &vni_info
->vni
);
943 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_vni_entry_down_callback
,
949 int zebra_vxlan_if_vni_up(struct interface
*ifp
, struct zebra_vxlan_vni
*vnip
)
952 struct zebra_if
*zif
;
953 struct zebra_evpn
*zevpn
;
954 struct zebra_l3vni
*zl3vni
;
956 /* Check if EVPN is enabled. */
957 if (!is_evpn_enabled())
964 zl3vni
= zl3vni_lookup(vni
);
966 /* we need to associate with SVI, if any, we can associate with
967 * svi-if only after association with vxlan-intf is complete
969 zl3vni
->svi_if
= zl3vni_map_to_svi_if(zl3vni
);
970 zl3vni
->mac_vlan_if
= zl3vni_map_to_mac_vlan_if(zl3vni
);
972 if (IS_ZEBRA_DEBUG_VXLAN
)
974 "Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s",
975 ifp
->name
, ifp
->ifindex
, vni
,
976 zl3vni
->svi_if
? zl3vni
->svi_if
->name
: "NIL",
977 zl3vni
->mac_vlan_if
? zl3vni
->mac_vlan_if
->name
980 if (is_l3vni_oper_up(zl3vni
))
981 zebra_vxlan_process_l3vni_oper_up(zl3vni
);
983 /* Handle L2-VNI add */
984 struct interface
*vlan_if
= NULL
;
986 if (IS_ZEBRA_DEBUG_VXLAN
)
987 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp
->name
,
990 /* Locate hash entry; it is expected to exist. */
991 zevpn
= zebra_evpn_lookup(vni
);
994 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
995 ifp
->name
, ifp
->ifindex
, vni
);
999 assert(zevpn
->vxlan_if
== ifp
);
1000 zebra_evpn_vl_vxl_ref(vnip
->access_vlan
, vnip
->vni
, zif
);
1001 vlan_if
= zvni_map_to_svi(vnip
->access_vlan
,
1002 zif
->brslave_info
.br_if
);
1004 zevpn
->svi_if
= vlan_if
;
1005 zevpn
->vrf_id
= vlan_if
->vrf
->vrf_id
;
1006 zl3vni
= zl3vni_from_vrf(vlan_if
->vrf
->vrf_id
);
1008 listnode_add_sort_nodup(zl3vni
->l2vnis
, zevpn
);
1011 /* If part of a bridge, inform BGP about this VNI. */
1012 /* Also, read and populate local MACs and neighbors. */
1013 if (zif
->brslave_info
.br_if
) {
1014 zebra_evpn_send_add_to_client(zevpn
);
1015 zebra_evpn_read_mac_neigh(zevpn
, ifp
);
1023 * Handle VxLAN interface up - update BGP if required.
1025 int zebra_vxlan_if_up(struct interface
*ifp
)
1027 struct zebra_if
*zif
;
1028 struct zebra_vxlan_vni_info
*vni_info
;
1030 /* Check if EVPN is enabled. */
1031 if (!is_evpn_enabled())
1037 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1038 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1039 return zebra_vxlan_if_vni_up(ifp
, &vni_info
->vni
);
1042 zebra_vxlan_if_vni_iterate(zif
, zebra_vxlan_if_vni_entry_up_callback
,
1048 int zebra_vxlan_if_vni_del(struct interface
*ifp
, vni_t vni
)
1050 struct zebra_if
*zif
;
1051 struct zebra_vxlan_vni
*vnip
;
1052 struct zebra_vxlan_vni vni_tmp
;
1053 struct zebra_vxlan_vni_info
*vni_info
;
1058 /* This should be called in SVD context only */
1059 assert(IS_ZEBRA_VXLAN_IF_SVD(zif
));
1061 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1062 memset(&vni_tmp
, 0, sizeof(vni_tmp
));
1065 vnip
= hash_release(vni_info
->vni_table
, &vni_tmp
);
1067 zebra_vxlan_if_vni_entry_del(zif
, vnip
);
1068 zebra_vxlan_vni_free(vnip
);
1074 * Handle VxLAN interface delete. Locate and remove entry in hash table
1075 * and update BGP, if required.
1077 int zebra_vxlan_if_del(struct interface
*ifp
)
1079 struct zebra_if
*zif
;
1080 struct zebra_vxlan_vni_info
*vni_info
;
1085 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1086 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1087 zebra_evpn_vl_vxl_deref(vni_info
->vni
.access_vlan
,
1088 vni_info
->vni
.vni
, zif
);
1089 return zebra_vxlan_if_del_vni(ifp
, &vni_info
->vni
);
1092 zebra_vxlan_if_vni_table_destroy(zif
);
1098 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
1100 int zebra_vxlan_if_update(struct interface
*ifp
,
1101 struct zebra_vxlan_if_update_ctx
*ctx
)
1103 struct zebra_if
*zif
;
1104 struct zebra_vxlan_vni_info
*vni_info
;
1109 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1110 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1111 return zebra_vxlan_if_update_vni(ifp
, &vni_info
->vni
, ctx
);
1114 zebra_vxlan_if_vni_iterate(
1115 zif
, zebra_vxlan_if_vni_entry_update_callback
, ctx
);
1120 int zebra_vxlan_if_vni_add(struct interface
*ifp
, struct zebra_vxlan_vni
*vni
)
1122 struct zebra_if
*zif
;
1123 struct zebra_vxlan_vni_info
*vni_info
;
1128 /* This should be called in SVD context only */
1129 assert(IS_ZEBRA_VXLAN_IF_SVD(zif
));
1131 /* First insert into the table */
1132 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1133 hash_get(vni_info
->vni_table
, (void *)vni
, zebra_vxlan_vni_alloc
);
1135 return zebra_vxlan_if_vni_entry_add(zif
, vni
);
1139 * Handle VxLAN interface add.
1141 int zebra_vxlan_if_add(struct interface
*ifp
)
1144 struct zebra_if
*zif
;
1145 struct zebra_vxlan_vni_info
*vni_info
;
1150 if (IS_ZEBRA_VXLAN_IF_VNI(zif
)) {
1151 vni_info
= VNI_INFO_FROM_ZEBRA_IF(zif
);
1152 zebra_evpn_vl_vxl_ref(vni_info
->vni
.access_vlan
,
1153 vni_info
->vni
.vni
, zif
);
1154 return zebra_vxlan_if_add_vni(ifp
, &vni_info
->vni
);
1157 ret
= zebra_vxlan_if_vni_table_create(zif
);