]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan_if.c
zebra: Bug fixes in fdb read for flooded traffic and remote fdb cleanup upon vni...
[mirror_frr.git] / zebra / zebra_vxlan_if.c
1 /*
2 * Zebra EVPN for VxLAN interface handling
3 *
4 * Copyright (C) 2021 Cumulus Networks, Inc.
5 * Vivek Venkatraman, Stephen Worley, Sharath Ramamurthy
6 *
7 * This file is part of FRR.
8 *
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
12 * later version.
13 *
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.
18 */
19
20 #include <zebra.h>
21
22 #include "hash.h"
23 #include "if.h"
24 #include "jhash.h"
25 #include "linklist.h"
26 #include "log.h"
27 #include "memory.h"
28 #include "prefix.h"
29 #include "stream.h"
30 #include "table.h"
31 #include "vlan.h"
32 #include "vxlan.h"
33 #ifdef GNU_LINUX
34 #include <linux/neighbour.h>
35 #endif
36
37 #include "zebra/zebra_router.h"
38 #include "zebra/debug.h"
39 #include "zebra/interface.h"
40 #include "zebra/rib.h"
41 #include "zebra/rt.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"
56
57 static unsigned int zebra_vxlan_vni_hash_keymake(const void *p)
58 {
59 const struct zebra_vxlan_vni *vni;
60
61 vni = (const struct zebra_vxlan_vni *)p;
62 return jhash_1word(vni->vni, 0);
63 }
64
65 static bool zebra_vxlan_vni_hash_cmp(const void *p1, const void *p2)
66 {
67 const struct zebra_vxlan_vni *vni1;
68 const struct zebra_vxlan_vni *vni2;
69
70 vni1 = (const struct zebra_vxlan_vni *)p1;
71 vni2 = (const struct zebra_vxlan_vni *)p2;
72
73 return (vni1->vni == vni2->vni);
74 }
75
76 static int zebra_vxlan_if_vni_walk_callback(struct hash_bucket *bucket,
77 void *ctxt)
78 {
79 int ret;
80 struct zebra_vxlan_vni *vni;
81 struct zebra_vxlan_if_ctx *ctx;
82
83 vni = (struct zebra_vxlan_vni *)bucket->data;
84 ctx = (struct zebra_vxlan_if_ctx *)ctxt;
85
86 ret = ctx->func(ctx->zif, vni, ctx->arg);
87 return ret;
88 }
89
90 static void zebra_vxlan_if_vni_iterate_callback(struct hash_bucket *bucket,
91 void *ctxt)
92 {
93 struct zebra_vxlan_vni *vni;
94 struct zebra_vxlan_if_ctx *ctx;
95
96 vni = (struct zebra_vxlan_vni *)bucket->data;
97 ctx = (struct zebra_vxlan_if_ctx *)ctxt;
98
99 ctx->func(ctx->zif, vni, ctx->arg);
100 }
101
102 static int zebra_vxlan_if_del_vni(struct interface *ifp,
103 struct zebra_vxlan_vni *vnip)
104 {
105 vni_t vni;
106 struct zebra_if *zif;
107 struct zebra_evpn *zevpn;
108 struct zebra_l3vni *zl3vni;
109 struct interface *br_if;
110
111 /* Check if EVPN is enabled. */
112 if (!is_evpn_enabled())
113 return 0;
114
115 zif = ifp->info;
116 assert(zif);
117 vni = vnip->vni;
118
119 zl3vni = zl3vni_lookup(vni);
120 if (zl3vni) {
121
122 if (IS_ZEBRA_DEBUG_VXLAN)
123 zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
124 ifp->ifindex);
125
126 /* process oper-down for l3-vni */
127 zebra_vxlan_process_l3vni_oper_down(zl3vni);
128
129 /* remove the association with vxlan_if */
130 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
131 zl3vni->vxlan_if = NULL;
132 zl3vni->vid = 0;
133 br_if = zif->brslave_info.br_if;
134 zl3vni_bridge_if_set(zl3vni, br_if, false /* unset */);
135 } else {
136
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,
140 ifp->ifindex);
141
142 /* Locate hash entry; it is expected to exist. */
143 zevpn = zebra_evpn_lookup(vni);
144 if (!zevpn) {
145 zlog_debug(
146 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
147 ifp->name, ifp->ifindex, vni);
148 return 0;
149 }
150
151 /* remove from l3-vni list */
152 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
153 if (zl3vni)
154 listnode_delete(zl3vni->l2vnis, zevpn);
155 /* Delete VNI from BGP. */
156 zebra_evpn_send_del_to_client(zevpn);
157
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);
161
162 /* Free up all remote VTEPs, if any. */
163 zebra_evpn_vtep_del_all(zevpn, 1);
164
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);
170 return -1;
171 }
172 }
173 return 0;
174 }
175
176 static int zebra_vxlan_if_update_vni(struct interface *ifp,
177 struct zebra_vxlan_vni *vnip,
178 uint16_t chgflags)
179 {
180 vni_t vni;
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;
187
188 /* Check if EVPN is enabled. */
189 if (!is_evpn_enabled())
190 return 0;
191
192 zif = ifp->info;
193 assert(zif);
194 vxl = &zif->l2info.vxl;
195 vni = vnip->vni;
196
197 zl3vni = zl3vni_lookup(vni);
198 if (zl3vni) {
199
200 if (IS_ZEBRA_DEBUG_VXLAN)
201 zlog_debug(
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,
205 chgflags);
206
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);
211 return 0;
212 }
213
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);
218 return 0;
219 }
220
221 /* access-vlan change - process oper down, associate with new
222 * svi_if and then process oper up again
223 */
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(
234 zl3vni);
235 }
236 }
237
238 /*
239 * local-ip change - process oper down, associate with new
240 * local-ip and then process oper up again
241 */
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(
248 zl3vni);
249 }
250 }
251
252 /* Update local tunnel IP. */
253 zl3vni->local_vtep_ip = vxl->vtep_ip;
254
255 zl3vni->vid = (zl3vni->vid != vnip->access_vlan)
256 ? vnip->access_vlan
257 : zl3vni->vid;
258 br_if = zif->brslave_info.br_if;
259 zl3vni_bridge_if_set(zl3vni, br_if, true /* set */);
260
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);
265 }
266 } else {
267
268 /* Update VNI hash. */
269 zevpn = zebra_evpn_lookup(vni);
270 if (!zevpn) {
271 zlog_debug(
272 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
273 ifp->name, ifp->ifindex, vni);
274 return -1;
275 }
276
277 if (IS_ZEBRA_DEBUG_VXLAN)
278 zlog_debug(
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,
282 chgflags);
283
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);
294 return 0;
295 }
296
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)
301 */
302 zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
303 zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
304 }
305
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,
309 zevpn->mcast_grp);
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
315 */
316 zebra_evpn_es_set_base_evpn(zevpn);
317 }
318 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
319 zevpn->vid = (zevpn->vid != vnip->access_vlan)
320 ? vnip->access_vlan
321 : zevpn->vid;
322 br_if = zif->brslave_info.br_if;
323 zevpn_bridge_if_set(zevpn, br_if, true /* set */);
324
325 vlan_if = zvni_map_to_svi(vnip->access_vlan, br_if);
326 if (vlan_if)
327 zevpn->svi_if = vlan_if;
328
329 /* Take further actions needed.
330 * Note that if we are here, there is a change of interest.
331 */
332 /* If down or not mapped to a bridge, we're done. */
333 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
334 return 0;
335
336 /* Inform BGP, if there is a change of interest. */
337 if (chgflags &
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);
341
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).
346 */
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;
352
353 zebra_evpn_read_mac_neigh(zevpn, ifp);
354
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);
359
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);
364 }
365 }
366
367 return 0;
368 }
369
370 static int zebra_vxlan_if_add_vni(struct interface *ifp,
371 struct zebra_vxlan_vni *vnip)
372 {
373 vni_t vni;
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;
379
380 /* Check if EVPN is enabled. */
381 if (!is_evpn_enabled())
382 return 0;
383
384 zif = ifp->info;
385 assert(zif);
386 vxl = &zif->l2info.vxl;
387 vni = vnip->vni;
388
389 zl3vni = zl3vni_lookup(vni);
390 if (zl3vni) {
391
392 /* process if-add for l3-vni*/
393 if (IS_ZEBRA_DEBUG_VXLAN)
394 zlog_debug(
395 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
396 vni, ifp->name, ifp->ifindex, vnip->access_vlan,
397 &vxl->vtep_ip,
398 zif->brslave_info.bridge_ifindex);
399
400 /* associate with vxlan_if */
401 zl3vni->local_vtep_ip = vxl->vtep_ip;
402 zl3vni->vxlan_if = ifp;
403
404 /*
405 * Associate with SVI, if any. We can associate with svi-if only
406 * after association with vxlan_if is complete
407 */
408 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
409
410 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
411
412 zl3vni->vid = vnip->access_vlan;
413 br_if = zif->brslave_info.br_if;
414 zl3vni_bridge_if_set(zl3vni, br_if, true /* set */);
415
416 if (is_l3vni_oper_up(zl3vni))
417 zebra_vxlan_process_l3vni_oper_up(zl3vni);
418 } else {
419
420 /* process if-add for l2-vni */
421 struct interface *vlan_if = NULL;
422
423 /* Create or update EVPN hash. */
424 zevpn = zebra_evpn_lookup(vni);
425 if (!zevpn)
426 zevpn = zebra_evpn_add(vni);
427
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,
431 zevpn->mcast_grp);
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
437 */
438 zebra_evpn_es_set_base_evpn(zevpn);
439 }
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);
444 if (vlan_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);
449 if (zl3vni)
450 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
451 }
452
453 if (IS_ZEBRA_DEBUG_VXLAN)
454 zlog_debug(
455 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
456 vni,
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);
461
462 /* If down or not mapped to a bridge, we're done. */
463 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
464 return 0;
465
466 /* Inform BGP */
467 zebra_evpn_send_add_to_client(zevpn);
468
469 /* Read and populate local MACs and neighbors */
470 zebra_evpn_read_mac_neigh(zevpn, ifp);
471 }
472
473 return 0;
474 }
475
476 static void zebra_vxlan_if_vni_entry_del(struct zebra_if *zif,
477 struct zebra_vxlan_vni *vni)
478 {
479 if (vni) {
480 zebra_evpn_vl_vxl_deref(vni->access_vlan, vni->vni, zif);
481 zebra_vxlan_if_del_vni(zif->ifp, vni);
482 }
483 }
484
485 static int zebra_vxlan_if_vni_entry_add(struct zebra_if *zif,
486 struct zebra_vxlan_vni *vni)
487 {
488 zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif);
489 return zebra_vxlan_if_add_vni(zif->ifp, vni);
490 }
491
492 static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif,
493 struct zebra_vxlan_vni *vni,
494 void *ctxt)
495 {
496 struct hash *old_vni_table;
497 struct zebra_vxlan_vni vni_tmp;
498 struct zebra_vxlan_vni *old_vni = NULL;
499
500 old_vni_table = (struct hash *)ctxt;
501 memcpy(&vni_tmp, vni, sizeof(*vni));
502
503 old_vni = hash_release(old_vni_table, &vni_tmp);
504 if (!old_vni) {
505 if (IS_ZEBRA_DEBUG_VXLAN)
506 zlog_debug("vxlan %s adding vni(%d, %d)",
507 zif->ifp->name, vni->vni, vni->access_vlan);
508
509 zebra_vxlan_if_vni_entry_add(zif, &vni_tmp);
510 return 0;
511 }
512
513 /* copy mcast group from old_vni as thats not being changed here */
514 vni->mcast_grp = old_vni->mcast_grp;
515
516 if (old_vni->access_vlan != vni->access_vlan) {
517 if (IS_ZEBRA_DEBUG_VXLAN)
518 zlog_debug(
519 "vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
520 zif->ifp->name, old_vni->vni,
521 old_vni->access_vlan, vni->vni,
522 vni->access_vlan);
523
524 zebra_evpn_vl_vxl_deref(old_vni->access_vlan, old_vni->vni,
525 zif);
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);
530 }
531
532 return 0;
533 }
534
535 static int zebra_vxlan_if_vni_entry_update_callback(struct zebra_if *zif,
536 struct zebra_vxlan_vni *vni,
537 void *ctxt)
538 {
539 uint16_t *chgflags;
540
541 chgflags = (uint16_t *)ctxt;
542 return zebra_vxlan_if_update_vni(zif->ifp, vni, *chgflags);
543 }
544
545 static int zebra_vxlan_if_vni_entry_del_callback(struct zebra_if *zif,
546 struct zebra_vxlan_vni *vni,
547 void *ctxt)
548 {
549 zebra_vxlan_if_vni_entry_del(zif, vni);
550 return 0;
551 }
552
553 static int zebra_vxlan_if_vni_entry_down_callback(struct zebra_if *zif,
554 struct zebra_vxlan_vni *vni,
555 void *ctxt)
556 {
557 return zebra_vxlan_if_vni_down(zif->ifp, vni);
558 }
559
560 static int zebra_vxlan_if_vni_entry_up_callback(struct zebra_if *zif,
561 struct zebra_vxlan_vni *vni,
562 void *ctxt)
563 {
564 return zebra_vxlan_if_vni_up(zif->ifp, vni);
565 }
566
567 static void zebra_vxlan_if_vni_clean(struct hash_bucket *bucket, void *arg)
568 {
569 struct zebra_if *zif;
570 struct zebra_vxlan_vni *vni;
571
572 zif = (struct zebra_if *)arg;
573 vni = (struct zebra_vxlan_vni *)bucket->data;
574 zebra_vxlan_if_vni_entry_del(zif, vni);
575 }
576
577 void zebra_vxlan_vni_free(void *arg)
578 {
579 struct zebra_vxlan_vni *vni;
580
581 vni = (struct zebra_vxlan_vni *)arg;
582
583 XFREE(MTYPE_TMP, vni);
584 }
585
586 void *zebra_vxlan_vni_alloc(void *p)
587 {
588 struct zebra_vxlan_vni *vni;
589 const struct zebra_vxlan_vni *vnip;
590
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;
596
597 return (void *)vni;
598 }
599
600 struct hash *zebra_vxlan_vni_table_create(void)
601 {
602 return hash_create(zebra_vxlan_vni_hash_keymake,
603 zebra_vxlan_vni_hash_cmp, "Zebra Vxlan VNI Table");
604 }
605
606 void zebra_vxlan_vni_table_destroy(struct hash *vni_table)
607 {
608 if (vni_table) {
609 hash_clean(vni_table, zebra_vxlan_vni_free);
610 hash_free(vni_table);
611 }
612 }
613
614 int zebra_vxlan_if_vni_table_destroy(struct zebra_if *zif)
615 {
616 struct zebra_vxlan_vni_info *vni_info;
617
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;
624 }
625 return 0;
626 }
627
628 int zebra_vxlan_if_vni_table_create(struct zebra_if *zif)
629 {
630 struct zebra_vxlan_vni_info *vni_info;
631
632 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
633 return 0;
634
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)
638 return -ENOMEM;
639
640 return 0;
641 }
642
643 struct zebra_vxlan_vni *zebra_vxlan_if_vni_find(const struct zebra_if *zif,
644 vni_t vni)
645 {
646 struct zebra_vxlan_vni *vnip = NULL;
647 const struct zebra_vxlan_vni_info *vni_info;
648 struct zebra_vxlan_vni vni_tmp;
649
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;
653 assert(vnip);
654 if (vni && (vnip->vni != vni))
655 vnip = NULL;
656
657 return vnip;
658 }
659
660 /* For SVD, the VNI value is a required parameter. */
661 assert(vni);
662
663 memset(&vni_tmp, 0, sizeof(vni_tmp));
664 vni_tmp.vni = vni;
665 vnip = (struct zebra_vxlan_vni *)hash_lookup(vni_info->vni_table,
666 (void *)&vni_tmp);
667
668 /* TODO: For debugging. Remove later */
669 if (vnip)
670 assert(vnip->vni == vni);
671
672 return vnip;
673 }
674
675 void zebra_vxlan_if_vni_iterate(struct zebra_if *zif,
676 int (*func)(struct zebra_if *zif,
677 struct zebra_vxlan_vni *, void *),
678 void *arg)
679 {
680 struct zebra_vxlan_vni_info *vni_info;
681 struct zebra_vxlan_vni *vni = NULL;
682 struct zebra_vxlan_if_ctx ctx;
683
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);
687 func(zif, vni, arg);
688 return;
689 }
690
691 memset(&ctx, 0, sizeof(ctx));
692 ctx.zif = zif;
693 ctx.func = func;
694 ctx.arg = arg;
695 hash_iterate(vni_info->vni_table, zebra_vxlan_if_vni_iterate_callback,
696 &ctx);
697 }
698
699 void zebra_vxlan_if_vni_walk(struct zebra_if *zif,
700 int (*func)(struct zebra_if *zif,
701 struct zebra_vxlan_vni *, void *),
702 void *arg)
703 {
704 struct zebra_vxlan_vni_info *vni_info;
705 struct zebra_vxlan_vni *vni = NULL;
706 struct zebra_vxlan_if_ctx ctx;
707
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);
711 func(zif, vni, arg);
712 return;
713 }
714
715 memset(&ctx, 0, sizeof(ctx));
716 ctx.zif = zif;
717 ctx.func = func;
718 ctx.arg = arg;
719 hash_walk(vni_info->vni_table, zebra_vxlan_if_vni_walk_callback, &ctx);
720 }
721
722 vni_t zebra_vxlan_if_access_vlan_vni_find(struct zebra_if *zif,
723 struct interface *br_if)
724 {
725 struct zebra_vxlan_vni *vni = NULL;
726
727 /* Expected to be called only for vlan-unware bridges. In this case,
728 * we only support a per-VNI VXLAN interface model.
729 */
730 if (!IS_ZEBRA_VXLAN_IF_VNI(zif))
731 return 0;
732
733 vni = zebra_vxlan_if_vni_find(zif, 0);
734 assert(vni);
735
736 return vni->vni;
737 }
738
739 int zebra_vxlan_if_vni_table_add_update(struct interface *ifp,
740 struct hash *vni_table)
741 {
742 struct zebra_if *zif;
743 struct hash *old_vni_table = NULL;
744 struct zebra_vxlan_vni_info *vni_info;
745
746 zif = (struct zebra_if *)ifp->info;
747
748 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
749
750 old_vni_table = vni_info->vni_table;
751 vni_info->vni_table = vni_table;
752
753 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_add_update_vni,
754 old_vni_table);
755
756 /* release kernel deleted vnis */
757 if (old_vni_table) {
758 if (hashcount(old_vni_table))
759 hash_iterate(old_vni_table, zebra_vxlan_if_vni_clean,
760 zif);
761 zebra_vxlan_vni_table_destroy(old_vni_table);
762 }
763
764 return 0;
765 }
766
767 int zebra_vxlan_if_vni_mcast_group_update(struct interface *ifp, vni_t vni_id,
768 struct in_addr *mcast_group)
769 {
770 struct zebra_if *zif;
771 struct zebra_vxlan_vni *vni;
772
773 zif = (struct zebra_if *)ifp->info;
774
775 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
776 return 0;
777
778 vni = zebra_vxlan_if_vni_find(zif, vni_id);
779 if (!vni)
780 return 0;
781
782 if (mcast_group)
783 vni->mcast_grp = *mcast_group;
784 else
785 memset(&vni->mcast_grp, 0, sizeof(vni->mcast_grp));
786
787 return zebra_vxlan_if_update_vni(ifp, vni,
788 ZEBRA_VXLIF_MCAST_GRP_CHANGE);
789 }
790
791 int zebra_vxlan_if_vni_down(struct interface *ifp, struct zebra_vxlan_vni *vnip)
792 {
793 vni_t vni;
794 struct zebra_if *zif;
795 struct zebra_l3vni *zl3vni;
796 struct zebra_evpn *zevpn;
797
798 /* Check if EVPN is enabled. */
799 if (!is_evpn_enabled())
800 return 0;
801
802 zif = ifp->info;
803 assert(zif);
804 vni = vnip->vni;
805
806 zl3vni = zl3vni_lookup(vni);
807 if (zl3vni) {
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,
811 ifp->ifindex, vni);
812
813 zebra_vxlan_process_l3vni_oper_down(zl3vni);
814 } else {
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,
818 ifp->ifindex, vni);
819
820 /* Locate hash entry; it is expected to exist. */
821 zevpn = zebra_evpn_lookup(vni);
822 if (!zevpn) {
823 zlog_debug(
824 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
825 ifp->name, ifp->ifindex, vni);
826 return -1;
827 }
828
829 assert(zevpn->vxlan_if == ifp);
830
831 /* remove from l3-vni list */
832 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
833 if (zl3vni)
834 listnode_delete(zl3vni->l2vnis, zevpn);
835
836 /* Delete this VNI from BGP. */
837 zebra_evpn_send_del_to_client(zevpn);
838
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);
842
843 /* Free up all remote VTEPs, if any. */
844 zebra_evpn_vtep_del_all(zevpn, 1);
845 }
846 return 0;
847 }
848
849 /*
850 * Handle VxLAN interface down
851 */
852 int zebra_vxlan_if_down(struct interface *ifp)
853 {
854 struct zebra_if *zif;
855 struct zebra_vxlan_vni_info *vni_info;
856
857 /* Check if EVPN is enabled. */
858 if (!is_evpn_enabled())
859 return 0;
860
861 zif = ifp->info;
862 assert(zif);
863
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);
867 }
868
869 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_vni_entry_down_callback,
870 NULL);
871
872 return 0;
873 }
874
875 int zebra_vxlan_if_vni_up(struct interface *ifp, struct zebra_vxlan_vni *vnip)
876 {
877 vni_t vni;
878 struct zebra_if *zif;
879 struct zebra_evpn *zevpn;
880 struct zebra_l3vni *zl3vni;
881
882 /* Check if EVPN is enabled. */
883 if (!is_evpn_enabled())
884 return 0;
885
886 zif = ifp->info;
887 assert(zif);
888 vni = vnip->vni;
889
890 zl3vni = zl3vni_lookup(vni);
891 if (zl3vni) {
892 /* we need to associate with SVI, if any, we can associate with
893 * svi-if only after association with vxlan-intf is complete
894 */
895 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
896 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
897
898 if (IS_ZEBRA_DEBUG_VXLAN)
899 zlog_debug(
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
904 : "NIL");
905
906 if (is_l3vni_oper_up(zl3vni))
907 zebra_vxlan_process_l3vni_oper_up(zl3vni);
908 } else {
909 /* Handle L2-VNI add */
910 struct interface *vlan_if = NULL;
911
912 if (IS_ZEBRA_DEBUG_VXLAN)
913 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
914 ifp->ifindex, vni);
915
916 /* Locate hash entry; it is expected to exist. */
917 zevpn = zebra_evpn_lookup(vni);
918 if (!zevpn) {
919 zlog_debug(
920 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
921 ifp->name, ifp->ifindex, vni);
922 return -1;
923 }
924
925 assert(zevpn->vxlan_if == ifp);
926 vlan_if = zvni_map_to_svi(vnip->access_vlan,
927 zif->brslave_info.br_if);
928 if (vlan_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);
932 if (zl3vni)
933 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
934 }
935
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);
941 }
942 }
943
944 return 0;
945 }
946
947 /*
948 * Handle VxLAN interface up - update BGP if required.
949 */
950 int zebra_vxlan_if_up(struct interface *ifp)
951 {
952 struct zebra_if *zif;
953 struct zebra_vxlan_vni_info *vni_info;
954
955 /* Check if EVPN is enabled. */
956 if (!is_evpn_enabled())
957 return 0;
958
959 zif = ifp->info;
960 assert(zif);
961
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);
965 }
966
967 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_vni_entry_up_callback,
968 NULL);
969
970 return 0;
971 }
972
973 int zebra_vxlan_if_vni_del(struct interface *ifp, vni_t vni)
974 {
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;
979
980 zif = ifp->info;
981 assert(zif);
982
983 /* This should be called in SVD context only */
984 assert(IS_ZEBRA_VXLAN_IF_SVD(zif));
985
986 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
987 memset(&vni_tmp, 0, sizeof(vni_tmp));
988 vni_tmp.vni = vni;
989
990 vnip = hash_release(vni_info->vni_table, &vni_tmp);
991 if (vnip) {
992 zebra_vxlan_if_vni_entry_del(zif, vnip);
993 zebra_vxlan_vni_free(vnip);
994 }
995 return 0;
996 }
997
998 /*
999 * Handle VxLAN interface delete. Locate and remove entry in hash table
1000 * and update BGP, if required.
1001 */
1002 int zebra_vxlan_if_del(struct interface *ifp)
1003 {
1004 struct zebra_if *zif;
1005 struct zebra_vxlan_vni_info *vni_info;
1006
1007 zif = ifp->info;
1008 assert(zif);
1009
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);
1015 }
1016
1017 zebra_vxlan_if_vni_table_destroy(zif);
1018
1019 return 0;
1020 }
1021
1022 /*
1023 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
1024 */
1025 int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
1026 {
1027 struct zebra_if *zif;
1028 struct zebra_vxlan_vni_info *vni_info;
1029
1030 zif = ifp->info;
1031 assert(zif);
1032
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);
1036 }
1037
1038 zebra_vxlan_if_vni_iterate(
1039 zif, zebra_vxlan_if_vni_entry_update_callback, &chgflags);
1040
1041 return 0;
1042 }
1043
1044 int zebra_vxlan_if_vni_add(struct interface *ifp, struct zebra_vxlan_vni *vni)
1045 {
1046 struct zebra_if *zif;
1047 struct zebra_vxlan_vni_info *vni_info;
1048
1049 zif = ifp->info;
1050 assert(zif);
1051
1052 /* This should be called in SVD context only */
1053 assert(IS_ZEBRA_VXLAN_IF_SVD(zif));
1054
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);
1058
1059 return zebra_vxlan_if_vni_entry_add(zif, vni);
1060 }
1061
1062 /*
1063 * Handle VxLAN interface add.
1064 */
1065 int zebra_vxlan_if_add(struct interface *ifp)
1066 {
1067 int ret;
1068 struct zebra_if *zif;
1069 struct zebra_vxlan_vni_info *vni_info;
1070
1071 zif = ifp->info;
1072 assert(zif);
1073
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);
1079 }
1080
1081 ret = zebra_vxlan_if_vni_table_create(zif);
1082 if (ret < 0)
1083 return ret;
1084
1085 return 0;
1086 }