]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vxlan_if.c
Merge pull request #13374 from opensourcerouting/build-fix-rmap-yang
[mirror_frr.git] / zebra / zebra_vxlan_if.c
CommitLineData
0adeb5fd
SR
1/*
2 * Zebra EVPN for VxLAN interface handling
3 *
96c25556 4 * Copyright (C) 2021 Cumulus Networks, Inc.
0adeb5fd
SR
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
96c25556 57static unsigned int zebra_vxlan_vni_hash_keymake(const void *p)
0adeb5fd 58{
96c25556 59 const struct zebra_vxlan_vni *vni;
0adeb5fd 60
96c25556
SR
61 vni = (const struct zebra_vxlan_vni *)p;
62 return jhash_1word(vni->vni, 0);
63}
0adeb5fd 64
96c25556
SR
65static 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;
0adeb5fd 69
96c25556
SR
70 vni1 = (const struct zebra_vxlan_vni *)p1;
71 vni2 = (const struct zebra_vxlan_vni *)p2;
0adeb5fd 72
96c25556
SR
73 return (vni1->vni == vni2->vni);
74}
0adeb5fd 75
96c25556
SR
76static 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;
0adeb5fd 82
96c25556
SR
83 vni = (struct zebra_vxlan_vni *)bucket->data;
84 ctx = (struct zebra_vxlan_if_ctx *)ctxt;
0adeb5fd 85
96c25556
SR
86 ret = ctx->func(ctx->zif, vni, ctx->arg);
87 return ret;
88}
0adeb5fd 89
96c25556
SR
90static void zebra_vxlan_if_vni_iterate_callback(struct hash_bucket *bucket,
91 void *ctxt)
0adeb5fd 92{
96c25556
SR
93 struct zebra_vxlan_vni *vni;
94 struct zebra_vxlan_if_ctx *ctx;
0adeb5fd 95
96c25556
SR
96 vni = (struct zebra_vxlan_vni *)bucket->data;
97 ctx = (struct zebra_vxlan_if_ctx *)ctxt;
0adeb5fd 98
96c25556 99 ctx->func(ctx->zif, vni, ctx->arg);
0adeb5fd
SR
100}
101
96c25556
SR
102static int zebra_vxlan_if_del_vni(struct interface *ifp,
103 struct zebra_vxlan_vni *vnip)
0adeb5fd
SR
104{
105 vni_t vni;
96c25556
SR
106 struct zebra_if *zif;
107 struct zebra_evpn *zevpn;
108 struct zebra_l3vni *zl3vni;
efde4f25 109 struct interface *br_if;
0adeb5fd
SR
110
111 /* Check if EVPN is enabled. */
112 if (!is_evpn_enabled())
113 return 0;
114
115 zif = ifp->info;
116 assert(zif);
0adeb5fd
SR
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;
efde4f25
SR
132 zl3vni->vid = 0;
133 br_if = zif->brslave_info.br_if;
134 zl3vni_bridge_if_set(zl3vni, br_if, false /* unset */);
0adeb5fd
SR
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. */
9464e5b8
SR
159 zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
160 zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
0adeb5fd
SR
161
162 /* Free up all remote VTEPs, if any. */
9464e5b8 163 zebra_evpn_vtep_del_all(zevpn, 1);
0adeb5fd
SR
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
96c25556
SR
176static int zebra_vxlan_if_update_vni(struct interface *ifp,
177 struct zebra_vxlan_vni *vnip,
00d30205 178 struct zebra_vxlan_if_update_ctx *ctx)
0adeb5fd
SR
179{
180 vni_t vni;
00d30205 181 uint16_t chgflags;
182 vlanid_t access_vlan;
96c25556
SR
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;
efde4f25 188 struct interface *br_if;
0adeb5fd
SR
189
190 /* Check if EVPN is enabled. */
191 if (!is_evpn_enabled())
192 return 0;
193
194 zif = ifp->info;
195 assert(zif);
96c25556 196 vxl = &zif->l2info.vxl;
0adeb5fd 197 vni = vnip->vni;
00d30205 198 chgflags = ctx->chgflags;
0adeb5fd
SR
199
200 zl3vni = zl3vni_lookup(vni);
201 if (zl3vni) {
202
203 if (IS_ZEBRA_DEBUG_VXLAN)
204 zlog_debug(
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,
208 chgflags);
209
210 /* Removed from bridge? Cleanup and return */
0bbad9d1
SW
211 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) &&
212 (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
0adeb5fd
SR
213 zebra_vxlan_process_l3vni_oper_down(zl3vni);
214 return 0;
215 }
216
0bbad9d1
SW
217 if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE) &&
218 if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) {
0adeb5fd
SR
219 zebra_vxlan_process_l3vni_oper_down(zl3vni);
220 zebra_vxlan_process_l3vni_oper_up(zl3vni);
221 return 0;
222 }
223
224 /* access-vlan change - process oper down, associate with new
225 * svi_if and then process oper up again
226 */
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(
237 zl3vni);
238 }
239 }
240
241 /*
242 * local-ip change - process oper down, associate with new
243 * local-ip and then process oper up again
244 */
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(
251 zl3vni);
252 }
253 }
254
255 /* Update local tunnel IP. */
256 zl3vni->local_vtep_ip = vxl->vtep_ip;
257
efde4f25
SR
258 zl3vni->vid = (zl3vni->vid != vnip->access_vlan)
259 ? vnip->access_vlan
260 : zl3vni->vid;
261 br_if = zif->brslave_info.br_if;
262 zl3vni_bridge_if_set(zl3vni, br_if, true /* set */);
263
0adeb5fd
SR
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);
268 }
269 } else {
270
271 /* Update VNI hash. */
272 zevpn = zebra_evpn_lookup(vni);
273 if (!zevpn) {
274 zlog_debug(
275 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
276 ifp->name, ifp->ifindex, vni);
277 return -1;
278 }
279
280 if (IS_ZEBRA_DEBUG_VXLAN)
281 zlog_debug(
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,
285 chgflags);
286
287 /* Removed from bridge? Cleanup and return */
0bbad9d1
SW
288 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) &&
289 (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
0adeb5fd
SR
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);
297 return 0;
298 }
299
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)
304 */
00d30205 305 access_vlan = vnip->access_vlan;
306 vnip->access_vlan = ctx->old_vni.access_vlan;
0adeb5fd
SR
307 zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
308 zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
00d30205 309 zebra_evpn_rem_mac_uninstall_all(zevpn);
310 vnip->access_vlan = access_vlan;
0adeb5fd
SR
311 }
312
0bbad9d1
SW
313 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
314 zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
0adeb5fd 315 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
0bbad9d1 316 zevpn->mcast_grp);
0adeb5fd
SR
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
322 */
323 zebra_evpn_es_set_base_evpn(zevpn);
324 }
325 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
efde4f25
SR
326 zevpn->vid = (zevpn->vid != vnip->access_vlan)
327 ? vnip->access_vlan
328 : zevpn->vid;
329 br_if = zif->brslave_info.br_if;
330 zevpn_bridge_if_set(zevpn, br_if, true /* set */);
331
332 vlan_if = zvni_map_to_svi(vnip->access_vlan, br_if);
0adeb5fd
SR
333 if (vlan_if)
334 zevpn->svi_if = vlan_if;
335
336 /* Take further actions needed.
337 * Note that if we are here, there is a change of interest.
338 */
339 /* If down or not mapped to a bridge, we're done. */
340 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
341 return 0;
342
343 /* Inform BGP, if there is a change of interest. */
344 if (chgflags &
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);
348
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).
353 */
354 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
355 zebra_evpn_read_mac_neigh(zevpn, ifp);
356 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
0adeb5fd
SR
357 struct neigh_walk_ctx n_wctx;
358
359 zebra_evpn_read_mac_neigh(zevpn, ifp);
360
00d30205 361 zebra_evpn_rem_mac_install_all(zevpn);
0adeb5fd
SR
362
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);
367 }
368 }
369
370 return 0;
371}
372
96c25556
SR
373static int zebra_vxlan_if_add_vni(struct interface *ifp,
374 struct zebra_vxlan_vni *vnip)
0adeb5fd
SR
375{
376 vni_t vni;
96c25556
SR
377 struct zebra_if *zif;
378 struct zebra_l2info_vxlan *vxl;
379 struct zebra_evpn *zevpn;
380 struct zebra_l3vni *zl3vni;
efde4f25 381 struct interface *br_if;
0adeb5fd
SR
382
383 /* Check if EVPN is enabled. */
384 if (!is_evpn_enabled())
385 return 0;
386
387 zif = ifp->info;
388 assert(zif);
96c25556 389 vxl = &zif->l2info.vxl;
0adeb5fd
SR
390 vni = vnip->vni;
391
392 zl3vni = zl3vni_lookup(vni);
393 if (zl3vni) {
394
395 /* process if-add for l3-vni*/
396 if (IS_ZEBRA_DEBUG_VXLAN)
397 zlog_debug(
398 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
399 vni, ifp->name, ifp->ifindex, vnip->access_vlan,
400 &vxl->vtep_ip,
401 zif->brslave_info.bridge_ifindex);
402
403 /* associate with vxlan_if */
404 zl3vni->local_vtep_ip = vxl->vtep_ip;
405 zl3vni->vxlan_if = ifp;
406
9464e5b8
SR
407 /*
408 * Associate with SVI, if any. We can associate with svi-if only
409 * after association with vxlan_if is complete
410 */
0adeb5fd
SR
411 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
412
413 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
414
efde4f25
SR
415 zl3vni->vid = vnip->access_vlan;
416 br_if = zif->brslave_info.br_if;
417 zl3vni_bridge_if_set(zl3vni, br_if, true /* set */);
418
0adeb5fd
SR
419 if (is_l3vni_oper_up(zl3vni))
420 zebra_vxlan_process_l3vni_oper_up(zl3vni);
421 } else {
422
423 /* process if-add for l2-vni */
424 struct interface *vlan_if = NULL;
425
426 /* Create or update EVPN hash. */
427 zevpn = zebra_evpn_lookup(vni);
428 if (!zevpn)
429 zevpn = zebra_evpn_add(vni);
430
0bbad9d1
SW
431 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
432 zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
0adeb5fd 433 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
0bbad9d1 434 zevpn->mcast_grp);
0adeb5fd
SR
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
440 */
441 zebra_evpn_es_set_base_evpn(zevpn);
442 }
443 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
efde4f25
SR
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);
0adeb5fd 447 if (vlan_if) {
efde4f25 448 zevpn->vid = vnip->access_vlan;
0adeb5fd
SR
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);
452 if (zl3vni)
453 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
454 }
455
456 if (IS_ZEBRA_DEBUG_VXLAN)
457 zlog_debug(
458 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
459 vni,
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);
464
465 /* If down or not mapped to a bridge, we're done. */
466 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
467 return 0;
468
469 /* Inform BGP */
470 zebra_evpn_send_add_to_client(zevpn);
471
472 /* Read and populate local MACs and neighbors */
473 zebra_evpn_read_mac_neigh(zevpn, ifp);
474 }
475
476 return 0;
477}
96c25556 478
96c25556
SR
479static void zebra_vxlan_if_vni_entry_del(struct zebra_if *zif,
480 struct zebra_vxlan_vni *vni)
481{
482 if (vni) {
483 zebra_evpn_vl_vxl_deref(vni->access_vlan, vni->vni, zif);
484 zebra_vxlan_if_del_vni(zif->ifp, vni);
485 }
486}
487
488static int zebra_vxlan_if_vni_entry_add(struct zebra_if *zif,
489 struct zebra_vxlan_vni *vni)
490{
491 zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif);
492 return zebra_vxlan_if_add_vni(zif->ifp, vni);
493}
494
495static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif,
496 struct zebra_vxlan_vni *vni,
497 void *ctxt)
498{
96c25556 499 struct zebra_vxlan_vni vni_tmp;
00d30205 500 struct zebra_vxlan_if_update_ctx *ctx;
96c25556
SR
501 struct zebra_vxlan_vni *old_vni = NULL;
502
00d30205 503 ctx = (struct zebra_vxlan_if_update_ctx *)ctxt;
96c25556
SR
504 memcpy(&vni_tmp, vni, sizeof(*vni));
505
00d30205 506 if ((hashcount(ctx->old_vni_table) == 0) ||
507 !(old_vni = hash_release(ctx->old_vni_table, &vni_tmp))) {
96c25556
SR
508 if (IS_ZEBRA_DEBUG_VXLAN)
509 zlog_debug("vxlan %s adding vni(%d, %d)",
510 zif->ifp->name, vni->vni, vni->access_vlan);
511
512 zebra_vxlan_if_vni_entry_add(zif, &vni_tmp);
513 return 0;
514 }
515
00d30205 516 ctx->old_vni = *old_vni;
517 ctx->chgflags = ZEBRA_VXLIF_VLAN_CHANGE;
518
4a08e697
SR
519 /* copy mcast group from old_vni as thats not being changed here */
520 vni->mcast_grp = old_vni->mcast_grp;
521
96c25556
SR
522 if (old_vni->access_vlan != vni->access_vlan) {
523 if (IS_ZEBRA_DEBUG_VXLAN)
524 zlog_debug(
525 "vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
526 zif->ifp->name, old_vni->vni,
4a08e697
SR
527 old_vni->access_vlan, vni->vni,
528 vni->access_vlan);
96c25556 529
4a08e697
SR
530 zebra_evpn_vl_vxl_deref(old_vni->access_vlan, old_vni->vni,
531 zif);
532 zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif);
00d30205 533 zebra_vxlan_if_update_vni(zif->ifp, vni, ctx);
96c25556
SR
534 zebra_vxlan_vni_free(old_vni);
535 }
536
537 return 0;
538}
539
540static int zebra_vxlan_if_vni_entry_update_callback(struct zebra_if *zif,
541 struct zebra_vxlan_vni *vni,
542 void *ctxt)
543{
00d30205 544 struct zebra_vxlan_if_update_ctx *ctx;
96c25556 545
00d30205 546 ctx = (struct zebra_vxlan_if_update_ctx *)ctxt;
547 return zebra_vxlan_if_update_vni(zif->ifp, vni, ctx);
96c25556
SR
548}
549
550static int zebra_vxlan_if_vni_entry_del_callback(struct zebra_if *zif,
551 struct zebra_vxlan_vni *vni,
552 void *ctxt)
553{
554 zebra_vxlan_if_vni_entry_del(zif, vni);
555 return 0;
556}
557
558static int zebra_vxlan_if_vni_entry_down_callback(struct zebra_if *zif,
559 struct zebra_vxlan_vni *vni,
560 void *ctxt)
561{
562 return zebra_vxlan_if_vni_down(zif->ifp, vni);
563}
564
565static int zebra_vxlan_if_vni_entry_up_callback(struct zebra_if *zif,
566 struct zebra_vxlan_vni *vni,
567 void *ctxt)
568{
569 return zebra_vxlan_if_vni_up(zif->ifp, vni);
570}
571
572static void zebra_vxlan_if_vni_clean(struct hash_bucket *bucket, void *arg)
573{
4a08e697 574 struct zebra_if *zif;
96c25556
SR
575 struct zebra_vxlan_vni *vni;
576
4a08e697 577 zif = (struct zebra_if *)arg;
96c25556 578 vni = (struct zebra_vxlan_vni *)bucket->data;
4a08e697 579 zebra_vxlan_if_vni_entry_del(zif, vni);
96c25556
SR
580}
581
582void zebra_vxlan_vni_free(void *arg)
583{
584 struct zebra_vxlan_vni *vni;
585
586 vni = (struct zebra_vxlan_vni *)arg;
587
588 XFREE(MTYPE_TMP, vni);
589}
590
591void *zebra_vxlan_vni_alloc(void *p)
592{
593 struct zebra_vxlan_vni *vni;
594 const struct zebra_vxlan_vni *vnip;
595
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;
601
602 return (void *)vni;
603}
604
605struct hash *zebra_vxlan_vni_table_create(void)
606{
607 return hash_create(zebra_vxlan_vni_hash_keymake,
608 zebra_vxlan_vni_hash_cmp, "Zebra Vxlan VNI Table");
609}
610
611void zebra_vxlan_vni_table_destroy(struct hash *vni_table)
612{
d8bc11a5 613 hash_clean_and_free(&vni_table, zebra_vxlan_vni_free);
96c25556
SR
614}
615
616int zebra_vxlan_if_vni_table_destroy(struct zebra_if *zif)
617{
618 struct zebra_vxlan_vni_info *vni_info;
619
620 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
621 if (vni_info->vni_table) {
622 zebra_vxlan_if_vni_iterate(
623 zif, zebra_vxlan_if_vni_entry_del_callback, NULL);
624 zebra_vxlan_vni_table_destroy(vni_info->vni_table);
625 vni_info->vni_table = NULL;
626 }
627 return 0;
628}
629
630int zebra_vxlan_if_vni_table_create(struct zebra_if *zif)
631{
632 struct zebra_vxlan_vni_info *vni_info;
633
634 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
635 return 0;
636
637 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
638 vni_info->vni_table = zebra_vxlan_vni_table_create();
639 if (!vni_info->vni_table)
9464e5b8 640 return -ENOMEM;
96c25556
SR
641
642 return 0;
643}
644
645struct zebra_vxlan_vni *zebra_vxlan_if_vni_find(const struct zebra_if *zif,
646 vni_t vni)
647{
648 struct zebra_vxlan_vni *vnip = NULL;
649 const struct zebra_vxlan_vni_info *vni_info;
650 struct zebra_vxlan_vni vni_tmp;
651
652 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
653 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
654 vnip = (struct zebra_vxlan_vni *)&vni_info->vni;
655 assert(vnip);
656 if (vni && (vnip->vni != vni))
657 vnip = NULL;
658
659 return vnip;
660 }
661
feffe4ee 662 /* For SVD, the VNI value is a required parameter. */
96c25556
SR
663 assert(vni);
664
665 memset(&vni_tmp, 0, sizeof(vni_tmp));
666 vni_tmp.vni = vni;
667 vnip = (struct zebra_vxlan_vni *)hash_lookup(vni_info->vni_table,
668 (void *)&vni_tmp);
669
670 /* TODO: For debugging. Remove later */
671 if (vnip)
672 assert(vnip->vni == vni);
673
674 return vnip;
675}
676
a26daa77
SW
677static int zif_vlanid_vni_walker(struct zebra_if *zif,
678 struct zebra_vxlan_vni *vnip, void *arg)
679{
680 struct zebra_vxlan_if_vlan_ctx *ctx;
681
682 ctx = (struct zebra_vxlan_if_vlan_ctx *)arg;
683
684 if (vnip->access_vlan == ctx->vid) {
685 ctx->vni = vnip;
686 return HASHWALK_ABORT;
687 }
688
689 return HASHWALK_CONTINUE;
690}
691
692struct zebra_vxlan_vni *zebra_vxlan_if_vlanid_vni_find(struct zebra_if *zif,
693 vlanid_t vid)
694{
695 struct zebra_vxlan_if_vlan_ctx ctx = {};
696
697 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
698 return NULL;
699
700 ctx.vid = vid;
701
702 zebra_vxlan_if_vni_walk(zif, zif_vlanid_vni_walker, &ctx);
703
704 return ctx.vni;
705}
706
96c25556
SR
707void zebra_vxlan_if_vni_iterate(struct zebra_if *zif,
708 int (*func)(struct zebra_if *zif,
709 struct zebra_vxlan_vni *, void *),
710 void *arg)
711{
712 struct zebra_vxlan_vni_info *vni_info;
713 struct zebra_vxlan_vni *vni = NULL;
714 struct zebra_vxlan_if_ctx ctx;
715
716 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
717 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
718 vni = zebra_vxlan_if_vni_find(zif, 0);
719 func(zif, vni, arg);
720 return;
721 }
722
723 memset(&ctx, 0, sizeof(ctx));
724 ctx.zif = zif;
725 ctx.func = func;
726 ctx.arg = arg;
727 hash_iterate(vni_info->vni_table, zebra_vxlan_if_vni_iterate_callback,
728 &ctx);
729}
730
731void zebra_vxlan_if_vni_walk(struct zebra_if *zif,
732 int (*func)(struct zebra_if *zif,
733 struct zebra_vxlan_vni *, void *),
734 void *arg)
735{
736 struct zebra_vxlan_vni_info *vni_info;
737 struct zebra_vxlan_vni *vni = NULL;
738 struct zebra_vxlan_if_ctx ctx;
739
740 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
741 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
742 vni = zebra_vxlan_if_vni_find(zif, 0);
743 func(zif, vni, arg);
744 return;
745 }
746
747 memset(&ctx, 0, sizeof(ctx));
748 ctx.zif = zif;
749 ctx.func = func;
750 ctx.arg = arg;
751 hash_walk(vni_info->vni_table, zebra_vxlan_if_vni_walk_callback, &ctx);
752}
753
feffe4ee 754vni_t zebra_vxlan_if_access_vlan_vni_find(struct zebra_if *zif,
efde4f25 755 struct interface *br_if)
96c25556
SR
756{
757 struct zebra_vxlan_vni *vni = NULL;
96c25556 758
feffe4ee
SR
759 /* Expected to be called only for vlan-unware bridges. In this case,
760 * we only support a per-VNI VXLAN interface model.
761 */
762 if (!IS_ZEBRA_VXLAN_IF_VNI(zif))
763 return 0;
764
efde4f25
SR
765 vni = zebra_vxlan_if_vni_find(zif, 0);
766 assert(vni);
96c25556 767
efde4f25 768 return vni->vni;
96c25556
SR
769}
770
771int zebra_vxlan_if_vni_table_add_update(struct interface *ifp,
772 struct hash *vni_table)
773{
774 struct zebra_if *zif;
96c25556 775 struct zebra_vxlan_vni_info *vni_info;
00d30205 776 struct zebra_vxlan_if_update_ctx ctx;
96c25556
SR
777
778 zif = (struct zebra_if *)ifp->info;
779
780 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
781
00d30205 782 memset(&ctx, 0, sizeof(ctx));
783 ctx.old_vni_table = vni_info->vni_table;
96c25556
SR
784 vni_info->vni_table = vni_table;
785
00d30205 786 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_add_update_vni, &ctx);
96c25556
SR
787
788 /* release kernel deleted vnis */
00d30205 789 if (ctx.old_vni_table) {
790 if (hashcount(ctx.old_vni_table)) {
a885db2f 791 /* UGLY HACK: Put back the old table so that delete of
792 * MACs goes through and then flip back.
793 */
00d30205 794 vni_info->vni_table = ctx.old_vni_table;
795 hash_iterate(ctx.old_vni_table,
796 zebra_vxlan_if_vni_clean, zif);
a885db2f 797 vni_info->vni_table = vni_table;
798 }
00d30205 799 zebra_vxlan_vni_table_destroy(ctx.old_vni_table);
800 ctx.old_vni_table = NULL;
96c25556
SR
801 }
802
803 return 0;
804}
805
e41db240 806int zebra_vxlan_if_vni_mcast_group_add_update(struct interface *ifp,
807 vni_t vni_id,
808 struct in_addr *mcast_group)
96c25556
SR
809{
810 struct zebra_if *zif;
4a08e697 811 struct zebra_vxlan_vni *vni;
00d30205 812 struct zebra_vxlan_if_update_ctx ctx;
96c25556
SR
813
814 zif = (struct zebra_if *)ifp->info;
815
816 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
817 return 0;
818
4a08e697
SR
819 vni = zebra_vxlan_if_vni_find(zif, vni_id);
820 if (!vni)
821 return 0;
822
00d30205 823 memset(&ctx, 0, sizeof(ctx));
824 ctx.old_vni.mcast_grp = vni->mcast_grp;
825 ctx.chgflags = ZEBRA_VXLIF_MCAST_GRP_CHANGE;
826
e41db240 827 vni->mcast_grp = *mcast_group;
828
829 return zebra_vxlan_if_update_vni(ifp, vni, &ctx);
830}
831
832int zebra_vxlan_if_vni_mcast_group_del(struct interface *ifp, vni_t vni_id,
833 struct in_addr *mcast_group)
834{
835 struct zebra_if *zif = NULL;
836 struct zebra_vxlan_vni *vni;
837 struct zebra_vxlan_if_update_ctx ctx;
838
839 zif = (struct zebra_if *)ifp->info;
840
841 if (!IS_ZEBRA_VXLAN_IF_SVD(zif))
842 return 0;
843
844 vni = zebra_vxlan_if_vni_find(zif, vni_id);
845 if (!vni)
846 return 0;
847
848 if (memcmp(mcast_group, &vni->mcast_grp, sizeof(*mcast_group)))
849 return 0;
850
851 memset(&ctx, 0, sizeof(ctx));
852 ctx.old_vni.mcast_grp = vni->mcast_grp;
853 ctx.chgflags = ZEBRA_VXLIF_MCAST_GRP_CHANGE;
854
855 memset(&vni->mcast_grp, 0, sizeof(vni->mcast_grp));
96c25556 856
00d30205 857 return zebra_vxlan_if_update_vni(ifp, vni, &ctx);
96c25556
SR
858}
859
860int zebra_vxlan_if_vni_down(struct interface *ifp, struct zebra_vxlan_vni *vnip)
861{
862 vni_t vni;
863 struct zebra_if *zif;
864 struct zebra_l3vni *zl3vni;
865 struct zebra_evpn *zevpn;
866
867 /* Check if EVPN is enabled. */
868 if (!is_evpn_enabled())
869 return 0;
870
871 zif = ifp->info;
872 assert(zif);
873 vni = vnip->vni;
874
875 zl3vni = zl3vni_lookup(vni);
876 if (zl3vni) {
877 /* process-if-down for l3-vni */
878 if (IS_ZEBRA_DEBUG_VXLAN)
879 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
880 ifp->ifindex, vni);
881
882 zebra_vxlan_process_l3vni_oper_down(zl3vni);
883 } else {
884 /* process if-down for l2-vni */
885 if (IS_ZEBRA_DEBUG_VXLAN)
886 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
887 ifp->ifindex, vni);
888
889 /* Locate hash entry; it is expected to exist. */
890 zevpn = zebra_evpn_lookup(vni);
891 if (!zevpn) {
892 zlog_debug(
893 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
894 ifp->name, ifp->ifindex, vni);
895 return -1;
896 }
897
898 assert(zevpn->vxlan_if == ifp);
899
900 /* remove from l3-vni list */
901 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
902 if (zl3vni)
903 listnode_delete(zl3vni->l2vnis, zevpn);
904
5c713062 905 zebra_evpn_vl_vxl_deref(vnip->access_vlan, vnip->vni, zif);
906
96c25556
SR
907 /* Delete this VNI from BGP. */
908 zebra_evpn_send_del_to_client(zevpn);
909
910 /* Free up all neighbors and MACs, if any. */
911 zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
912 zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
913
914 /* Free up all remote VTEPs, if any. */
915 zebra_evpn_vtep_del_all(zevpn, 1);
916 }
917 return 0;
918}
919
920/*
921 * Handle VxLAN interface down
922 */
923int zebra_vxlan_if_down(struct interface *ifp)
924{
925 struct zebra_if *zif;
926 struct zebra_vxlan_vni_info *vni_info;
927
928 /* Check if EVPN is enabled. */
929 if (!is_evpn_enabled())
930 return 0;
931
932 zif = ifp->info;
933 assert(zif);
934
935 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
936 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
937 return zebra_vxlan_if_vni_down(ifp, &vni_info->vni);
938 }
939
940 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_vni_entry_down_callback,
941 NULL);
942
943 return 0;
944}
945
946int zebra_vxlan_if_vni_up(struct interface *ifp, struct zebra_vxlan_vni *vnip)
947{
948 vni_t vni;
949 struct zebra_if *zif;
950 struct zebra_evpn *zevpn;
951 struct zebra_l3vni *zl3vni;
952
953 /* Check if EVPN is enabled. */
954 if (!is_evpn_enabled())
955 return 0;
956
957 zif = ifp->info;
958 assert(zif);
959 vni = vnip->vni;
960
961 zl3vni = zl3vni_lookup(vni);
962 if (zl3vni) {
963 /* we need to associate with SVI, if any, we can associate with
964 * svi-if only after association with vxlan-intf is complete
965 */
966 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
967 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
968
969 if (IS_ZEBRA_DEBUG_VXLAN)
970 zlog_debug(
971 "Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s",
972 ifp->name, ifp->ifindex, vni,
973 zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
974 zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
975 : "NIL");
976
977 if (is_l3vni_oper_up(zl3vni))
978 zebra_vxlan_process_l3vni_oper_up(zl3vni);
979 } else {
980 /* Handle L2-VNI add */
981 struct interface *vlan_if = NULL;
982
983 if (IS_ZEBRA_DEBUG_VXLAN)
984 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
985 ifp->ifindex, vni);
986
987 /* Locate hash entry; it is expected to exist. */
988 zevpn = zebra_evpn_lookup(vni);
989 if (!zevpn) {
990 zlog_debug(
991 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
992 ifp->name, ifp->ifindex, vni);
993 return -1;
994 }
995
996 assert(zevpn->vxlan_if == ifp);
5c713062 997 zebra_evpn_vl_vxl_ref(vnip->access_vlan, vnip->vni, zif);
96c25556
SR
998 vlan_if = zvni_map_to_svi(vnip->access_vlan,
999 zif->brslave_info.br_if);
1000 if (vlan_if) {
1001 zevpn->svi_if = vlan_if;
1002 zevpn->vrf_id = vlan_if->vrf->vrf_id;
1003 zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
1004 if (zl3vni)
1005 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
1006 }
1007
1008 /* If part of a bridge, inform BGP about this VNI. */
1009 /* Also, read and populate local MACs and neighbors. */
1010 if (zif->brslave_info.br_if) {
1011 zebra_evpn_send_add_to_client(zevpn);
1012 zebra_evpn_read_mac_neigh(zevpn, ifp);
1013 }
1014 }
1015
1016 return 0;
1017}
1018
1019/*
1020 * Handle VxLAN interface up - update BGP if required.
1021 */
1022int zebra_vxlan_if_up(struct interface *ifp)
1023{
1024 struct zebra_if *zif;
1025 struct zebra_vxlan_vni_info *vni_info;
1026
1027 /* Check if EVPN is enabled. */
1028 if (!is_evpn_enabled())
1029 return 0;
1030
1031 zif = ifp->info;
1032 assert(zif);
1033
1034 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
1035 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
1036 return zebra_vxlan_if_vni_up(ifp, &vni_info->vni);
1037 }
1038
1039 zebra_vxlan_if_vni_iterate(zif, zebra_vxlan_if_vni_entry_up_callback,
1040 NULL);
1041
1042 return 0;
1043}
1044
1045int zebra_vxlan_if_vni_del(struct interface *ifp, vni_t vni)
1046{
1047 struct zebra_if *zif;
1048 struct zebra_vxlan_vni *vnip;
1049 struct zebra_vxlan_vni vni_tmp;
1050 struct zebra_vxlan_vni_info *vni_info;
1051
96c25556
SR
1052 zif = ifp->info;
1053 assert(zif);
1054
1055 /* This should be called in SVD context only */
1056 assert(IS_ZEBRA_VXLAN_IF_SVD(zif));
1057
1058 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
1059 memset(&vni_tmp, 0, sizeof(vni_tmp));
1060 vni_tmp.vni = vni;
1061
1062 vnip = hash_release(vni_info->vni_table, &vni_tmp);
1063 if (vnip) {
1064 zebra_vxlan_if_vni_entry_del(zif, vnip);
1065 zebra_vxlan_vni_free(vnip);
1066 }
1067 return 0;
1068}
1069
1070/*
1071 * Handle VxLAN interface delete. Locate and remove entry in hash table
1072 * and update BGP, if required.
1073 */
1074int zebra_vxlan_if_del(struct interface *ifp)
1075{
1076 struct zebra_if *zif;
1077 struct zebra_vxlan_vni_info *vni_info;
1078
96c25556
SR
1079 zif = ifp->info;
1080 assert(zif);
1081
1082 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
1083 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
1084 zebra_evpn_vl_vxl_deref(vni_info->vni.access_vlan,
1085 vni_info->vni.vni, zif);
1086 return zebra_vxlan_if_del_vni(ifp, &vni_info->vni);
1087 }
1088
1089 zebra_vxlan_if_vni_table_destroy(zif);
1090
1091 return 0;
1092}
1093
96c25556
SR
1094/*
1095 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
1096 */
00d30205 1097int zebra_vxlan_if_update(struct interface *ifp,
1098 struct zebra_vxlan_if_update_ctx *ctx)
96c25556
SR
1099{
1100 struct zebra_if *zif;
1101 struct zebra_vxlan_vni_info *vni_info;
1102
1103 zif = ifp->info;
1104 assert(zif);
1105
1106 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
1107 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
00d30205 1108 return zebra_vxlan_if_update_vni(ifp, &vni_info->vni, ctx);
96c25556
SR
1109 }
1110
1111 zebra_vxlan_if_vni_iterate(
00d30205 1112 zif, zebra_vxlan_if_vni_entry_update_callback, ctx);
96c25556
SR
1113
1114 return 0;
1115}
1116
1117int zebra_vxlan_if_vni_add(struct interface *ifp, struct zebra_vxlan_vni *vni)
1118{
1119 struct zebra_if *zif;
1120 struct zebra_vxlan_vni_info *vni_info;
1121
1122 zif = ifp->info;
1123 assert(zif);
1124
1125 /* This should be called in SVD context only */
1126 assert(IS_ZEBRA_VXLAN_IF_SVD(zif));
1127
efde4f25 1128 /* First insert into the table */
96c25556
SR
1129 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
1130 hash_get(vni_info->vni_table, (void *)vni, zebra_vxlan_vni_alloc);
1131
1132 return zebra_vxlan_if_vni_entry_add(zif, vni);
1133}
1134
1135/*
1136 * Handle VxLAN interface add.
1137 */
1138int zebra_vxlan_if_add(struct interface *ifp)
1139{
1140 int ret;
1141 struct zebra_if *zif;
1142 struct zebra_vxlan_vni_info *vni_info;
1143
1144 zif = ifp->info;
1145 assert(zif);
1146
1147 if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
1148 vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
1149 zebra_evpn_vl_vxl_ref(vni_info->vni.access_vlan,
1150 vni_info->vni.vni, zif);
1151 return zebra_vxlan_if_add_vni(ifp, &vni_info->vni);
1152 }
1153
1154 ret = zebra_vxlan_if_vni_table_create(zif);
1155 if (ret < 0)
1156 return ret;
1157
1158 return 0;
1159}