]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
zebra: single vxlan device dataplace vni update changes
[mirror_frr.git] / zebra / zebra_vxlan.c
1 /*
2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "hash.h"
26 #include "if.h"
27 #include "jhash.h"
28 #include "linklist.h"
29 #include "log.h"
30 #include "memory.h"
31 #include "prefix.h"
32 #include "stream.h"
33 #include "table.h"
34 #include "vlan.h"
35 #include "vxlan.h"
36 #ifdef GNU_LINUX
37 #include <linux/neighbour.h>
38 #endif
39 #include "lib/printfrr.h"
40
41 #include "zebra/zebra_router.h"
42 #include "zebra/debug.h"
43 #include "zebra/interface.h"
44 #include "zebra/rib.h"
45 #include "zebra/rt.h"
46 #include "zebra/rt_netlink.h"
47 #include "zebra/zebra_errors.h"
48 #include "zebra/zebra_l2.h"
49 #include "zebra/zebra_ns.h"
50 #include "zebra/zebra_vrf.h"
51 #include "zebra/zebra_vxlan.h"
52 #include "zebra/zebra_vxlan_private.h"
53 #include "zebra/zebra_evpn.h"
54 #include "zebra/zebra_evpn_mac.h"
55 #include "zebra/zebra_evpn_neigh.h"
56 #include "zebra/zebra_evpn_mh.h"
57 #include "zebra/zebra_evpn_vxlan.h"
58 #include "zebra/zebra_router.h"
59
60 DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
61 DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
62 DEFINE_MTYPE_STATIC(ZEBRA, L3VNI_MAC, "EVPN L3VNI MAC");
63 DEFINE_MTYPE_STATIC(ZEBRA, L3NEIGH, "EVPN Neighbor");
64 DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group");
65 DEFINE_MTYPE_STATIC(ZEBRA, EVPN_VTEP, "zebra VxLAN VTEP IP");
66
67 DEFINE_HOOK(zebra_rmac_update,
68 (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete,
69 const char *reason),
70 (rmac, zl3vni, delete, reason));
71
72 /* config knobs */
73 static bool accept_bgp_seq = true;
74
75 /* static function declarations */
76 static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
77 void **args);
78 static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
79 json_object *json);
80 static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
81 json_object *json);
82 static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt);
83
84 /* l3-vni next-hop neigh related APIs */
85 static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
86 const struct ipaddr *ip);
87 static void *zl3vni_nh_alloc(void *p);
88 static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
89 const struct ipaddr *vtep_ip,
90 const struct ethaddr *rmac);
91 static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
92 static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n);
93 static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
94 struct zebra_neigh *n);
95
96 /* l3-vni rmac related APIs */
97 static void zl3vni_print_rmac_hash(struct hash_bucket *, void *);
98 static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
99 const struct ethaddr *rmac);
100 static void *zl3vni_rmac_alloc(void *p);
101 static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
102 const struct ethaddr *rmac);
103 static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac);
104 static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
105 struct zebra_mac *zrmac);
106 static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
107 struct zebra_mac *zrmac);
108
109 /* l3-vni related APIs*/
110 static void *zl3vni_alloc(void *p);
111 static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
112 static int zl3vni_del(struct zebra_l3vni *zl3vni);
113
114 static void zevpn_build_hash_table(void);
115 static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
116 static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
117 static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
118 struct in_addr sip, struct in_addr mcast_grp);
119 static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf,
120 struct in_addr sip,
121 struct in_addr mcast_grp);
122 static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf);
123
124 bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf)
125 {
126 return zvrf->dup_addr_detect && zebra_evpn_mh_do_dup_addr_detect();
127 }
128
129 /* Private functions */
130 static int host_rb_entry_compare(const struct host_rb_entry *hle1,
131 const struct host_rb_entry *hle2)
132 {
133 if (hle1->p.family < hle2->p.family)
134 return -1;
135
136 if (hle1->p.family > hle2->p.family)
137 return 1;
138
139 if (hle1->p.prefixlen < hle2->p.prefixlen)
140 return -1;
141
142 if (hle1->p.prefixlen > hle2->p.prefixlen)
143 return 1;
144
145 if (hle1->p.family == AF_INET) {
146 if (hle1->p.u.prefix4.s_addr < hle2->p.u.prefix4.s_addr)
147 return -1;
148
149 if (hle1->p.u.prefix4.s_addr > hle2->p.u.prefix4.s_addr)
150 return 1;
151
152 return 0;
153 } else if (hle1->p.family == AF_INET6) {
154 return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
155 IPV6_MAX_BYTELEN);
156 } else if (hle1->p.family == AF_EVPN) {
157 uint8_t family1;
158 uint8_t family2;
159
160 /* two (v4/v6) dummy prefixes of route_type BGP_EVPN_AD_ROUTE
161 * are used for all nexthops associated with a non-zero ESI
162 */
163 family1 = is_evpn_prefix_ipaddr_v4(
164 (const struct prefix_evpn *)&hle1->p)
165 ? AF_INET
166 : AF_INET6;
167 family2 = is_evpn_prefix_ipaddr_v4(
168 (const struct prefix_evpn *)&hle2->p)
169 ? AF_INET
170 : AF_INET6;
171
172
173 if (family1 < family2)
174 return -1;
175
176 if (family1 > family2)
177 return 1;
178
179 return 0;
180 } else {
181 zlog_debug("%s: Unexpected family type: %d", __func__,
182 hle1->p.family);
183 return 0;
184 }
185 }
186 RB_GENERATE(host_rb_tree_entry, host_rb_entry, hl_entry, host_rb_entry_compare);
187
188 static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe)
189 {
190 struct host_rb_entry *hle;
191 uint32_t count = 0;
192
193 RB_FOREACH (hle, host_rb_tree_entry, hrbe)
194 count++;
195
196 return count;
197 }
198
199 static int l3vni_rmac_nh_list_cmp(void *p1, void *p2)
200 {
201 const struct ipaddr *vtep_ip1 = p1;
202 const struct ipaddr *vtep_ip2 = p2;
203
204 return !ipaddr_cmp(vtep_ip1, vtep_ip2);
205 }
206
207 static void l3vni_rmac_nh_free(struct ipaddr *vtep_ip)
208 {
209 XFREE(MTYPE_EVPN_VTEP, vtep_ip);
210 }
211
212 static void l3vni_rmac_nh_list_nh_delete(struct zebra_l3vni *zl3vni,
213 struct zebra_mac *zrmac,
214 struct ipaddr *vtep_ip)
215 {
216 struct listnode *node = NULL, *nnode = NULL;
217 struct ipaddr *vtep = NULL;
218
219 for (ALL_LIST_ELEMENTS(zrmac->nh_list, node, nnode, vtep)) {
220 if (ipaddr_cmp(vtep, vtep_ip) == 0)
221 break;
222 }
223
224 if (node) {
225 l3vni_rmac_nh_free(vtep);
226 list_delete_node(zrmac->nh_list, node);
227 }
228 }
229
230 /*
231 * Print neighbors for all EVPN.
232 */
233 static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
234 void **args)
235 {
236 struct vty *vty;
237 json_object *json = NULL, *json_evpn = NULL;
238 struct zebra_evpn *zevpn;
239 uint32_t num_neigh;
240 struct neigh_walk_ctx wctx;
241 char vni_str[VNI_STR_LEN];
242 uint32_t print_dup;
243
244 vty = (struct vty *)args[0];
245 json = (json_object *)args[1];
246 print_dup = (uint32_t)(uintptr_t)args[2];
247
248 zevpn = (struct zebra_evpn *)bucket->data;
249
250 num_neigh = hashcount(zevpn->neigh_table);
251
252 if (print_dup)
253 num_neigh = num_dup_detected_neighs(zevpn);
254
255 if (json == NULL) {
256 vty_out(vty,
257 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
258 zevpn->vni, num_neigh);
259 } else {
260 json_evpn = json_object_new_object();
261 json_object_int_add(json_evpn, "numArpNd", num_neigh);
262 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
263 }
264
265 if (!num_neigh) {
266 if (json)
267 json_object_object_add(json, vni_str, json_evpn);
268 return;
269 }
270
271 /* Since we have IPv6 addresses to deal with which can vary widely in
272 * size, we try to be a bit more elegant in display by first computing
273 * the maximum width.
274 */
275 memset(&wctx, 0, sizeof(wctx));
276 wctx.zevpn = zevpn;
277 wctx.vty = vty;
278 wctx.addr_width = 15;
279 wctx.json = json_evpn;
280 hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
281 &wctx);
282
283 if (json == NULL)
284 zebra_evpn_print_neigh_hdr(vty, &wctx);
285
286 if (print_dup)
287 hash_iterate(zevpn->neigh_table,
288 zebra_evpn_print_dad_neigh_hash, &wctx);
289 else
290 hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash,
291 &wctx);
292
293 if (json)
294 json_object_object_add(json, vni_str, json_evpn);
295 }
296
297 /*
298 * Print neighbors for all EVPNs in detail.
299 */
300 static void zevpn_print_neigh_hash_all_evpn_detail(struct hash_bucket *bucket,
301 void **args)
302 {
303 struct vty *vty;
304 json_object *json = NULL, *json_evpn = NULL;
305 struct zebra_evpn *zevpn;
306 uint32_t num_neigh;
307 struct neigh_walk_ctx wctx;
308 char vni_str[VNI_STR_LEN];
309 uint32_t print_dup;
310
311 vty = (struct vty *)args[0];
312 json = (json_object *)args[1];
313 print_dup = (uint32_t)(uintptr_t)args[2];
314
315 zevpn = (struct zebra_evpn *)bucket->data;
316 if (!zevpn) {
317 if (json)
318 vty_out(vty, "{}\n");
319 return;
320 }
321 num_neigh = hashcount(zevpn->neigh_table);
322
323 if (print_dup && num_dup_detected_neighs(zevpn) == 0)
324 return;
325
326 if (json == NULL) {
327 vty_out(vty,
328 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
329 zevpn->vni, num_neigh);
330 } else {
331 json_evpn = json_object_new_object();
332 json_object_int_add(json_evpn, "numArpNd", num_neigh);
333 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
334 }
335 if (!num_neigh) {
336 if (json)
337 json_object_object_add(json, vni_str, json_evpn);
338 return;
339 }
340
341 memset(&wctx, 0, sizeof(wctx));
342 wctx.zevpn = zevpn;
343 wctx.vty = vty;
344 wctx.addr_width = 15;
345 wctx.json = json_evpn;
346
347 if (print_dup)
348 hash_iterate(zevpn->neigh_table,
349 zebra_evpn_print_dad_neigh_hash_detail, &wctx);
350 else
351 hash_iterate(zevpn->neigh_table,
352 zebra_evpn_print_neigh_hash_detail, &wctx);
353
354 if (json)
355 json_object_object_add(json, vni_str, json_evpn);
356 }
357
358 /* print a specific next hop for an l3vni */
359 static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty,
360 json_object *json)
361 {
362 char buf1[ETHER_ADDR_STRLEN];
363 char buf2[INET6_ADDRSTRLEN];
364 json_object *json_hosts = NULL;
365 struct host_rb_entry *hle;
366
367 if (!json) {
368 vty_out(vty, "Ip: %s\n",
369 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
370 vty_out(vty, " RMAC: %s\n",
371 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
372 vty_out(vty, " Refcount: %d\n",
373 rb_host_count(&n->host_rb));
374 vty_out(vty, " Prefixes:\n");
375 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
376 vty_out(vty, " %pFX\n", &hle->p);
377 } else {
378 json_hosts = json_object_new_array();
379 json_object_string_add(
380 json, "ip", ipaddr2str(&(n->ip), buf2, sizeof(buf2)));
381 json_object_string_add(
382 json, "routerMac",
383 prefix_mac2str(&n->emac, buf2, sizeof(buf2)));
384 json_object_int_add(json, "refCount",
385 rb_host_count(&n->host_rb));
386 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
387 json_object_array_add(json_hosts,
388 json_object_new_string(prefix2str(
389 &hle->p, buf2, sizeof(buf2))));
390 json_object_object_add(json, "prefixList", json_hosts);
391 }
392 }
393
394 /* Print a specific RMAC entry */
395 static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty,
396 json_object *json)
397 {
398 struct listnode *node = NULL;
399 struct ipaddr *vtep = NULL;
400 json_object *json_nhs = NULL;
401
402 if (!json) {
403 vty_out(vty, "MAC: %pEA\n", &zrmac->macaddr);
404 vty_out(vty, " Remote VTEP: %pI4\n",
405 &zrmac->fwd_info.r_vtep_ip);
406 } else {
407 json_nhs = json_object_new_array();
408 json_object_string_addf(json, "routerMac", "%pEA",
409 &zrmac->macaddr);
410 json_object_string_addf(json, "vtepIp", "%pI4",
411 &zrmac->fwd_info.r_vtep_ip);
412 for (ALL_LIST_ELEMENTS_RO(zrmac->nh_list, node, vtep)) {
413 json_object_array_add(json_nhs, json_object_new_stringf(
414 "%pIA", vtep));
415 }
416 json_object_object_add(json, "nexthops", json_nhs);
417 }
418 }
419
420 /*
421 * Print MACs for all EVPNs.
422 */
423 static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt)
424 {
425 struct vty *vty;
426 json_object *json = NULL, *json_evpn = NULL;
427 json_object *json_mac = NULL;
428 struct zebra_evpn *zevpn;
429 uint32_t num_macs;
430 struct mac_walk_ctx *wctx = ctxt;
431 char vni_str[VNI_STR_LEN];
432
433 vty = wctx->vty;
434 json = wctx->json;
435
436 zevpn = (struct zebra_evpn *)bucket->data;
437 wctx->zevpn = zevpn;
438
439 /*We are iterating over a new VNI, set the count to 0*/
440 wctx->count = 0;
441
442 num_macs = num_valid_macs(zevpn);
443 if (!num_macs)
444 return;
445
446 if (wctx->print_dup)
447 num_macs = num_dup_detected_macs(zevpn);
448
449 if (json) {
450 json_evpn = json_object_new_object();
451 json_mac = json_object_new_object();
452 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
453 }
454
455 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
456 if (json == NULL) {
457 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
458 zevpn->vni, num_macs);
459 vty_out(vty,
460 "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
461 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
462 "Type", "Flags", "Intf/Remote ES/VTEP",
463 "VLAN", "Seq #'s");
464 } else
465 json_object_int_add(json_evpn, "numMacs", num_macs);
466 }
467
468 if (!num_macs) {
469 if (json) {
470 json_object_int_add(json_evpn, "numMacs", num_macs);
471 json_object_object_add(json, vni_str, json_evpn);
472 }
473 return;
474 }
475
476 /* assign per-evpn to wctx->json object to fill macs
477 * under the evpn. Re-assign primary json object to fill
478 * next evpn information.
479 */
480 wctx->json = json_mac;
481 if (wctx->print_dup)
482 hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash,
483 wctx);
484 else
485 hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, wctx);
486 wctx->json = json;
487 if (json) {
488 if (wctx->count)
489 json_object_object_add(json_evpn, "macs", json_mac);
490 json_object_object_add(json, vni_str, json_evpn);
491 }
492 }
493
494 /*
495 * Print MACs in detail for all EVPNs.
496 */
497 static void zevpn_print_mac_hash_all_evpn_detail(struct hash_bucket *bucket,
498 void *ctxt)
499 {
500 struct vty *vty;
501 json_object *json = NULL, *json_evpn = NULL;
502 json_object *json_mac = NULL;
503 struct zebra_evpn *zevpn;
504 uint32_t num_macs;
505 struct mac_walk_ctx *wctx = ctxt;
506 char vni_str[VNI_STR_LEN];
507
508 vty = wctx->vty;
509 json = wctx->json;
510
511 zevpn = (struct zebra_evpn *)bucket->data;
512 if (!zevpn) {
513 if (json)
514 vty_out(vty, "{}\n");
515 return;
516 }
517 wctx->zevpn = zevpn;
518
519 /*We are iterating over a new EVPN, set the count to 0*/
520 wctx->count = 0;
521
522 num_macs = num_valid_macs(zevpn);
523 if (!num_macs)
524 return;
525
526 if (wctx->print_dup && (num_dup_detected_macs(zevpn) == 0))
527 return;
528
529 if (json) {
530 json_evpn = json_object_new_object();
531 json_mac = json_object_new_object();
532 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
533 }
534
535 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
536 if (json == NULL) {
537 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
538 zevpn->vni, num_macs);
539 } else
540 json_object_int_add(json_evpn, "numMacs", num_macs);
541 }
542 /* assign per-evpn to wctx->json object to fill macs
543 * under the evpn. Re-assign primary json object to fill
544 * next evpn information.
545 */
546 wctx->json = json_mac;
547 if (wctx->print_dup)
548 hash_iterate(zevpn->mac_table,
549 zebra_evpn_print_dad_mac_hash_detail, wctx);
550 else
551 hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
552 wctx);
553 wctx->json = json;
554 if (json) {
555 if (wctx->count)
556 json_object_object_add(json_evpn, "macs", json_mac);
557 json_object_object_add(json, vni_str, json_evpn);
558 }
559 }
560
561 static void zl3vni_print_nh_hash(struct hash_bucket *bucket, void *ctx)
562 {
563 struct nh_walk_ctx *wctx = NULL;
564 struct vty *vty = NULL;
565 struct json_object *json_evpn = NULL;
566 struct json_object *json_nh = NULL;
567 struct zebra_neigh *n = NULL;
568 char buf1[ETHER_ADDR_STRLEN];
569 char buf2[INET6_ADDRSTRLEN];
570
571 wctx = (struct nh_walk_ctx *)ctx;
572 vty = wctx->vty;
573 json_evpn = wctx->json;
574 if (json_evpn)
575 json_nh = json_object_new_object();
576 n = (struct zebra_neigh *)bucket->data;
577
578 if (!json_evpn) {
579 vty_out(vty, "%-15s %-17s\n",
580 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
581 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
582 } else {
583 json_object_string_add(json_nh, "nexthopIp",
584 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
585 json_object_string_add(
586 json_nh, "routerMac",
587 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
588 json_object_object_add(json_evpn,
589 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
590 json_nh);
591 }
592 }
593
594 static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket,
595 void **args)
596 {
597 struct vty *vty = NULL;
598 json_object *json = NULL;
599 json_object *json_evpn = NULL;
600 struct zebra_l3vni *zl3vni = NULL;
601 uint32_t num_nh = 0;
602 struct nh_walk_ctx wctx;
603 char vni_str[VNI_STR_LEN];
604
605 vty = (struct vty *)args[0];
606 json = (struct json_object *)args[1];
607
608 zl3vni = (struct zebra_l3vni *)bucket->data;
609
610 num_nh = hashcount(zl3vni->nh_table);
611 if (!num_nh)
612 return;
613
614 if (json) {
615 json_evpn = json_object_new_object();
616 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
617 }
618
619 if (json == NULL) {
620 vty_out(vty, "\nVNI %u #Next-Hops %u\n\n", zl3vni->vni, num_nh);
621 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
622 } else
623 json_object_int_add(json_evpn, "numNextHops", num_nh);
624
625 memset(&wctx, 0, sizeof(wctx));
626 wctx.vty = vty;
627 wctx.json = json_evpn;
628 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
629 if (json)
630 json_object_object_add(json, vni_str, json_evpn);
631 }
632
633 static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket,
634 void **args)
635 {
636 struct vty *vty = NULL;
637 json_object *json = NULL;
638 json_object *json_evpn = NULL;
639 struct zebra_l3vni *zl3vni = NULL;
640 uint32_t num_rmacs;
641 struct rmac_walk_ctx wctx;
642 char vni_str[VNI_STR_LEN];
643
644 vty = (struct vty *)args[0];
645 json = (struct json_object *)args[1];
646
647 zl3vni = (struct zebra_l3vni *)bucket->data;
648
649 num_rmacs = hashcount(zl3vni->rmac_table);
650 if (!num_rmacs)
651 return;
652
653 if (json) {
654 json_evpn = json_object_new_object();
655 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
656 }
657
658 if (json == NULL) {
659 vty_out(vty, "\nVNI %u #RMACs %u\n\n", zl3vni->vni, num_rmacs);
660 vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
661 } else
662 json_object_int_add(json_evpn, "numRmacs", num_rmacs);
663
664 /* assign per-vni to wctx->json object to fill macs
665 * under the vni. Re-assign primary json object to fill
666 * next vni information.
667 */
668 memset(&wctx, 0, sizeof(wctx));
669 wctx.vty = vty;
670 wctx.json = json_evpn;
671 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
672 if (json)
673 json_object_object_add(json, vni_str, json_evpn);
674 }
675
676 static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
677 {
678 struct zebra_mac *zrmac = NULL;
679 struct rmac_walk_ctx *wctx = NULL;
680 struct vty *vty = NULL;
681 struct json_object *json = NULL;
682 struct json_object *json_rmac = NULL;
683 char buf[PREFIX_STRLEN];
684
685 wctx = (struct rmac_walk_ctx *)ctx;
686 vty = wctx->vty;
687 json = wctx->json;
688 if (json)
689 json_rmac = json_object_new_object();
690 zrmac = (struct zebra_mac *)bucket->data;
691
692 if (!json) {
693 vty_out(vty, "%-17s %-21pI4\n",
694 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
695 &zrmac->fwd_info.r_vtep_ip);
696 } else {
697 json_object_string_add(
698 json_rmac, "routerMac",
699 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
700 json_object_string_addf(json_rmac, "vtepIp", "%pI4",
701 &zrmac->fwd_info.r_vtep_ip);
702 json_object_object_add(
703 json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
704 json_rmac);
705 }
706 }
707
708 /* print a specific L3 VNI entry */
709 static void zl3vni_print(struct zebra_l3vni *zl3vni, void **ctx)
710 {
711 char buf[PREFIX_STRLEN];
712 struct vty *vty = NULL;
713 json_object *json = NULL;
714 struct zebra_evpn *zevpn = NULL;
715 json_object *json_evpn_list = NULL;
716 struct listnode *node = NULL, *nnode = NULL;
717
718 vty = ctx[0];
719 json = ctx[1];
720
721 if (!json) {
722 vty_out(vty, "VNI: %u\n", zl3vni->vni);
723 vty_out(vty, " Type: %s\n", "L3");
724 vty_out(vty, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
725 vty_out(vty, " Local Vtep Ip: %pI4\n",
726 &zl3vni->local_vtep_ip);
727 vty_out(vty, " Vxlan-Intf: %s\n",
728 zl3vni_vxlan_if_name(zl3vni));
729 vty_out(vty, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
730 vty_out(vty, " State: %s\n", zl3vni_state2str(zl3vni));
731 vty_out(vty, " VNI Filter: %s\n",
732 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
733 ? "prefix-routes-only"
734 : "none");
735 vty_out(vty, " System MAC: %s\n",
736 zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
737 vty_out(vty, " Router MAC: %s\n",
738 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
739 vty_out(vty, " L2 VNIs: ");
740 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn))
741 vty_out(vty, "%u ", zevpn->vni);
742 vty_out(vty, "\n");
743 } else {
744 json_evpn_list = json_object_new_array();
745 json_object_int_add(json, "vni", zl3vni->vni);
746 json_object_string_add(json, "type", "L3");
747 #if CONFDATE > 20240210
748 CPP_NOTICE("Drop `vrf` from JSON outputs")
749 #endif
750 json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
751 json_object_string_add(json, "tenantVrf",
752 zl3vni_vrf_name(zl3vni));
753 json_object_string_addf(json, "localVtepIp", "%pI4",
754 &zl3vni->local_vtep_ip);
755 json_object_string_add(json, "vxlanIntf",
756 zl3vni_vxlan_if_name(zl3vni));
757 json_object_string_add(json, "sviIntf",
758 zl3vni_svi_if_name(zl3vni));
759 json_object_string_add(json, "state", zl3vni_state2str(zl3vni));
760 json_object_string_add(
761 json, "sysMac",
762 zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
763 json_object_string_add(
764 json, "routerMac",
765 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
766 json_object_string_add(
767 json, "vniFilter",
768 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
769 ? "prefix-routes-only"
770 : "none");
771 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn)) {
772 json_object_array_add(json_evpn_list,
773 json_object_new_int(zevpn->vni));
774 }
775 json_object_object_add(json, "l2Vnis", json_evpn_list);
776 }
777 }
778
779 /* print a L3 VNI hash entry */
780 static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[])
781 {
782 struct vty *vty = NULL;
783 json_object *json = NULL;
784 json_object *json_evpn = NULL;
785 struct zebra_l3vni *zl3vni = NULL;
786
787 vty = (struct vty *)ctx[0];
788 json = (json_object *)ctx[1];
789
790 zl3vni = (struct zebra_l3vni *)bucket->data;
791
792 if (!json) {
793 vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
794 zl3vni->vni, "L3", zl3vni_vxlan_if_name(zl3vni),
795 hashcount(zl3vni->rmac_table),
796 hashcount(zl3vni->nh_table), "n/a",
797 zl3vni_vrf_name(zl3vni));
798 } else {
799 char vni_str[VNI_STR_LEN];
800
801 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
802 json_evpn = json_object_new_object();
803 json_object_int_add(json_evpn, "vni", zl3vni->vni);
804 json_object_string_add(json_evpn, "vxlanIf",
805 zl3vni_vxlan_if_name(zl3vni));
806 json_object_int_add(json_evpn, "numMacs",
807 hashcount(zl3vni->rmac_table));
808 json_object_int_add(json_evpn, "numArpNd",
809 hashcount(zl3vni->nh_table));
810 json_object_string_add(json_evpn, "numRemoteVteps", "n/a");
811 json_object_string_add(json_evpn, "type", "L3");
812 json_object_string_add(json_evpn, "tenantVrf",
813 zl3vni_vrf_name(zl3vni));
814 json_object_object_add(json, vni_str, json_evpn);
815 }
816 }
817
818 /* print a L3 VNI hash entry in detail*/
819 static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
820 {
821 struct vty *vty = NULL;
822 struct zebra_l3vni *zl3vni = NULL;
823 json_object *json_array = NULL;
824 bool use_json = false;
825 struct zebra_evpn_show *zes = data;
826
827 vty = zes->vty;
828 json_array = zes->json;
829 use_json = zes->use_json;
830
831 zl3vni = (struct zebra_l3vni *)bucket->data;
832
833 zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni,
834 use_json, json_array);
835
836 if (!use_json)
837 vty_out(vty, "\n");
838 }
839
840 static int zvni_map_to_svi_ns(struct ns *ns,
841 void *_in_param,
842 void **_p_ifp)
843 {
844 struct zebra_ns *zns = ns->info;
845 struct route_node *rn;
846 struct zebra_from_svi_param *in_param =
847 (struct zebra_from_svi_param *)_in_param;
848 struct zebra_l2info_vlan *vl;
849 struct interface *tmp_if = NULL;
850 struct interface **p_ifp = (struct interface **)_p_ifp;
851 struct zebra_if *zif;
852
853 assert(in_param && p_ifp);
854
855 /* TODO: Optimize with a hash. */
856 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
857 tmp_if = (struct interface *)rn->info;
858 /* Check oper status of the SVI. */
859 if (!tmp_if || !if_is_operative(tmp_if))
860 continue;
861 zif = tmp_if->info;
862 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
863 || zif->link != in_param->br_if)
864 continue;
865 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
866
867 if (vl->vid == in_param->vid) {
868 *p_ifp = tmp_if;
869 return NS_WALK_STOP;
870 }
871 }
872 return NS_WALK_CONTINUE;
873 }
874
875 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
876 * of two cases:
877 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
878 * linked to the bridge
879 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge interface
880 * itself
881 */
882 struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
883 {
884 struct interface *tmp_if = NULL;
885 struct zebra_if *zif;
886 struct zebra_from_svi_param in_param;
887 struct interface **p_ifp;
888 /* Defensive check, caller expected to invoke only with valid bridge. */
889 if (!br_if)
890 return NULL;
891
892 /* Determine if bridge is VLAN-aware or not */
893 zif = br_if->info;
894 assert(zif);
895 in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
896 /* Check oper status of the SVI. */
897 if (!in_param.bridge_vlan_aware)
898 return if_is_operative(br_if) ? br_if : NULL;
899
900 in_param.vid = vid;
901 in_param.br_if = br_if;
902 in_param.zif = NULL;
903 p_ifp = &tmp_if;
904 /* Identify corresponding VLAN interface. */
905 ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param,
906 (void **)p_ifp);
907 return tmp_if;
908 }
909
910 static int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)
911 {
912 zevpn_vxlan_if_set(zevpn, zevpn->vxlan_if, false /* set */);
913
914 /* Remove references to the BUM mcast grp */
915 zebra_vxlan_sg_deref(zevpn->local_vtep_ip, zevpn->mcast_grp);
916
917 return zebra_evpn_del(zevpn);
918 }
919
920 static int zevpn_build_hash_table_zns(struct ns *ns,
921 void *param_in __attribute__((unused)),
922 void **param_out __attribute__((unused)))
923 {
924 struct zebra_ns *zns = ns->info;
925 struct route_node *rn;
926 struct interface *ifp;
927 struct zebra_vrf *zvrf;
928
929 zvrf = zebra_vrf_get_evpn();
930
931 /* Walk VxLAN interfaces and create EVPN hash. */
932 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
933 vni_t vni;
934 struct zebra_evpn *zevpn = NULL;
935 struct zebra_l3vni *zl3vni = NULL;
936 struct zebra_if *zif;
937 struct zebra_l2info_vxlan *vxl;
938 struct zebra_vxlan_vni *vnip;
939
940 ifp = (struct interface *)rn->info;
941 if (!ifp)
942 continue;
943 zif = ifp->info;
944 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
945 continue;
946
947 vxl = &zif->l2info.vxl;
948 vnip = zebra_vxlan_if_vni_find(zif, 0);
949 vni = vnip->vni;
950 /* link of VXLAN interface should be in zebra_evpn_vrf */
951 if (zvrf->zns->ns_id != vxl->link_nsid) {
952 if (IS_ZEBRA_DEBUG_VXLAN)
953 zlog_debug(
954 "Intf %s(%u) VNI %u, link not in same "
955 "namespace than BGP EVPN core instance ",
956 ifp->name, ifp->ifindex, vni);
957 continue;
958 }
959 /* L3-VNI and L2-VNI are handled seperately */
960 zl3vni = zl3vni_lookup(vni);
961 if (zl3vni) {
962
963 if (IS_ZEBRA_DEBUG_VXLAN)
964 zlog_debug(
965 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
966 ifp->name, ifp->ifindex, vni);
967
968 /* associate with vxlan_if */
969 zl3vni->local_vtep_ip = vxl->vtep_ip;
970 zl3vni->vxlan_if = ifp;
971
972 /*
973 * we need to associate with SVI.
974 * we can associate with svi-if only after association
975 * with vxlan-intf is complete
976 */
977 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
978
979 /* Associate l3vni to mac-vlan and extract VRR MAC */
980 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
981
982 if (IS_ZEBRA_DEBUG_VXLAN)
983 zlog_debug("create l3vni %u svi_if %s mac_vlan_if %s",
984 vni, zl3vni->svi_if ? zl3vni->svi_if->name
985 : "NIL",
986 zl3vni->mac_vlan_if ?
987 zl3vni->mac_vlan_if->name : "NIL");
988
989 if (is_l3vni_oper_up(zl3vni))
990 zebra_vxlan_process_l3vni_oper_up(zl3vni);
991
992 } else {
993 struct interface *vlan_if = NULL;
994
995 if (IS_ZEBRA_DEBUG_VXLAN)
996 zlog_debug(
997 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %pI4",
998 ifp->name, ifp->ifindex, vni,
999 &vxl->vtep_ip);
1000
1001 /* EVPN hash entry is expected to exist, if the BGP process is killed */
1002 zevpn = zebra_evpn_lookup(vni);
1003 if (zevpn) {
1004 zlog_debug(
1005 "EVPN hash already present for IF %s(%u) L2-VNI %u",
1006 ifp->name, ifp->ifindex, vni);
1007
1008 /*
1009 * Inform BGP if intf is up and mapped to
1010 * bridge.
1011 */
1012 if (if_is_operative(ifp) &&
1013 zif->brslave_info.br_if)
1014 zebra_evpn_send_add_to_client(zevpn);
1015
1016 /* Send Local MAC-entries to client */
1017 zebra_evpn_send_mac_list_to_client(zevpn);
1018
1019 /* Send Loval Neighbor entries to client */
1020 zebra_evpn_send_neigh_to_client(zevpn);
1021 } else {
1022 zevpn = zebra_evpn_add(vni);
1023 if (!zevpn) {
1024 zlog_debug(
1025 "Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
1026 ifp->name, ifp->ifindex, vni);
1027 return NS_WALK_CONTINUE;
1028 }
1029
1030 if (zevpn->local_vtep_ip.s_addr
1031 != vxl->vtep_ip.s_addr
1032 || zevpn->mcast_grp.s_addr
1033 != vnip->mcast_grp.s_addr) {
1034 zebra_vxlan_sg_deref(
1035 zevpn->local_vtep_ip,
1036 zevpn->mcast_grp);
1037 zebra_vxlan_sg_ref(vxl->vtep_ip,
1038 vnip->mcast_grp);
1039 zevpn->local_vtep_ip = vxl->vtep_ip;
1040 zevpn->mcast_grp = vnip->mcast_grp;
1041 /* on local vtep-ip check if ES
1042 * orig-ip needs to be updated
1043 */
1044 zebra_evpn_es_set_base_evpn(zevpn);
1045 }
1046 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
1047 vlan_if = zvni_map_to_svi(
1048 vnip->access_vlan,
1049 zif->brslave_info.br_if);
1050 if (vlan_if) {
1051 zevpn->svi_if = vlan_if;
1052 zevpn->vrf_id = vlan_if->vrf->vrf_id;
1053 zl3vni = zl3vni_from_vrf(
1054 vlan_if->vrf->vrf_id);
1055 if (zl3vni)
1056 listnode_add_sort(
1057 zl3vni->l2vnis, zevpn);
1058 }
1059
1060 /*
1061 * Inform BGP if intf is up and mapped to
1062 * bridge.
1063 */
1064 if (if_is_operative(ifp) &&
1065 zif->brslave_info.br_if)
1066 zebra_evpn_send_add_to_client(zevpn);
1067 }
1068 }
1069 }
1070 return NS_WALK_CONTINUE;
1071 }
1072
1073 /*
1074 * Build the VNI hash table by going over the VxLAN interfaces. This
1075 * is called when EVPN (advertise-all-vni) is enabled.
1076 */
1077
1078 static void zevpn_build_hash_table(void)
1079 {
1080 ns_walk_func(zevpn_build_hash_table_zns, NULL, NULL);
1081 }
1082
1083 /*
1084 * Cleanup EVPN/VTEP and update kernel
1085 */
1086 static void zebra_evpn_vxlan_cleanup_all(struct hash_bucket *bucket, void *arg)
1087 {
1088 struct zebra_evpn *zevpn = NULL;
1089 struct zebra_l3vni *zl3vni = NULL;
1090
1091 zevpn = (struct zebra_evpn *)bucket->data;
1092
1093 /* remove l2vni from l2vni's tenant-vrf l3-vni list */
1094 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
1095 if (zl3vni)
1096 listnode_delete(zl3vni->l2vnis, zevpn);
1097
1098 zebra_evpn_cleanup_all(bucket, arg);
1099 }
1100
1101 /* cleanup L3VNI */
1102 static void zl3vni_cleanup_all(struct hash_bucket *bucket, void *args)
1103 {
1104 struct zebra_l3vni *zl3vni = NULL;
1105
1106 zl3vni = (struct zebra_l3vni *)bucket->data;
1107
1108 zebra_vxlan_process_l3vni_oper_down(zl3vni);
1109 }
1110
1111 static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
1112 const struct prefix *host)
1113 {
1114 struct host_rb_entry lookup;
1115 struct host_rb_entry *hle;
1116
1117 memset(&lookup, 0, sizeof(lookup));
1118 memcpy(&lookup.p, host, sizeof(*host));
1119
1120 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1121 if (hle)
1122 return;
1123
1124 hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
1125 memcpy(hle, &lookup, sizeof(lookup));
1126
1127 RB_INSERT(host_rb_tree_entry, hrbe, hle);
1128 }
1129
1130 static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
1131 {
1132 struct host_rb_entry lookup;
1133 struct host_rb_entry *hle;
1134
1135 memset(&lookup, 0, sizeof(lookup));
1136 memcpy(&lookup.p, host, sizeof(*host));
1137
1138 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
1139 if (hle) {
1140 RB_REMOVE(host_rb_tree_entry, hrbe, hle);
1141 XFREE(MTYPE_HOST_PREFIX, hle);
1142 }
1143
1144 return;
1145 }
1146
1147 /*
1148 * Look up MAC hash entry.
1149 */
1150 static struct zebra_mac *zl3vni_rmac_lookup(struct zebra_l3vni *zl3vni,
1151 const struct ethaddr *rmac)
1152 {
1153 struct zebra_mac tmp;
1154 struct zebra_mac *pmac;
1155
1156 memset(&tmp, 0, sizeof(tmp));
1157 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
1158 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
1159
1160 return pmac;
1161 }
1162
1163 /*
1164 * Callback to allocate RMAC hash entry.
1165 */
1166 static void *zl3vni_rmac_alloc(void *p)
1167 {
1168 const struct zebra_mac *tmp_rmac = p;
1169 struct zebra_mac *zrmac;
1170
1171 zrmac = XCALLOC(MTYPE_L3VNI_MAC, sizeof(struct zebra_mac));
1172 *zrmac = *tmp_rmac;
1173
1174 return ((void *)zrmac);
1175 }
1176
1177 /*
1178 * Add RMAC entry to l3-vni
1179 */
1180 static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni,
1181 const struct ethaddr *rmac)
1182 {
1183 struct zebra_mac tmp_rmac;
1184 struct zebra_mac *zrmac = NULL;
1185
1186 memset(&tmp_rmac, 0, sizeof(tmp_rmac));
1187 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
1188 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
1189 zrmac->nh_list = list_new();
1190 zrmac->nh_list->cmp = (int (*)(void *, void *))l3vni_rmac_nh_list_cmp;
1191 zrmac->nh_list->del = (void (*)(void *))l3vni_rmac_nh_free;
1192
1193 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
1194 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
1195
1196 return zrmac;
1197 }
1198
1199 /*
1200 * Delete MAC entry.
1201 */
1202 static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac)
1203 {
1204 struct zebra_mac *tmp_rmac;
1205
1206 /* free the list of nh list*/
1207 list_delete(&zrmac->nh_list);
1208
1209 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
1210 XFREE(MTYPE_L3VNI_MAC, tmp_rmac);
1211
1212 return 0;
1213 }
1214
1215 /*
1216 * Install remote RMAC into the forwarding plane.
1217 */
1218 static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
1219 struct zebra_mac *zrmac)
1220 {
1221 const struct zebra_if *zif = NULL, *br_zif = NULL;
1222 const struct zebra_vxlan_vni *vni;
1223 const struct interface *br_ifp;
1224 enum zebra_dplane_result res;
1225 vlanid_t vid;
1226
1227 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1228 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1229 return 0;
1230
1231 zif = zl3vni->vxlan_if->info;
1232 if (!zif)
1233 return -1;
1234
1235 br_ifp = zif->brslave_info.br_if;
1236 if (br_ifp == NULL)
1237 return -1;
1238
1239 vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1240
1241 br_zif = (const struct zebra_if *)br_ifp->info;
1242
1243 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1244 vid = vni->access_vlan;
1245 else
1246 vid = 0;
1247
1248 res = dplane_rem_mac_add(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr,
1249 vni->vni, zrmac->fwd_info.r_vtep_ip, 0, 0,
1250 false /*was_static*/);
1251 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1252 return 0;
1253 else
1254 return -1;
1255 }
1256
1257 /*
1258 * Uninstall remote RMAC from the forwarding plane.
1259 */
1260 static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
1261 struct zebra_mac *zrmac)
1262 {
1263 const struct zebra_if *zif = NULL, *br_zif;
1264 const struct zebra_vxlan_vni *vni;
1265 const struct interface *br_ifp;
1266 vlanid_t vid;
1267 enum zebra_dplane_result res;
1268
1269 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
1270 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
1271 return 0;
1272
1273 if (!zl3vni->vxlan_if) {
1274 if (IS_ZEBRA_DEBUG_VXLAN)
1275 zlog_debug(
1276 "RMAC %pEA on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
1277 &zrmac->macaddr, zl3vni->vni, zl3vni);
1278 return -1;
1279 }
1280
1281 zif = zl3vni->vxlan_if->info;
1282 if (!zif)
1283 return -1;
1284
1285 br_ifp = zif->brslave_info.br_if;
1286 if (br_ifp == NULL)
1287 return -1;
1288
1289 vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1290
1291 br_zif = (const struct zebra_if *)br_ifp->info;
1292 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
1293 vid = vni->access_vlan;
1294 else
1295 vid = 0;
1296
1297 res = dplane_rem_mac_del(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr,
1298 vni->vni, zrmac->fwd_info.r_vtep_ip);
1299 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
1300 return 0;
1301 else
1302 return -1;
1303 }
1304
1305 /* handle rmac add */
1306 static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
1307 const struct ethaddr *rmac,
1308 const struct ipaddr *vtep_ip)
1309 {
1310 struct zebra_mac *zrmac = NULL;
1311 struct ipaddr *vtep = NULL;
1312
1313 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
1314 if (!zrmac) {
1315
1316 /* Create the RMAC entry, or update its vtep, if necessary. */
1317 zrmac = zl3vni_rmac_add(zl3vni, rmac);
1318 if (!zrmac) {
1319 zlog_debug(
1320 "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA",
1321 rmac, zl3vni->vni, vtep_ip);
1322 return -1;
1323 }
1324 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
1325 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1326
1327 vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1328 memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1329 if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1330 XFREE(MTYPE_EVPN_VTEP, vtep);
1331
1332 /* Send RMAC for FPM processing */
1333 hook_call(zebra_rmac_update, zrmac, zl3vni, false,
1334 "new RMAC added");
1335
1336 /* install rmac in kernel */
1337 zl3vni_rmac_install(zl3vni, zrmac);
1338 } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1339 &vtep_ip->ipaddr_v4)) {
1340 if (IS_ZEBRA_DEBUG_VXLAN)
1341 zlog_debug(
1342 "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA",
1343 zl3vni->vni, &zrmac->fwd_info.r_vtep_ip,
1344 vtep_ip, rmac);
1345
1346 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
1347
1348 vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
1349 memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
1350 if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep))
1351 XFREE(MTYPE_EVPN_VTEP, vtep);
1352
1353 /* install rmac in kernel */
1354 zl3vni_rmac_install(zl3vni, zrmac);
1355 }
1356
1357 return 0;
1358 }
1359
1360
1361 /* handle rmac delete */
1362 static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
1363 struct zebra_mac *zrmac,
1364 struct ipaddr *vtep_ip)
1365 {
1366 struct ipaddr ipv4_vtep;
1367
1368 if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) {
1369 memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
1370 ipv4_vtep.ipa_type = IPADDR_V4;
1371 if (vtep_ip->ipa_type == IPADDR_V6)
1372 ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
1373 &ipv4_vtep.ipaddr_v4);
1374 else
1375 memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
1376 sizeof(struct in_addr));
1377
1378 /* remove nh from rmac's list */
1379 l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep);
1380 /* delete nh is same as current selected, fall back to
1381 * one present in the list
1382 */
1383 if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
1384 &ipv4_vtep.ipaddr_v4) &&
1385 listcount(zrmac->nh_list)) {
1386 struct ipaddr *vtep;
1387
1388 vtep = listgetdata(listhead(zrmac->nh_list));
1389 zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4;
1390 if (IS_ZEBRA_DEBUG_VXLAN)
1391 zlog_debug(
1392 "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
1393 zl3vni->vni, &ipv4_vtep,
1394 &zrmac->fwd_info.r_vtep_ip,
1395 &zrmac->macaddr);
1396
1397 /* install rmac in kernel */
1398 zl3vni_rmac_install(zl3vni, zrmac);
1399 }
1400
1401 if (!listcount(zrmac->nh_list)) {
1402 /* uninstall from kernel */
1403 zl3vni_rmac_uninstall(zl3vni, zrmac);
1404
1405 /* Send RMAC for FPM processing */
1406 hook_call(zebra_rmac_update, zrmac, zl3vni, true,
1407 "RMAC deleted");
1408
1409 if (IS_ZEBRA_DEBUG_VXLAN)
1410 zlog_debug(
1411 "L3VNI %u RMAC %pEA vtep_ip %pIA delete",
1412 zl3vni->vni, &zrmac->macaddr, vtep_ip);
1413
1414 /* del the rmac entry */
1415 zl3vni_rmac_del(zl3vni, zrmac);
1416 }
1417 }
1418 }
1419
1420 /*
1421 * Look up nh hash entry on a l3-vni.
1422 */
1423 static struct zebra_neigh *zl3vni_nh_lookup(struct zebra_l3vni *zl3vni,
1424 const struct ipaddr *ip)
1425 {
1426 struct zebra_neigh tmp;
1427 struct zebra_neigh *n;
1428
1429 memset(&tmp, 0, sizeof(tmp));
1430 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
1431 n = hash_lookup(zl3vni->nh_table, &tmp);
1432
1433 return n;
1434 }
1435
1436
1437 /*
1438 * Callback to allocate NH hash entry on L3-VNI.
1439 */
1440 static void *zl3vni_nh_alloc(void *p)
1441 {
1442 const struct zebra_neigh *tmp_n = p;
1443 struct zebra_neigh *n;
1444
1445 n = XCALLOC(MTYPE_L3NEIGH, sizeof(struct zebra_neigh));
1446 *n = *tmp_n;
1447
1448 return ((void *)n);
1449 }
1450
1451 /*
1452 * Add neighbor entry.
1453 */
1454 static struct zebra_neigh *zl3vni_nh_add(struct zebra_l3vni *zl3vni,
1455 const struct ipaddr *ip,
1456 const struct ethaddr *mac)
1457 {
1458 struct zebra_neigh tmp_n;
1459 struct zebra_neigh *n = NULL;
1460
1461 memset(&tmp_n, 0, sizeof(tmp_n));
1462 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
1463 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
1464
1465 RB_INIT(host_rb_tree_entry, &n->host_rb);
1466
1467 memcpy(&n->emac, mac, ETH_ALEN);
1468 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1469 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
1470
1471 return n;
1472 }
1473
1474 /*
1475 * Delete neighbor entry.
1476 */
1477 static int zl3vni_nh_del(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1478 {
1479 struct zebra_neigh *tmp_n;
1480 struct host_rb_entry *hle;
1481
1482 while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
1483 hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
1484
1485 RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
1486 XFREE(MTYPE_HOST_PREFIX, hle);
1487 }
1488
1489 tmp_n = hash_release(zl3vni->nh_table, n);
1490 XFREE(MTYPE_L3NEIGH, tmp_n);
1491
1492 return 0;
1493 }
1494
1495 /*
1496 * Install remote nh as neigh into the kernel.
1497 */
1498 static int zl3vni_nh_install(struct zebra_l3vni *zl3vni, struct zebra_neigh *n)
1499 {
1500 uint8_t flags;
1501 int ret = 0;
1502
1503 if (!is_l3vni_oper_up(zl3vni))
1504 return -1;
1505
1506 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1507 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1508 return 0;
1509
1510 flags = DPLANE_NTF_EXT_LEARNED;
1511 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
1512 flags |= DPLANE_NTF_ROUTER;
1513
1514 dplane_rem_neigh_add(zl3vni->svi_if, &n->ip, &n->emac, flags,
1515 false /*was_static*/);
1516
1517 return ret;
1518 }
1519
1520 /*
1521 * Uninstall remote nh from the kernel.
1522 */
1523 static int zl3vni_nh_uninstall(struct zebra_l3vni *zl3vni,
1524 struct zebra_neigh *n)
1525 {
1526 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
1527 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
1528 return 0;
1529
1530 if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
1531 return 0;
1532
1533 dplane_rem_neigh_delete(zl3vni->svi_if, &n->ip);
1534
1535 return 0;
1536 }
1537
1538 /* add remote vtep as a neigh entry */
1539 static int zl3vni_remote_nh_add(struct zebra_l3vni *zl3vni,
1540 const struct ipaddr *vtep_ip,
1541 const struct ethaddr *rmac,
1542 const struct prefix *host_prefix)
1543 {
1544 struct zebra_neigh *nh = NULL;
1545
1546 /* Create the next hop entry, or update its mac, if necessary. */
1547 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
1548 if (!nh) {
1549 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
1550 if (!nh) {
1551 zlog_debug(
1552 "Failed to add NH %pIA as Neigh (RMAC %pEA L3-VNI %u prefix %pFX)",
1553 vtep_ip, rmac, zl3vni->vni, host_prefix);
1554 return -1;
1555 }
1556
1557 /* install the nh neigh in kernel */
1558 zl3vni_nh_install(zl3vni, nh);
1559 } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
1560 if (IS_ZEBRA_DEBUG_VXLAN)
1561 zlog_debug(
1562 "L3VNI %u RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX",
1563 zl3vni->vni, &nh->emac, rmac, vtep_ip,
1564 host_prefix);
1565
1566 memcpy(&nh->emac, rmac, ETH_ALEN);
1567 /* install (update) the nh neigh in kernel */
1568 zl3vni_nh_install(zl3vni, nh);
1569 }
1570
1571 rb_find_or_add_host(&nh->host_rb, host_prefix);
1572
1573 return 0;
1574 }
1575
1576 /* handle nh neigh delete */
1577 static void zl3vni_remote_nh_del(struct zebra_l3vni *zl3vni,
1578 struct zebra_neigh *nh,
1579 struct prefix *host_prefix)
1580 {
1581 rb_delete_host(&nh->host_rb, host_prefix);
1582
1583 if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
1584 /* uninstall from kernel */
1585 zl3vni_nh_uninstall(zl3vni, nh);
1586
1587 /* delete the nh entry */
1588 zl3vni_nh_del(zl3vni, nh);
1589 }
1590 }
1591
1592 /* handle neigh update from kernel - the only thing of interest is to
1593 * readd stale entries.
1594 */
1595 static int zl3vni_local_nh_add_update(struct zebra_l3vni *zl3vni,
1596 struct ipaddr *ip, uint16_t state)
1597 {
1598 #ifdef GNU_LINUX
1599 struct zebra_neigh *n = NULL;
1600
1601 n = zl3vni_nh_lookup(zl3vni, ip);
1602 if (!n)
1603 return 0;
1604
1605 /* all next hop neigh are remote and installed by frr.
1606 * If the kernel has aged this entry, re-install.
1607 */
1608 if (state & NUD_STALE)
1609 zl3vni_nh_install(zl3vni, n);
1610 #endif
1611 return 0;
1612 }
1613
1614 /* handle neigh delete from kernel */
1615 static int zl3vni_local_nh_del(struct zebra_l3vni *zl3vni, struct ipaddr *ip)
1616 {
1617 struct zebra_neigh *n = NULL;
1618
1619 n = zl3vni_nh_lookup(zl3vni, ip);
1620 if (!n)
1621 return 0;
1622
1623 /* all next hop neigh are remote and installed by frr.
1624 * If we get an age out notification for these neigh entries, we have to
1625 * install it back
1626 */
1627 zl3vni_nh_install(zl3vni, n);
1628
1629 return 0;
1630 }
1631
1632 /*
1633 * Hash function for L3 VNI.
1634 */
1635 static unsigned int l3vni_hash_keymake(const void *p)
1636 {
1637 const struct zebra_l3vni *zl3vni = p;
1638
1639 return jhash_1word(zl3vni->vni, 0);
1640 }
1641
1642 /*
1643 * Compare 2 L3 VNI hash entries.
1644 */
1645 static bool l3vni_hash_cmp(const void *p1, const void *p2)
1646 {
1647 const struct zebra_l3vni *zl3vni1 = p1;
1648 const struct zebra_l3vni *zl3vni2 = p2;
1649
1650 return (zl3vni1->vni == zl3vni2->vni);
1651 }
1652
1653 /*
1654 * Callback to allocate L3 VNI hash entry.
1655 */
1656 static void *zl3vni_alloc(void *p)
1657 {
1658 struct zebra_l3vni *zl3vni = NULL;
1659 const struct zebra_l3vni *tmp_l3vni = p;
1660
1661 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(struct zebra_l3vni));
1662 zl3vni->vni = tmp_l3vni->vni;
1663 return ((void *)zl3vni);
1664 }
1665
1666 /*
1667 * Look up L3 VNI hash entry.
1668 */
1669 struct zebra_l3vni *zl3vni_lookup(vni_t vni)
1670 {
1671 struct zebra_l3vni tmp_l3vni;
1672 struct zebra_l3vni *zl3vni = NULL;
1673
1674 memset(&tmp_l3vni, 0, sizeof(tmp_l3vni));
1675 tmp_l3vni.vni = vni;
1676 zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
1677
1678 return zl3vni;
1679 }
1680
1681 /*
1682 * Add L3 VNI hash entry.
1683 */
1684 static struct zebra_l3vni *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
1685 {
1686 struct zebra_l3vni tmp_zl3vni;
1687 struct zebra_l3vni *zl3vni = NULL;
1688
1689 memset(&tmp_zl3vni, 0, sizeof(tmp_zl3vni));
1690 tmp_zl3vni.vni = vni;
1691
1692 zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
1693
1694 zl3vni->vrf_id = vrf_id;
1695 zl3vni->svi_if = NULL;
1696 zl3vni->vxlan_if = NULL;
1697 zl3vni->l2vnis = list_new();
1698 zl3vni->l2vnis->cmp = zebra_evpn_list_cmp;
1699
1700 /* Create hash table for remote RMAC */
1701 zl3vni->rmac_table = zebra_mac_db_create("Zebra L3-VNI RMAC-Table");
1702
1703 /* Create hash table for neighbors */
1704 zl3vni->nh_table = zebra_neigh_db_create("Zebra L3-VNI next-hop table");
1705
1706 return zl3vni;
1707 }
1708
1709 /*
1710 * Delete L3 VNI hash entry.
1711 */
1712 static int zl3vni_del(struct zebra_l3vni *zl3vni)
1713 {
1714 struct zebra_l3vni *tmp_zl3vni;
1715
1716 /* free the list of l2vnis */
1717 list_delete(&zl3vni->l2vnis);
1718 zl3vni->l2vnis = NULL;
1719
1720 /* Free the rmac table */
1721 hash_free(zl3vni->rmac_table);
1722 zl3vni->rmac_table = NULL;
1723
1724 /* Free the nh table */
1725 hash_free(zl3vni->nh_table);
1726 zl3vni->nh_table = NULL;
1727
1728 /* Free the VNI hash entry and allocated memory. */
1729 tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
1730 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
1731
1732 return 0;
1733 }
1734
1735 static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
1736 void *_zl3vni,
1737 void **_pifp)
1738 {
1739 struct zebra_ns *zns = ns->info;
1740 struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)_zl3vni;
1741 struct route_node *rn = NULL;
1742 struct interface *ifp = NULL;
1743 struct zebra_vrf *zvrf;
1744
1745 zvrf = zebra_vrf_get_evpn();
1746
1747 assert(_pifp);
1748
1749 /* loop through all vxlan-interface */
1750 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1751
1752 struct zebra_if *zif = NULL;
1753 struct zebra_l2info_vxlan *vxl;
1754 struct zebra_vxlan_vni *vni = NULL;
1755
1756 ifp = (struct interface *)rn->info;
1757 if (!ifp)
1758 continue;
1759
1760 zif = ifp->info;
1761 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1762 continue;
1763
1764 vxl = &zif->l2info.vxl;
1765 vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1766 if (vni->vni != zl3vni->vni)
1767 continue;
1768
1769 /* link of VXLAN interface should be in zebra_evpn_vrf */
1770 if (zvrf->zns->ns_id != vxl->link_nsid) {
1771 if (IS_ZEBRA_DEBUG_VXLAN)
1772 zlog_debug(
1773 "Intf %s(%u) VNI %u, link not in same "
1774 "namespace than BGP EVPN core instance ",
1775 ifp->name, ifp->ifindex, vni->vni);
1776 continue;
1777 }
1778
1779
1780 zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip;
1781 *_pifp = (void *)ifp;
1782 return NS_WALK_STOP;
1783 }
1784
1785 return NS_WALK_CONTINUE;
1786 }
1787
1788 struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
1789 {
1790 struct interface **p_ifp;
1791 struct interface *ifp = NULL;
1792
1793 p_ifp = &ifp;
1794
1795 ns_walk_func(zl3vni_map_to_vxlan_if_ns,
1796 (void *)zl3vni, (void **)p_ifp);
1797 return ifp;
1798 }
1799
1800 struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
1801 {
1802 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
1803 struct zebra_vxlan_vni *vni = NULL; /* vni info in vxlan_if */
1804
1805 if (!zl3vni)
1806 return NULL;
1807
1808 if (!zl3vni->vxlan_if)
1809 return NULL;
1810
1811 zif = zl3vni->vxlan_if->info;
1812 if (!zif)
1813 return NULL;
1814
1815 vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
1816 if (!vni)
1817 return NULL;
1818
1819 return zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
1820 }
1821
1822 struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni)
1823 {
1824 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
1825
1826 if (!zl3vni)
1827 return NULL;
1828
1829 if (!zl3vni->vxlan_if)
1830 return NULL;
1831
1832 zif = zl3vni->vxlan_if->info;
1833 if (!zif)
1834 return NULL;
1835
1836 return zebra_evpn_map_to_macvlan(zif->brslave_info.br_if,
1837 zl3vni->svi_if);
1838 }
1839
1840
1841 struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id)
1842 {
1843 struct zebra_vrf *zvrf = NULL;
1844
1845 zvrf = zebra_vrf_lookup_by_id(vrf_id);
1846 if (!zvrf)
1847 return NULL;
1848
1849 return zl3vni_lookup(zvrf->l3vni);
1850 }
1851
1852 static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
1853 {
1854 struct zebra_ns *zns = ns->info;
1855 struct zebra_l3vni **p_zl3vni = (struct zebra_l3vni **)_p_zl3vni;
1856 struct zebra_from_svi_param *in_param =
1857 (struct zebra_from_svi_param *)_in_param;
1858 struct route_node *rn = NULL;
1859 struct interface *tmp_if = NULL;
1860 struct zebra_if *zif = NULL;
1861 struct zebra_vxlan_vni *vni = NULL;
1862
1863 assert(in_param && p_zl3vni);
1864
1865 /* loop through all vxlan-interface */
1866 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1867 tmp_if = (struct interface *)rn->info;
1868 if (!tmp_if)
1869 continue;
1870 zif = tmp_if->info;
1871 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1872 continue;
1873 if (!if_is_operative(tmp_if))
1874 continue;
1875
1876 if (zif->brslave_info.br_if != in_param->br_if)
1877 continue;
1878
1879 vni = zebra_vxlan_if_access_vlan_find(zif, in_param->bridge_vlan_aware,
1880 in_param->vid);
1881 if (!in_param->bridge_vlan_aware || vni) {
1882 *p_zl3vni = zl3vni_lookup(vni->vni);
1883 return NS_WALK_STOP;
1884 }
1885 }
1886
1887 return NS_WALK_CONTINUE;
1888 }
1889
1890 /*
1891 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1892 * neighbor notifications, to see if they are of interest.
1893 */
1894 static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
1895 struct interface *br_if)
1896 {
1897 struct zebra_l3vni *zl3vni = NULL;
1898 struct zebra_if *zif = NULL;
1899 struct zebra_from_svi_param in_param = {};
1900 struct zebra_l3vni **p_zl3vni;
1901
1902 if (!br_if)
1903 return NULL;
1904
1905 /* Make sure the linked interface is a bridge. */
1906 if (!IS_ZEBRA_IF_BRIDGE(br_if))
1907 return NULL;
1908 in_param.br_if = br_if;
1909
1910 /* Determine if bridge is VLAN-aware or not */
1911 zif = br_if->info;
1912 assert(zif);
1913 in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
1914 if (in_param.bridge_vlan_aware) {
1915 struct zebra_l2info_vlan *vl;
1916
1917 if (!IS_ZEBRA_IF_VLAN(ifp))
1918 return NULL;
1919
1920 zif = ifp->info;
1921 assert(zif);
1922 vl = &zif->l2info.vl;
1923 in_param.vid = vl->vid;
1924 }
1925
1926 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1927 /* TODO: Optimize with a hash. */
1928
1929 p_zl3vni = &zl3vni;
1930
1931 ns_walk_func(zl3vni_from_svi_ns, (void *)&in_param, (void **)p_zl3vni);
1932 return zl3vni;
1933 }
1934
1935 vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if)
1936 {
1937 vni_t vni = 0;
1938 struct zebra_evpn *zevpn = NULL;
1939 struct zebra_l3vni *zl3vni = NULL;
1940
1941 /* Check if an L3VNI belongs to this SVI interface.
1942 * If not, check if an L2VNI belongs to this SVI interface.
1943 */
1944 zl3vni = zl3vni_from_svi(ifp, br_if);
1945 if (zl3vni)
1946 vni = zl3vni->vni;
1947 else {
1948 zevpn = zebra_evpn_from_svi(ifp, br_if);
1949 if (zevpn)
1950 vni = zevpn->vni;
1951 }
1952
1953 return vni;
1954 }
1955
1956 static inline void zl3vni_get_vrr_rmac(struct zebra_l3vni *zl3vni,
1957 struct ethaddr *rmac)
1958 {
1959 if (!zl3vni)
1960 return;
1961
1962 if (!is_l3vni_oper_up(zl3vni))
1963 return;
1964
1965 if (zl3vni->mac_vlan_if && if_is_operative(zl3vni->mac_vlan_if))
1966 memcpy(rmac->octet, zl3vni->mac_vlan_if->hw_addr, ETH_ALEN);
1967 }
1968
1969 /*
1970 * Inform BGP about l3-vni.
1971 */
1972 static int zl3vni_send_add_to_client(struct zebra_l3vni *zl3vni)
1973 {
1974 struct stream *s = NULL;
1975 struct zserv *client = NULL;
1976 struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
1977 struct zebra_vrf *zvrf;
1978 bool is_anycast_mac = true;
1979
1980 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
1981 /* BGP may not be running. */
1982 if (!client)
1983 return 0;
1984
1985 zvrf = zebra_vrf_lookup_by_id(zl3vni->vrf_id);
1986 assert(zvrf);
1987
1988 /* get the svi and vrr rmac values */
1989 memset(&svi_rmac, 0, sizeof(svi_rmac));
1990 zl3vni_get_svi_rmac(zl3vni, &svi_rmac);
1991 zl3vni_get_vrr_rmac(zl3vni, &vrr_rmac);
1992
1993 /* In absence of vrr mac use svi mac as anycast MAC value */
1994 if (is_zero_mac(&vrr_rmac)) {
1995 memcpy(&vrr_rmac, &svi_rmac, ETH_ALEN);
1996 is_anycast_mac = false;
1997 }
1998
1999 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2000
2001 /* The message is used for both vni add and/or update like
2002 * vrr mac is added for l3vni SVI.
2003 */
2004 zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
2005 stream_putl(s, zl3vni->vni);
2006 stream_put(s, &svi_rmac, sizeof(struct ethaddr));
2007 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
2008 stream_put(s, &zl3vni->filter, sizeof(int));
2009 stream_putl(s, zl3vni->svi_if->ifindex);
2010 stream_put(s, &vrr_rmac, sizeof(struct ethaddr));
2011 stream_putl(s, is_anycast_mac);
2012
2013 /* Write packet size. */
2014 stream_putw_at(s, 0, stream_get_endp(s));
2015
2016 if (IS_ZEBRA_DEBUG_VXLAN)
2017 zlog_debug(
2018 "Send L3_VNI_ADD %u VRF %s RMAC %pEA VRR %pEA local-ip %pI4 filter %s to %s",
2019 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2020 &svi_rmac, &vrr_rmac, &zl3vni->local_vtep_ip,
2021 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
2022 ? "prefix-routes-only"
2023 : "none",
2024 zebra_route_string(client->proto));
2025
2026 client->l3vniadd_cnt++;
2027 return zserv_send_message(client, s);
2028 }
2029
2030 /*
2031 * Inform BGP about local l3-VNI deletion.
2032 */
2033 static int zl3vni_send_del_to_client(struct zebra_l3vni *zl3vni)
2034 {
2035 struct stream *s = NULL;
2036 struct zserv *client = NULL;
2037
2038 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
2039 /* BGP may not be running. */
2040 if (!client)
2041 return 0;
2042
2043 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2044
2045 zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
2046 stream_putl(s, zl3vni->vni);
2047
2048 /* Write packet size. */
2049 stream_putw_at(s, 0, stream_get_endp(s));
2050
2051 if (IS_ZEBRA_DEBUG_VXLAN)
2052 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
2053 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
2054 zebra_route_string(client->proto));
2055
2056 client->l3vnidel_cnt++;
2057 return zserv_send_message(client, s);
2058 }
2059
2060 void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni)
2061 {
2062 if (!zl3vni)
2063 return;
2064
2065 /* send l3vni add to BGP */
2066 zl3vni_send_add_to_client(zl3vni);
2067 }
2068
2069 void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni)
2070 {
2071 if (!zl3vni)
2072 return;
2073
2074 /* send l3-vni del to BGP*/
2075 zl3vni_send_del_to_client(zl3vni);
2076 }
2077
2078 static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
2079 {
2080 struct zebra_evpn *zevpn = (struct zebra_evpn *)bucket->data;
2081 struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)ctxt;
2082
2083 if (zevpn->vrf_id == zl3vni_vrf_id(zl3vni))
2084 listnode_add_sort(zl3vni->l2vnis, zevpn);
2085 }
2086
2087 /*
2088 * Handle transition of vni from l2 to l3 and vice versa.
2089 * This function handles only the L2VNI add/delete part of
2090 * the above transition.
2091 * L3VNI add/delete is handled by the calling functions.
2092 */
2093 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
2094 int add)
2095 {
2096 struct zebra_evpn *zevpn = NULL;
2097 struct zebra_l3vni *zl3vni = NULL;
2098
2099 /* There is a possibility that VNI notification was already received
2100 * from kernel and we programmed it as L2-VNI
2101 * In such a case we need to delete this L2-VNI first, so
2102 * that it can be reprogrammed as L3-VNI in the system. It is also
2103 * possible that the vrf-vni mapping is removed from FRR while the vxlan
2104 * interface is still present in kernel. In this case to keep it
2105 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
2106 */
2107 if (add) {
2108 /* Locate hash entry */
2109 zevpn = zebra_evpn_lookup(vni);
2110 if (!zevpn)
2111 return 0;
2112
2113 if (IS_ZEBRA_DEBUG_VXLAN)
2114 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
2115
2116 /* Delete EVPN from BGP. */
2117 zebra_evpn_send_del_to_client(zevpn);
2118
2119 zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
2120 zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
2121
2122 /* Free up all remote VTEPs, if any. */
2123 zebra_evpn_vtep_del_all(zevpn, 1);
2124
2125 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
2126 if (zl3vni)
2127 listnode_delete(zl3vni->l2vnis, zevpn);
2128
2129 /* Delete the hash entry. */
2130 if (zebra_evpn_vxlan_del(zevpn)) {
2131 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
2132 "Failed to del EVPN hash %p, VNI %u", zevpn,
2133 zevpn->vni);
2134 return -1;
2135 }
2136 } else {
2137 struct zebra_ns *zns;
2138 struct route_node *rn;
2139 struct interface *ifp;
2140 struct zebra_if *zif;
2141 struct zebra_vxlan_vni *vnip;
2142 struct zebra_l2info_vxlan *vxl;
2143 struct interface *vlan_if;
2144 bool found = false;
2145
2146 if (IS_ZEBRA_DEBUG_VXLAN)
2147 zlog_debug("Adding L2-VNI %u - transition from L3-VNI",
2148 vni);
2149
2150 /* Find VxLAN interface for this VNI. */
2151 zns = zebra_ns_lookup(NS_DEFAULT);
2152 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2153 ifp = (struct interface *)rn->info;
2154 if (!ifp)
2155 continue;
2156 zif = ifp->info;
2157 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2158 continue;
2159
2160 vxl = &zif->l2info.vxl;
2161 vnip = zebra_vxlan_if_vni_find(zif, vni);
2162 if (vnip) {
2163 found = true;
2164 break;
2165 }
2166 }
2167
2168 if (!found) {
2169 if (IS_ZEBRA_DEBUG_VXLAN)
2170 zlog_err(
2171 "Adding L2-VNI - Failed to find VxLAN interface for VNI %u",
2172 vni);
2173 return -1;
2174 }
2175
2176 /* Create VNI hash entry for L2VNI */
2177 zevpn = zebra_evpn_lookup(vni);
2178 if (zevpn)
2179 return 0;
2180
2181 zevpn = zebra_evpn_add(vni);
2182
2183 /* Find bridge interface for the VNI */
2184 vlan_if = zvni_map_to_svi(vnip->access_vlan,
2185 zif->brslave_info.br_if);
2186 if (vlan_if) {
2187 zevpn->vrf_id = vlan_if->vrf->vrf_id;
2188 zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
2189 if (zl3vni)
2190 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
2191 }
2192
2193 zevpn->vxlan_if = ifp;
2194 zevpn->local_vtep_ip = vxl->vtep_ip;
2195
2196 /* Inform BGP if the VNI is up and mapped to a bridge. */
2197 if (if_is_operative(ifp) && zif->brslave_info.br_if) {
2198 zebra_evpn_send_add_to_client(zevpn);
2199 zebra_evpn_read_mac_neigh(zevpn, ifp);
2200 }
2201 }
2202
2203 return 0;
2204 }
2205
2206 /* delete and uninstall rmac hash entry */
2207 static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx)
2208 {
2209 struct zebra_mac *zrmac = NULL;
2210 struct zebra_l3vni *zl3vni = NULL;
2211
2212 zrmac = (struct zebra_mac *)bucket->data;
2213 zl3vni = (struct zebra_l3vni *)ctx;
2214 zl3vni_rmac_uninstall(zl3vni, zrmac);
2215
2216 /* Send RMAC for FPM processing */
2217 hook_call(zebra_rmac_update, zrmac, zl3vni, true, "RMAC deleted");
2218
2219 zl3vni_rmac_del(zl3vni, zrmac);
2220 }
2221
2222 /* delete and uninstall nh hash entry */
2223 static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx)
2224 {
2225 struct zebra_neigh *n = NULL;
2226 struct zebra_l3vni *zl3vni = NULL;
2227
2228 n = (struct zebra_neigh *)bucket->data;
2229 zl3vni = (struct zebra_l3vni *)ctx;
2230 zl3vni_nh_uninstall(zl3vni, n);
2231 zl3vni_nh_del(zl3vni, n);
2232 }
2233
2234 /* re-add remote rmac if needed */
2235 static int zebra_vxlan_readd_remote_rmac(struct zebra_l3vni *zl3vni,
2236 struct ethaddr *rmac)
2237 {
2238 struct zebra_mac *zrmac = NULL;
2239
2240 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2241 if (!zrmac)
2242 return 0;
2243
2244 if (IS_ZEBRA_DEBUG_VXLAN)
2245 zlog_debug("Del remote RMAC %pEA L3VNI %u - readd",
2246 rmac, zl3vni->vni);
2247
2248 zl3vni_rmac_install(zl3vni, zrmac);
2249 return 0;
2250 }
2251
2252 /* Public functions */
2253
2254 int is_l3vni_for_prefix_routes_only(vni_t vni)
2255 {
2256 struct zebra_l3vni *zl3vni = NULL;
2257
2258 zl3vni = zl3vni_lookup(vni);
2259 if (!zl3vni)
2260 return 0;
2261
2262 return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
2263 }
2264
2265 /* handle evpn route in vrf table */
2266 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
2267 const struct ipaddr *vtep_ip,
2268 const struct prefix *host_prefix)
2269 {
2270 struct zebra_l3vni *zl3vni = NULL;
2271 struct ipaddr ipv4_vtep;
2272
2273 zl3vni = zl3vni_from_vrf(vrf_id);
2274 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
2275 return;
2276
2277 /*
2278 * add the next hop neighbor -
2279 * neigh to be installed is the ipv6 nexthop neigh
2280 */
2281 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
2282
2283 /*
2284 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
2285 * address. Rmac is programmed against the ipv4 vtep because we only
2286 * support ipv4 tunnels in the h/w right now
2287 */
2288 memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
2289 ipv4_vtep.ipa_type = IPADDR_V4;
2290 if (vtep_ip->ipa_type == IPADDR_V6)
2291 ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
2292 &(ipv4_vtep.ipaddr_v4));
2293 else
2294 memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
2295 sizeof(struct in_addr));
2296
2297 /*
2298 * add the rmac - remote rmac to be installed is against the ipv4
2299 * nexthop address
2300 */
2301 zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep);
2302 }
2303
2304 /* handle evpn vrf route delete */
2305 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
2306 struct ipaddr *vtep_ip,
2307 struct prefix *host_prefix)
2308 {
2309 struct zebra_l3vni *zl3vni = NULL;
2310 struct zebra_neigh *nh = NULL;
2311 struct zebra_mac *zrmac = NULL;
2312
2313 zl3vni = zl3vni_from_vrf(vrf_id);
2314 if (!zl3vni)
2315 return;
2316
2317 /* find the next hop entry and rmac entry */
2318 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
2319 if (!nh)
2320 return;
2321 zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
2322
2323 /* delete the next hop entry */
2324 zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
2325
2326 /* delete the rmac entry */
2327 if (zrmac)
2328 zl3vni_remote_rmac_del(zl3vni, zrmac, vtep_ip);
2329 }
2330
2331 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
2332 struct ethaddr *rmac, bool use_json)
2333 {
2334 struct zebra_l3vni *zl3vni = NULL;
2335 struct zebra_mac *zrmac = NULL;
2336 json_object *json = NULL;
2337
2338 if (!is_evpn_enabled()) {
2339 if (use_json)
2340 vty_out(vty, "{}\n");
2341 return;
2342 }
2343
2344 if (use_json)
2345 json = json_object_new_object();
2346
2347 zl3vni = zl3vni_lookup(l3vni);
2348 if (!zl3vni) {
2349 if (use_json)
2350 vty_out(vty, "{}\n");
2351 else
2352 vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
2353 return;
2354 }
2355
2356 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
2357 if (!zrmac) {
2358 if (use_json)
2359 vty_out(vty, "{}\n");
2360 else
2361 vty_out(vty,
2362 "%% Requested RMAC doesn't exist in L3-VNI %u\n",
2363 l3vni);
2364 return;
2365 }
2366
2367 zl3vni_print_rmac(zrmac, vty, json);
2368
2369 if (use_json)
2370 vty_json(vty, json);
2371 }
2372
2373 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2374 {
2375 struct zebra_l3vni *zl3vni;
2376 uint32_t num_rmacs;
2377 struct rmac_walk_ctx wctx;
2378 json_object *json = NULL;
2379
2380 if (!is_evpn_enabled())
2381 return;
2382
2383 zl3vni = zl3vni_lookup(l3vni);
2384 if (!zl3vni) {
2385 if (use_json)
2386 vty_out(vty, "{}\n");
2387 else
2388 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2389 return;
2390 }
2391 num_rmacs = hashcount(zl3vni->rmac_table);
2392 if (!num_rmacs)
2393 return;
2394
2395 if (use_json)
2396 json = json_object_new_object();
2397
2398 memset(&wctx, 0, sizeof(wctx));
2399 wctx.vty = vty;
2400 wctx.json = json;
2401 if (!use_json) {
2402 vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
2403 num_rmacs);
2404 vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
2405 } else
2406 json_object_int_add(json, "numRmacs", num_rmacs);
2407
2408 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
2409
2410 if (use_json)
2411 vty_json(vty, json);
2412 }
2413
2414 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
2415 {
2416 json_object *json = NULL;
2417 void *args[2];
2418
2419 if (!is_evpn_enabled()) {
2420 if (use_json)
2421 vty_out(vty, "{}\n");
2422 return;
2423 }
2424
2425 if (use_json)
2426 json = json_object_new_object();
2427
2428 args[0] = vty;
2429 args[1] = json;
2430 hash_iterate(zrouter.l3vni_table,
2431 (void (*)(struct hash_bucket *,
2432 void *))zl3vni_print_rmac_hash_all_vni,
2433 args);
2434
2435 if (use_json)
2436 vty_json(vty, json);
2437 }
2438
2439 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
2440 struct ipaddr *ip, bool use_json)
2441 {
2442 struct zebra_l3vni *zl3vni = NULL;
2443 struct zebra_neigh *n = NULL;
2444 json_object *json = NULL;
2445
2446 if (!is_evpn_enabled()) {
2447 if (use_json)
2448 vty_out(vty, "{}\n");
2449 return;
2450 }
2451
2452 if (use_json)
2453 json = json_object_new_object();
2454
2455 zl3vni = zl3vni_lookup(l3vni);
2456 if (!zl3vni) {
2457 if (use_json)
2458 vty_out(vty, "{}\n");
2459 else
2460 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2461 return;
2462 }
2463
2464 n = zl3vni_nh_lookup(zl3vni, ip);
2465 if (!n) {
2466 if (use_json)
2467 vty_out(vty, "{}\n");
2468 else
2469 vty_out(vty,
2470 "%% Requested next-hop not present for L3-VNI %u",
2471 l3vni);
2472 return;
2473 }
2474
2475 zl3vni_print_nh(n, vty, json);
2476
2477 if (use_json)
2478 vty_json(vty, json);
2479 }
2480
2481 void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
2482 {
2483 uint32_t num_nh;
2484 struct nh_walk_ctx wctx;
2485 json_object *json = NULL;
2486 struct zebra_l3vni *zl3vni = NULL;
2487
2488 if (!is_evpn_enabled())
2489 return;
2490
2491 zl3vni = zl3vni_lookup(l3vni);
2492 if (!zl3vni) {
2493 if (use_json)
2494 vty_out(vty, "{}\n");
2495 else
2496 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
2497 return;
2498 }
2499
2500 num_nh = hashcount(zl3vni->nh_table);
2501 if (!num_nh)
2502 return;
2503
2504 if (use_json)
2505 json = json_object_new_object();
2506
2507 wctx.vty = vty;
2508 wctx.json = json;
2509 if (!use_json) {
2510 vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
2511 num_nh);
2512 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
2513 } else
2514 json_object_int_add(json, "numNextHops", num_nh);
2515
2516 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
2517
2518 if (use_json)
2519 vty_json(vty, json);
2520 }
2521
2522 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
2523 {
2524 json_object *json = NULL;
2525 void *args[2];
2526
2527 if (!is_evpn_enabled()) {
2528 if (use_json)
2529 vty_out(vty, "{}\n");
2530 return;
2531 }
2532
2533 if (use_json)
2534 json = json_object_new_object();
2535
2536 args[0] = vty;
2537 args[1] = json;
2538 hash_iterate(zrouter.l3vni_table,
2539 (void (*)(struct hash_bucket *,
2540 void *))zl3vni_print_nh_hash_all_vni,
2541 args);
2542
2543 if (use_json)
2544 vty_json(vty, json);
2545 }
2546
2547 /*
2548 * Display L3 VNI information (VTY command handler).
2549 */
2550 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
2551 {
2552 void *args[2];
2553 json_object *json = NULL;
2554 struct zebra_l3vni *zl3vni = NULL;
2555
2556 if (!is_evpn_enabled()) {
2557 if (use_json)
2558 vty_out(vty, "{}\n");
2559 return;
2560 }
2561
2562 zl3vni = zl3vni_lookup(vni);
2563 if (!zl3vni) {
2564 if (use_json)
2565 vty_out(vty, "{}\n");
2566 else
2567 vty_out(vty, "%% VNI %u does not exist\n", vni);
2568 return;
2569 }
2570
2571 if (use_json)
2572 json = json_object_new_object();
2573
2574 args[0] = vty;
2575 args[1] = json;
2576 zl3vni_print(zl3vni, (void *)args);
2577
2578 if (use_json)
2579 vty_json(vty, json);
2580 }
2581
2582 void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
2583 json_object *json_vrfs)
2584 {
2585 char buf[ETHER_ADDR_STRLEN];
2586 struct zebra_l3vni *zl3vni = NULL;
2587
2588 zl3vni = zl3vni_lookup(zvrf->l3vni);
2589 if (!zl3vni)
2590 return;
2591
2592 if (!json_vrfs) {
2593 vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
2594 zvrf_name(zvrf), zl3vni->vni,
2595 zl3vni_vxlan_if_name(zl3vni),
2596 zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
2597 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2598 } else {
2599 json_object *json_vrf = NULL;
2600
2601 json_vrf = json_object_new_object();
2602 json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
2603 json_object_int_add(json_vrf, "vni", zl3vni->vni);
2604 json_object_string_add(json_vrf, "vxlanIntf",
2605 zl3vni_vxlan_if_name(zl3vni));
2606 json_object_string_add(json_vrf, "sviIntf",
2607 zl3vni_svi_if_name(zl3vni));
2608 json_object_string_add(json_vrf, "state",
2609 zl3vni_state2str(zl3vni));
2610 json_object_string_add(
2611 json_vrf, "routerMac",
2612 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2613 json_object_array_add(json_vrfs, json_vrf);
2614 }
2615 }
2616
2617 /*
2618 * Display Neighbors for a VNI (VTY command handler).
2619 */
2620 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
2621 vni_t vni, bool use_json)
2622 {
2623 struct zebra_evpn *zevpn;
2624 uint32_t num_neigh;
2625 struct neigh_walk_ctx wctx;
2626 json_object *json = NULL;
2627
2628 if (!is_evpn_enabled())
2629 return;
2630 zevpn = zebra_evpn_lookup(vni);
2631 if (!zevpn) {
2632 if (use_json)
2633 vty_out(vty, "{}\n");
2634 else
2635 vty_out(vty, "%% VNI %u does not exist\n", vni);
2636 return;
2637 }
2638 num_neigh = hashcount(zevpn->neigh_table);
2639 if (!num_neigh)
2640 return;
2641
2642 if (use_json)
2643 json = json_object_new_object();
2644
2645 /* Since we have IPv6 addresses to deal with which can vary widely in
2646 * size, we try to be a bit more elegant in display by first computing
2647 * the maximum width.
2648 */
2649 memset(&wctx, 0, sizeof(wctx));
2650 wctx.zevpn = zevpn;
2651 wctx.vty = vty;
2652 wctx.addr_width = 15;
2653 wctx.json = json;
2654 hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2655 &wctx);
2656
2657 if (!use_json) {
2658 vty_out(vty,
2659 "Number of ARPs (local and remote) known for this VNI: %u\n",
2660 num_neigh);
2661 zebra_evpn_print_neigh_hdr(vty, &wctx);
2662 } else
2663 json_object_int_add(json, "numArpNd", num_neigh);
2664
2665 hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
2666 if (use_json)
2667 vty_json(vty, json);
2668 }
2669
2670 /*
2671 * Display neighbors across all VNIs (VTY command handler).
2672 */
2673 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2674 bool print_dup, bool use_json)
2675 {
2676 json_object *json = NULL;
2677 void *args[3];
2678
2679 if (!is_evpn_enabled())
2680 return;
2681
2682 if (use_json)
2683 json = json_object_new_object();
2684
2685 args[0] = vty;
2686 args[1] = json;
2687 args[2] = (void *)(ptrdiff_t)print_dup;
2688
2689 hash_iterate(zvrf->evpn_table,
2690 (void (*)(struct hash_bucket *,
2691 void *))zevpn_print_neigh_hash_all_evpn,
2692 args);
2693 if (use_json)
2694 vty_json(vty, json);
2695 }
2696
2697 /*
2698 * Display neighbors across all VNIs in detail(VTY command handler).
2699 */
2700 void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
2701 struct zebra_vrf *zvrf,
2702 bool print_dup, bool use_json)
2703 {
2704 json_object *json = NULL;
2705 void *args[3];
2706
2707 if (!is_evpn_enabled())
2708 return;
2709
2710 if (use_json)
2711 json = json_object_new_object();
2712
2713 args[0] = vty;
2714 args[1] = json;
2715 args[2] = (void *)(ptrdiff_t)print_dup;
2716
2717 hash_iterate(zvrf->evpn_table,
2718 (void (*)(struct hash_bucket *,
2719 void *))zevpn_print_neigh_hash_all_evpn_detail,
2720 args);
2721 if (use_json)
2722 vty_json(vty, json);
2723 }
2724
2725 /*
2726 * Display specific neighbor for a VNI, if present (VTY command handler).
2727 */
2728 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
2729 struct zebra_vrf *zvrf, vni_t vni,
2730 struct ipaddr *ip, bool use_json)
2731 {
2732 struct zebra_evpn *zevpn;
2733 struct zebra_neigh *n;
2734 json_object *json = NULL;
2735
2736 if (!is_evpn_enabled())
2737 return;
2738 zevpn = zebra_evpn_lookup(vni);
2739 if (!zevpn) {
2740 if (use_json)
2741 vty_out(vty, "{}\n");
2742 else
2743 vty_out(vty, "%% VNI %u does not exist\n", vni);
2744 return;
2745 }
2746 n = zebra_evpn_neigh_lookup(zevpn, ip);
2747 if (!n) {
2748 if (!use_json)
2749 vty_out(vty,
2750 "%% Requested neighbor does not exist in VNI %u\n",
2751 vni);
2752 return;
2753 }
2754 if (use_json)
2755 json = json_object_new_object();
2756
2757 zebra_evpn_print_neigh(n, vty, json);
2758
2759 if (use_json)
2760 vty_json(vty, json);
2761 }
2762
2763 /*
2764 * Display neighbors for a VNI from specific VTEP (VTY command handler).
2765 * By definition, these are remote neighbors.
2766 */
2767 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2768 vni_t vni, struct in_addr vtep_ip,
2769 bool use_json)
2770 {
2771 struct zebra_evpn *zevpn;
2772 uint32_t num_neigh;
2773 struct neigh_walk_ctx wctx;
2774 json_object *json = NULL;
2775
2776 if (!is_evpn_enabled())
2777 return;
2778 zevpn = zebra_evpn_lookup(vni);
2779 if (!zevpn) {
2780 if (use_json)
2781 vty_out(vty, "{}\n");
2782 else
2783 vty_out(vty, "%% VNI %u does not exist\n", vni);
2784 return;
2785 }
2786 num_neigh = hashcount(zevpn->neigh_table);
2787 if (!num_neigh)
2788 return;
2789
2790 if (use_json)
2791 json = json_object_new_object();
2792
2793 memset(&wctx, 0, sizeof(wctx));
2794 wctx.zevpn = zevpn;
2795 wctx.vty = vty;
2796 wctx.addr_width = 15;
2797 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
2798 wctx.r_vtep_ip = vtep_ip;
2799 wctx.json = json;
2800 hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2801 &wctx);
2802 hash_iterate(zevpn->neigh_table, zebra_evpn_print_neigh_hash, &wctx);
2803
2804 if (use_json)
2805 vty_json(vty, json);
2806 }
2807
2808 /*
2809 * Display Duplicate detected Neighbors for a VNI
2810 * (VTY command handler).
2811 */
2812 void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
2813 struct zebra_vrf *zvrf,
2814 vni_t vni,
2815 bool use_json)
2816 {
2817 struct zebra_evpn *zevpn;
2818 uint32_t num_neigh;
2819 struct neigh_walk_ctx wctx;
2820 json_object *json = NULL;
2821
2822 if (!is_evpn_enabled())
2823 return;
2824
2825 zevpn = zebra_evpn_lookup(vni);
2826 if (!zevpn) {
2827 vty_out(vty, "%% VNI %u does not exist\n", vni);
2828 return;
2829 }
2830
2831 num_neigh = hashcount(zevpn->neigh_table);
2832 if (!num_neigh)
2833 return;
2834
2835 num_neigh = num_dup_detected_neighs(zevpn);
2836 if (!num_neigh)
2837 return;
2838
2839 if (use_json)
2840 json = json_object_new_object();
2841
2842 /* Since we have IPv6 addresses to deal with which can vary widely in
2843 * size, we try to be a bit more elegant in display by first computing
2844 * the maximum width.
2845 */
2846 memset(&wctx, 0, sizeof(wctx));
2847 wctx.zevpn = zevpn;
2848 wctx.vty = vty;
2849 wctx.addr_width = 15;
2850 wctx.json = json;
2851 hash_iterate(zevpn->neigh_table, zebra_evpn_find_neigh_addr_width,
2852 &wctx);
2853
2854 if (!use_json) {
2855 vty_out(vty,
2856 "Number of ARPs (local and remote) known for this VNI: %u\n",
2857 num_neigh);
2858 vty_out(vty, "%*s %-6s %-8s %-17s %-30s\n",
2859 -wctx.addr_width, "IP", "Type",
2860 "State", "MAC", "Remote ES/VTEP");
2861 } else
2862 json_object_int_add(json, "numArpNd", num_neigh);
2863
2864 hash_iterate(zevpn->neigh_table, zebra_evpn_print_dad_neigh_hash,
2865 &wctx);
2866
2867 if (use_json)
2868 vty_json(vty, json);
2869 }
2870
2871 /*
2872 * Display MACs for a VNI (VTY command handler).
2873 */
2874 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
2875 vni_t vni, bool use_json, bool detail)
2876 {
2877 struct zebra_evpn *zevpn;
2878 uint32_t num_macs;
2879 struct mac_walk_ctx wctx;
2880 json_object *json = NULL;
2881 json_object *json_mac = NULL;
2882
2883 if (!is_evpn_enabled())
2884 return;
2885 zevpn = zebra_evpn_lookup(vni);
2886 if (!zevpn) {
2887 if (use_json)
2888 vty_out(vty, "{}\n");
2889 else
2890 vty_out(vty, "%% VNI %u does not exist\n", vni);
2891 return;
2892 }
2893 num_macs = num_valid_macs(zevpn);
2894 if (!num_macs)
2895 return;
2896
2897 if (use_json) {
2898 json = json_object_new_object();
2899 json_mac = json_object_new_object();
2900 }
2901
2902 memset(&wctx, 0, sizeof(wctx));
2903 wctx.zevpn = zevpn;
2904 wctx.vty = vty;
2905 wctx.json = json_mac;
2906
2907 if (!use_json) {
2908 if (detail) {
2909 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
2910 zevpn->vni, num_macs);
2911 } else {
2912 vty_out(vty,
2913 "Number of MACs (local and remote) known for this VNI: %u\n",
2914 num_macs);
2915 vty_out(vty,
2916 "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
2917 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
2918 "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN",
2919 "Seq #'s");
2920 }
2921 } else
2922 json_object_int_add(json, "numMacs", num_macs);
2923
2924 if (detail)
2925 hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash_detail,
2926 &wctx);
2927 else
2928 hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash,
2929 &wctx);
2930
2931 if (use_json) {
2932 json_object_object_add(json, "macs", json_mac);
2933 vty_json(vty, json);
2934 }
2935 }
2936
2937 /*
2938 * Display MACs for all VNIs (VTY command handler).
2939 */
2940 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2941 bool print_dup, bool use_json)
2942 {
2943 struct mac_walk_ctx wctx;
2944 json_object *json = NULL;
2945
2946 if (!is_evpn_enabled()) {
2947 if (use_json)
2948 vty_out(vty, "{}\n");
2949 return;
2950 }
2951 if (use_json)
2952 json = json_object_new_object();
2953
2954 memset(&wctx, 0, sizeof(wctx));
2955 wctx.vty = vty;
2956 wctx.json = json;
2957 wctx.print_dup = print_dup;
2958 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
2959
2960 if (use_json)
2961 vty_json(vty, json);
2962 }
2963
2964 /*
2965 * Display MACs in detail for all VNIs (VTY command handler).
2966 */
2967 void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
2968 struct zebra_vrf *zvrf,
2969 bool print_dup, bool use_json)
2970 {
2971 struct mac_walk_ctx wctx;
2972 json_object *json = NULL;
2973
2974 if (!is_evpn_enabled()) {
2975 if (use_json)
2976 vty_out(vty, "{}\n");
2977 return;
2978 }
2979 if (use_json)
2980 json = json_object_new_object();
2981
2982 memset(&wctx, 0, sizeof(wctx));
2983 wctx.vty = vty;
2984 wctx.json = json;
2985 wctx.print_dup = print_dup;
2986 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn_detail,
2987 &wctx);
2988
2989 if (use_json)
2990 vty_json(vty, json);
2991 }
2992
2993 /*
2994 * Display MACs for all VNIs (VTY command handler).
2995 */
2996 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
2997 struct zebra_vrf *zvrf,
2998 struct in_addr vtep_ip, bool use_json)
2999 {
3000 struct mac_walk_ctx wctx;
3001 json_object *json = NULL;
3002
3003 if (!is_evpn_enabled())
3004 return;
3005
3006 if (use_json)
3007 json = json_object_new_object();
3008
3009 memset(&wctx, 0, sizeof(wctx));
3010 wctx.vty = vty;
3011 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3012 wctx.r_vtep_ip = vtep_ip;
3013 wctx.json = json;
3014 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
3015
3016 if (use_json)
3017 vty_json(vty, json);
3018 }
3019
3020 /*
3021 * Display specific MAC for a VNI, if present (VTY command handler).
3022 */
3023 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
3024 vni_t vni, struct ethaddr *macaddr,
3025 bool use_json)
3026 {
3027 struct zebra_evpn *zevpn;
3028 struct zebra_mac *mac;
3029 json_object *json = NULL;
3030
3031 if (!is_evpn_enabled())
3032 return;
3033
3034 zevpn = zebra_evpn_lookup(vni);
3035 if (!zevpn) {
3036 if (use_json)
3037 vty_out(vty, "{}\n");
3038 else
3039 vty_out(vty, "%% VNI %u does not exist\n", vni);
3040 return;
3041 }
3042 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3043 if (!mac) {
3044 if (use_json)
3045 vty_out(vty, "{}\n");
3046 else
3047 vty_out(vty,
3048 "%% Requested MAC does not exist in VNI %u\n",
3049 vni);
3050 return;
3051 }
3052
3053 if (use_json)
3054 json = json_object_new_object();
3055
3056 zebra_evpn_print_mac(mac, vty, json);
3057 if (use_json)
3058 vty_json(vty, json);
3059 }
3060
3061 /* Print Duplicate MACs per VNI */
3062 void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
3063 struct zebra_vrf *zvrf,
3064 vni_t vni, bool use_json)
3065 {
3066 struct zebra_evpn *zevpn;
3067 struct mac_walk_ctx wctx;
3068 uint32_t num_macs;
3069 json_object *json = NULL;
3070 json_object *json_mac = NULL;
3071
3072 if (!is_evpn_enabled())
3073 return;
3074
3075 zevpn = zebra_evpn_lookup(vni);
3076 if (!zevpn) {
3077 vty_out(vty, "%% VNI %u does not exist\n", vni);
3078 return;
3079 }
3080
3081 num_macs = num_valid_macs(zevpn);
3082 if (!num_macs)
3083 return;
3084
3085 num_macs = num_dup_detected_macs(zevpn);
3086 if (!num_macs)
3087 return;
3088
3089 if (use_json) {
3090 json = json_object_new_object();
3091 json_mac = json_object_new_object();
3092 }
3093
3094 memset(&wctx, 0, sizeof(wctx));
3095 wctx.zevpn = zevpn;
3096 wctx.vty = vty;
3097 wctx.json = json_mac;
3098
3099 if (!use_json) {
3100 vty_out(vty,
3101 "Number of MACs (local and remote) known for this VNI: %u\n",
3102 num_macs);
3103 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s\n", "MAC", "Type",
3104 "Flags", "Intf/Remote ES/VTEP", "VLAN");
3105 } else
3106 json_object_int_add(json, "numMacs", num_macs);
3107
3108 hash_iterate(zevpn->mac_table, zebra_evpn_print_dad_mac_hash, &wctx);
3109
3110 if (use_json) {
3111 json_object_object_add(json, "macs", json_mac);
3112 vty_json(vty, json);
3113 }
3114
3115 }
3116
3117 int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
3118 struct ethaddr *macaddr, char *errmsg,
3119 size_t errmsg_len)
3120 {
3121 struct zebra_evpn *zevpn;
3122 struct zebra_mac *mac;
3123 struct listnode *node = NULL;
3124 struct zebra_neigh *nbr = NULL;
3125
3126 if (!is_evpn_enabled())
3127 return 0;
3128
3129 zevpn = zebra_evpn_lookup(vni);
3130 if (!zevpn) {
3131 snprintfrr(errmsg, errmsg_len, "VNI %u does not exist", vni);
3132 return -1;
3133 }
3134
3135 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
3136 if (!mac) {
3137 snprintf(errmsg, errmsg_len,
3138 "Requested MAC does not exist in VNI %u\n", vni);
3139 return -1;
3140 }
3141
3142 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3143 snprintfrr(errmsg, errmsg_len,
3144 "Requested MAC is not duplicate detected\n");
3145 return -1;
3146 }
3147
3148 /* Remove all IPs as duplicate associcated with this MAC */
3149 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3150 /* For local neigh mark inactive so MACIP update is generated
3151 * to BGP. This is a scenario where MAC update received
3152 * and detected as duplicate which marked neigh as duplicate.
3153 * Later local neigh update did not get a chance to relay
3154 * to BGP. Similarly remote macip update, neigh needs to be
3155 * installed locally.
3156 */
3157 if (zvrf->dad_freeze &&
3158 CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3159 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
3160 ZEBRA_NEIGH_SET_INACTIVE(nbr);
3161 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
3162 zebra_evpn_rem_neigh_install(
3163 zevpn, nbr, false /*was_static*/);
3164 }
3165
3166 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3167 nbr->dad_count = 0;
3168 nbr->detect_start_time.tv_sec = 0;
3169 nbr->dad_dup_detect_time = 0;
3170 }
3171
3172 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3173 mac->dad_count = 0;
3174 mac->detect_start_time.tv_sec = 0;
3175 mac->detect_start_time.tv_usec = 0;
3176 mac->dad_dup_detect_time = 0;
3177 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3178
3179 /* warn-only action return */
3180 if (!zvrf->dad_freeze)
3181 return 0;
3182
3183 /* Local: Notify Peer VTEPs, Remote: Install the entry */
3184 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3185 /* Inform to BGP */
3186 if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3187 mac->flags, mac->loc_seq,
3188 mac->es))
3189 return 0;
3190
3191 /* Process all neighbors associated with this MAC. */
3192 zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3193 0 /*es_change*/);
3194
3195 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3196 zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3197
3198 /* Install the entry. */
3199 zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3200 }
3201
3202 return 0;
3203 }
3204
3205 int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
3206 struct ipaddr *ip, char *errmsg,
3207 size_t errmsg_len)
3208 {
3209 struct zebra_evpn *zevpn;
3210 struct zebra_neigh *nbr;
3211 struct zebra_mac *mac;
3212 char buf[INET6_ADDRSTRLEN];
3213 char buf2[ETHER_ADDR_STRLEN];
3214
3215 if (!is_evpn_enabled())
3216 return 0;
3217
3218 zevpn = zebra_evpn_lookup(vni);
3219 if (!zevpn) {
3220 snprintfrr(errmsg, errmsg_len, "VNI %u does not exist\n", vni);
3221 return -1;
3222 }
3223
3224 nbr = zebra_evpn_neigh_lookup(zevpn, ip);
3225 if (!nbr) {
3226 snprintfrr(errmsg, errmsg_len,
3227 "Requested host IP does not exist in VNI %u\n", vni);
3228 return -1;
3229 }
3230
3231 ipaddr2str(&nbr->ip, buf, sizeof(buf));
3232
3233 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
3234 snprintfrr(errmsg, errmsg_len,
3235 "Requested host IP %s is not duplicate detected\n",
3236 buf);
3237 return -1;
3238 }
3239
3240 mac = zebra_evpn_mac_lookup(zevpn, &nbr->emac);
3241
3242 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
3243 snprintfrr(
3244 errmsg, errmsg_len,
3245 "Requested IP's associated MAC %s is still in duplicate state\n",
3246 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
3247 return -1;
3248 }
3249
3250 if (IS_ZEBRA_DEBUG_VXLAN)
3251 zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
3252 __func__, buf, nbr->flags, nbr->loc_seq);
3253
3254 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3255 nbr->dad_count = 0;
3256 nbr->detect_start_time.tv_sec = 0;
3257 nbr->detect_start_time.tv_usec = 0;
3258 nbr->dad_dup_detect_time = 0;
3259 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
3260
3261 if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
3262 zebra_evpn_neigh_send_add_to_client(zevpn->vni, ip, &nbr->emac,
3263 nbr->mac, nbr->flags,
3264 nbr->loc_seq);
3265 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
3266 zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
3267 }
3268
3269 return 0;
3270 }
3271
3272 static void zevpn_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt)
3273 {
3274 struct mac_walk_ctx *wctx = ctxt;
3275 struct zebra_mac *mac;
3276 struct zebra_evpn *zevpn;
3277 struct listnode *node = NULL;
3278 struct zebra_neigh *nbr = NULL;
3279
3280 mac = (struct zebra_mac *)bucket->data;
3281 if (!mac)
3282 return;
3283
3284 zevpn = wctx->zevpn;
3285
3286 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
3287 return;
3288
3289 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
3290 mac->dad_count = 0;
3291 mac->detect_start_time.tv_sec = 0;
3292 mac->detect_start_time.tv_usec = 0;
3293 mac->dad_dup_detect_time = 0;
3294 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3295
3296 /* Remove all IPs as duplicate associcated with this MAC */
3297 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
3298 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
3299 && nbr->dad_count)
3300 ZEBRA_NEIGH_SET_INACTIVE(nbr);
3301
3302 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
3303 nbr->dad_count = 0;
3304 nbr->detect_start_time.tv_sec = 0;
3305 nbr->dad_dup_detect_time = 0;
3306 }
3307
3308 /* Local: Notify Peer VTEPs, Remote: Install the entry */
3309 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3310 /* Inform to BGP */
3311 if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
3312 mac->flags, mac->loc_seq,
3313 mac->es))
3314 return;
3315
3316 /* Process all neighbors associated with this MAC. */
3317 zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
3318 0 /*es_change*/);
3319
3320 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3321 zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
3322
3323 /* Install the entry. */
3324 zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
3325 }
3326 }
3327
3328 static void zevpn_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket,
3329 void **args)
3330 {
3331 struct zebra_evpn *zevpn;
3332 struct zebra_vrf *zvrf;
3333 struct mac_walk_ctx m_wctx;
3334 struct neigh_walk_ctx n_wctx;
3335
3336 zevpn = (struct zebra_evpn *)bucket->data;
3337 if (!zevpn)
3338 return;
3339
3340 zvrf = (struct zebra_vrf *)args[0];
3341
3342 if (hashcount(zevpn->neigh_table)) {
3343 memset(&n_wctx, 0, sizeof(n_wctx));
3344 n_wctx.zevpn = zevpn;
3345 n_wctx.zvrf = zvrf;
3346 hash_iterate(zevpn->neigh_table,
3347 zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3348 }
3349
3350 if (num_valid_macs(zevpn)) {
3351 memset(&m_wctx, 0, sizeof(m_wctx));
3352 m_wctx.zevpn = zevpn;
3353 m_wctx.zvrf = zvrf;
3354 hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3355 }
3356
3357 }
3358
3359 int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf)
3360 {
3361 void *args[1];
3362
3363 if (!is_evpn_enabled())
3364 return 0;
3365
3366 args[0] = zvrf;
3367
3368 hash_iterate(zvrf->evpn_table,
3369 (void (*)(struct hash_bucket *, void *))
3370 zevpn_clear_dup_detect_hash_vni_all, args);
3371
3372 return 0;
3373 }
3374
3375 int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni)
3376 {
3377 struct zebra_evpn *zevpn;
3378 struct mac_walk_ctx m_wctx;
3379 struct neigh_walk_ctx n_wctx;
3380
3381 if (!is_evpn_enabled())
3382 return 0;
3383
3384 zevpn = zebra_evpn_lookup(vni);
3385 if (!zevpn) {
3386 zlog_warn("VNI %u does not exist", vni);
3387 return CMD_WARNING;
3388 }
3389
3390 if (hashcount(zevpn->neigh_table)) {
3391 memset(&n_wctx, 0, sizeof(n_wctx));
3392 n_wctx.zevpn = zevpn;
3393 n_wctx.zvrf = zvrf;
3394 hash_iterate(zevpn->neigh_table,
3395 zebra_evpn_clear_dup_neigh_hash, &n_wctx);
3396 }
3397
3398 if (num_valid_macs(zevpn)) {
3399 memset(&m_wctx, 0, sizeof(m_wctx));
3400 m_wctx.zevpn = zevpn;
3401 m_wctx.zvrf = zvrf;
3402 hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
3403 }
3404
3405 return 0;
3406 }
3407
3408 /*
3409 * Display MACs for a VNI from specific VTEP (VTY command handler).
3410 */
3411 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
3412 vni_t vni, struct in_addr vtep_ip,
3413 bool use_json)
3414 {
3415 struct zebra_evpn *zevpn;
3416 uint32_t num_macs;
3417 struct mac_walk_ctx wctx;
3418 json_object *json = NULL;
3419 json_object *json_mac = NULL;
3420
3421 if (!is_evpn_enabled())
3422 return;
3423 zevpn = zebra_evpn_lookup(vni);
3424 if (!zevpn) {
3425 if (use_json)
3426 vty_out(vty, "{}\n");
3427 else
3428 vty_out(vty, "%% VNI %u does not exist\n", vni);
3429 return;
3430 }
3431 num_macs = num_valid_macs(zevpn);
3432 if (!num_macs)
3433 return;
3434
3435 if (use_json) {
3436 json = json_object_new_object();
3437 json_mac = json_object_new_object();
3438 }
3439
3440 memset(&wctx, 0, sizeof(wctx));
3441 wctx.zevpn = zevpn;
3442 wctx.vty = vty;
3443 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
3444 wctx.r_vtep_ip = vtep_ip;
3445 wctx.json = json_mac;
3446 hash_iterate(zevpn->mac_table, zebra_evpn_print_mac_hash, &wctx);
3447
3448 if (use_json) {
3449 json_object_int_add(json, "numMacs", wctx.count);
3450 if (wctx.count)
3451 json_object_object_add(json, "macs", json_mac);
3452 vty_json(vty, json);
3453 }
3454 }
3455
3456
3457 /*
3458 * Display VNI information (VTY command handler).
3459 *
3460 * use_json flag indicates that output should be in JSON format.
3461 * json_array is non NULL when JSON output needs to be aggregated (by the
3462 * caller) and then printed, otherwise, JSON evpn vni info is printed
3463 * right away.
3464 */
3465 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
3466 bool use_json, json_object *json_array)
3467 {
3468 json_object *json = NULL;
3469 void *args[2];
3470 struct zebra_l3vni *zl3vni = NULL;
3471 struct zebra_evpn *zevpn = NULL;
3472
3473 if (!is_evpn_enabled())
3474 return;
3475
3476 if (use_json)
3477 json = json_object_new_object();
3478
3479 args[0] = vty;
3480 args[1] = json;
3481
3482 zl3vni = zl3vni_lookup(vni);
3483 if (zl3vni) {
3484 zl3vni_print(zl3vni, (void *)args);
3485 } else {
3486 zevpn = zebra_evpn_lookup(vni);
3487 if (zevpn)
3488 zebra_evpn_print(zevpn, (void *)args);
3489 else if (!json)
3490 vty_out(vty, "%% VNI %u does not exist\n", vni);
3491 }
3492
3493 if (use_json) {
3494 /*
3495 * Each "json" object contains info about 1 VNI.
3496 * When "json_array" is non-null, we aggreggate the json output
3497 * into json_array and print it as a JSON array.
3498 */
3499 if (json_array)
3500 json_object_array_add(json_array, json);
3501 else
3502 vty_json(vty, json);
3503 }
3504 }
3505
3506 /* Display all global details for EVPN */
3507 void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
3508 {
3509 int num_l2vnis = 0;
3510 int num_l3vnis = 0;
3511 int num_vnis = 0;
3512 json_object *json = NULL;
3513 struct zebra_vrf *zvrf = NULL;
3514
3515 if (!is_evpn_enabled())
3516 return;
3517
3518 zvrf = zebra_vrf_get_evpn();
3519
3520 num_l3vnis = hashcount(zrouter.l3vni_table);
3521 num_l2vnis = hashcount(zvrf->evpn_table);
3522 num_vnis = num_l2vnis + num_l3vnis;
3523
3524 if (uj) {
3525 json = json_object_new_object();
3526 json_object_string_add(json, "advertiseGatewayMacip",
3527 zvrf->advertise_gw_macip ? "Yes" : "No");
3528 json_object_string_add(json, "advertiseSviMacip",
3529 zvrf->advertise_svi_macip ? "Yes"
3530 : "No");
3531 json_object_string_add(json, "advertiseSviMac",
3532 zebra_evpn_mh_do_adv_svi_mac() ? "Yes"
3533 : "No");
3534 json_object_int_add(json, "numVnis", num_vnis);
3535 json_object_int_add(json, "numL2Vnis", num_l2vnis);
3536 json_object_int_add(json, "numL3Vnis", num_l3vnis);
3537 if (zebra_evpn_do_dup_addr_detect(zvrf))
3538 json_object_boolean_true_add(json,
3539 "isDuplicateAddrDetection");
3540 else
3541 json_object_boolean_false_add(json,
3542 "isDuplicateAddrDetection");
3543 json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
3544 json_object_int_add(json, "detectionTime", zvrf->dad_time);
3545 json_object_int_add(json, "detectionFreezeTime",
3546 zvrf->dad_freeze_time);
3547 zebra_evpn_mh_json(json);
3548 } else {
3549 vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
3550 vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
3551 vty_out(vty, "Advertise gateway mac-ip: %s\n",
3552 zvrf->advertise_gw_macip ? "Yes" : "No");
3553 vty_out(vty, "Advertise svi mac-ip: %s\n",
3554 zvrf->advertise_svi_macip ? "Yes" : "No");
3555 vty_out(vty, "Advertise svi mac: %s\n",
3556 zebra_evpn_mh_do_adv_svi_mac() ? "Yes" : "No");
3557 vty_out(vty, "Duplicate address detection: %s\n",
3558 zebra_evpn_do_dup_addr_detect(zvrf) ? "Enable"
3559 : "Disable");
3560 vty_out(vty, " Detection max-moves %u, time %d\n",
3561 zvrf->dad_max_moves, zvrf->dad_time);
3562 if (zvrf->dad_freeze) {
3563 if (zvrf->dad_freeze_time)
3564 vty_out(vty, " Detection freeze %u\n",
3565 zvrf->dad_freeze_time);
3566 else
3567 vty_out(vty, " Detection freeze %s\n",
3568 "permanent");
3569 }
3570 zebra_evpn_mh_print(vty);
3571 }
3572
3573 if (uj)
3574 vty_json(vty, json);
3575 }
3576
3577 /*
3578 * Display VNI hash table (VTY command handler).
3579 */
3580 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
3581 bool use_json)
3582 {
3583 json_object *json = NULL;
3584 void *args[2];
3585
3586 if (!is_evpn_enabled())
3587 return;
3588
3589 if (use_json)
3590 json = json_object_new_object();
3591 else
3592 vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
3593 "Type", "VxLAN IF", "# MACs", "# ARPs",
3594 "# Remote VTEPs", "Tenant VRF");
3595
3596 args[0] = vty;
3597 args[1] = json;
3598
3599 /* Display all L2-VNIs */
3600 hash_iterate(
3601 zvrf->evpn_table,
3602 (void (*)(struct hash_bucket *, void *))zebra_evpn_print_hash,
3603 args);
3604
3605 /* Display all L3-VNIs */
3606 hash_iterate(zrouter.l3vni_table,
3607 (void (*)(struct hash_bucket *, void *))zl3vni_print_hash,
3608 args);
3609
3610 if (use_json)
3611 vty_json(vty, json);
3612 }
3613
3614 void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
3615 {
3616 struct stream *s;
3617 int time = 0;
3618 uint32_t max_moves = 0;
3619 uint32_t freeze_time = 0;
3620 bool dup_addr_detect = false;
3621 bool freeze = false;
3622 bool old_addr_detect;
3623
3624 s = msg;
3625 STREAM_GETL(s, dup_addr_detect);
3626 STREAM_GETL(s, time);
3627 STREAM_GETL(s, max_moves);
3628 STREAM_GETL(s, freeze);
3629 STREAM_GETL(s, freeze_time);
3630
3631 old_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3632 zvrf->dup_addr_detect = dup_addr_detect;
3633 dup_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
3634
3635 /* DAD previous state was enabled, and new state is disable,
3636 * clear all duplicate detected addresses.
3637 */
3638 if (old_addr_detect && !dup_addr_detect)
3639 zebra_vxlan_clear_dup_detect_vni_all(zvrf);
3640
3641 zvrf->dad_time = time;
3642 zvrf->dad_max_moves = max_moves;
3643 zvrf->dad_freeze = freeze;
3644 zvrf->dad_freeze_time = freeze_time;
3645
3646 if (IS_ZEBRA_DEBUG_VXLAN)
3647 zlog_debug(
3648 "VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
3649 vrf_id_to_name(zvrf->vrf->vrf_id),
3650 dup_addr_detect ? "enable" : "disable",
3651 zvrf->dad_max_moves, zvrf->dad_time,
3652 zvrf->dad_freeze ? "enable" : "disable",
3653 zvrf->dad_freeze_time);
3654
3655 stream_failure:
3656 return;
3657 }
3658
3659 /*
3660 * Display VNI hash table in detail(VTY command handler).
3661 */
3662 void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
3663 bool use_json)
3664 {
3665 json_object *json_array = NULL;
3666 struct zebra_ns *zns = NULL;
3667 struct zebra_evpn_show zes;
3668
3669 if (!is_evpn_enabled())
3670 return;
3671
3672 zns = zebra_ns_lookup(NS_DEFAULT);
3673 if (!zns)
3674 return;
3675
3676 if (use_json)
3677 json_array = json_object_new_array();
3678
3679 zes.vty = vty;
3680 zes.json = json_array;
3681 zes.zvrf = zvrf;
3682 zes.use_json = use_json;
3683
3684 /* Display all L2-VNIs */
3685 hash_iterate(zvrf->evpn_table,
3686 (void (*)(struct hash_bucket *,
3687 void *))zebra_evpn_print_hash_detail,
3688 &zes);
3689
3690 /* Display all L3-VNIs */
3691 hash_iterate(zrouter.l3vni_table,
3692 (void (*)(struct hash_bucket *,
3693 void *))zl3vni_print_hash_detail,
3694 &zes);
3695
3696 if (use_json)
3697 vty_json(vty, json_array);
3698 }
3699
3700 /*
3701 * Handle neighbor delete notification from the kernel (on a VLAN device
3702 * / L3 interface). This may result in either the neighbor getting deleted
3703 * from our database or being re-added to the kernel (if it is a valid
3704 * remote neighbor).
3705 */
3706 int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
3707 struct interface *link_if,
3708 struct ipaddr *ip)
3709 {
3710 struct zebra_evpn *zevpn = NULL;
3711 struct zebra_l3vni *zl3vni = NULL;
3712
3713 /* check if this is a remote neigh entry corresponding to remote
3714 * next-hop
3715 */
3716 zl3vni = zl3vni_from_svi(ifp, link_if);
3717 if (zl3vni)
3718 return zl3vni_local_nh_del(zl3vni, ip);
3719
3720 /* We are only interested in neighbors on an SVI that resides on top
3721 * of a VxLAN bridge.
3722 */
3723 zevpn = zebra_evpn_from_svi(ifp, link_if);
3724 if (!zevpn) {
3725 if (IS_ZEBRA_DEBUG_VXLAN)
3726 zlog_debug(
3727 "%s: Del neighbor %pIA EVPN is not present for interface %s",
3728 __func__, ip, ifp->name);
3729 return 0;
3730 }
3731
3732 if (!zevpn->vxlan_if) {
3733 zlog_debug(
3734 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
3735 zevpn->vni, zevpn);
3736 return -1;
3737 }
3738
3739 if (IS_ZEBRA_DEBUG_VXLAN)
3740 zlog_debug("Del neighbor %pIA intf %s(%u) -> L2-VNI %u",
3741 ip, ifp->name, ifp->ifindex, zevpn->vni);
3742
3743 return zebra_evpn_neigh_del_ip(zevpn, ip);
3744 }
3745
3746 /*
3747 * Handle neighbor add or update notification from the kernel (on a VLAN
3748 * device / L3 interface). This is typically for a local neighbor but can
3749 * also be for a remote neighbor (e.g., ageout notification). It could
3750 * also be a "move" scenario.
3751 */
3752 int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
3753 struct interface *link_if,
3754 struct ipaddr *ip,
3755 struct ethaddr *macaddr,
3756 uint16_t state,
3757 bool is_ext,
3758 bool is_router,
3759 bool local_inactive, bool dp_static)
3760 {
3761 struct zebra_evpn *zevpn = NULL;
3762 struct zebra_l3vni *zl3vni = NULL;
3763
3764 /* check if this is a remote neigh entry corresponding to remote
3765 * next-hop
3766 */
3767 zl3vni = zl3vni_from_svi(ifp, link_if);
3768 if (zl3vni)
3769 return zl3vni_local_nh_add_update(zl3vni, ip, state);
3770
3771 /* We are only interested in neighbors on an SVI that resides on top
3772 * of a VxLAN bridge.
3773 */
3774 zevpn = zebra_evpn_from_svi(ifp, link_if);
3775 if (!zevpn)
3776 return 0;
3777
3778 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
3779 zlog_debug(
3780 "Add/Update neighbor %pIA MAC %pEA intf %s(%u) state 0x%x %s%s%s%s-> L2-VNI %u",
3781 ip, macaddr, ifp->name,
3782 ifp->ifindex, state, is_ext ? "ext-learned " : "",
3783 is_router ? "router " : "",
3784 local_inactive ? "local_inactive " : "",
3785 dp_static ? "peer_sync " : "", zevpn->vni);
3786
3787 /* Is this about a local neighbor or a remote one? */
3788 if (!is_ext)
3789 return zebra_evpn_local_neigh_update(zevpn, ifp, ip, macaddr,
3790 is_router, local_inactive,
3791 dp_static);
3792
3793 return zebra_evpn_remote_neigh_update(zevpn, ifp, ip, macaddr, state);
3794 }
3795
3796 static int32_t
3797 zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
3798 struct ethaddr *macaddr, uint16_t *ipa_len,
3799 struct ipaddr *ip, struct in_addr *vtep_ip,
3800 uint8_t *flags, uint32_t *seq, esi_t *esi)
3801 {
3802 uint16_t l = 0;
3803
3804 /*
3805 * Obtain each remote MACIP and process.
3806 * Message contains VNI, followed by MAC followed by IP (if any)
3807 * followed by remote VTEP IP.
3808 */
3809 memset(ip, 0, sizeof(*ip));
3810 STREAM_GETL(s, *vni);
3811 STREAM_GET(macaddr->octet, s, ETH_ALEN);
3812 STREAM_GETW(s, *ipa_len);
3813
3814 if (*ipa_len) {
3815 if (*ipa_len == IPV4_MAX_BYTELEN)
3816 ip->ipa_type = IPADDR_V4;
3817 else if (*ipa_len == IPV6_MAX_BYTELEN)
3818 ip->ipa_type = IPADDR_V6;
3819 else {
3820 if (IS_ZEBRA_DEBUG_VXLAN)
3821 zlog_debug(
3822 "ipa_len *must* be %d or %d bytes in length not %d",
3823 IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
3824 *ipa_len);
3825 goto stream_failure;
3826 }
3827
3828 STREAM_GET(&ip->ip.addr, s, *ipa_len);
3829 }
3830 l += 4 + ETH_ALEN + 4 + *ipa_len;
3831 STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
3832 l += IPV4_MAX_BYTELEN;
3833
3834 if (add) {
3835 STREAM_GETC(s, *flags);
3836 STREAM_GETL(s, *seq);
3837 l += 5;
3838 STREAM_GET(esi, s, sizeof(esi_t));
3839 l += sizeof(esi_t);
3840 }
3841
3842 return l;
3843
3844 stream_failure:
3845 return -1;
3846 }
3847
3848 /*
3849 * Handle message from client to delete a remote MACIP for a VNI.
3850 */
3851 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
3852 {
3853 struct stream *s;
3854 vni_t vni;
3855 struct ethaddr macaddr;
3856 struct ipaddr ip;
3857 struct in_addr vtep_ip;
3858 uint16_t l = 0, ipa_len;
3859 char buf1[INET6_ADDRSTRLEN];
3860
3861 s = msg;
3862
3863 while (l < hdr->length) {
3864 int res_length = zebra_vxlan_remote_macip_helper(
3865 false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
3866 NULL, NULL);
3867
3868 if (res_length == -1)
3869 goto stream_failure;
3870
3871 l += res_length;
3872 if (IS_ZEBRA_DEBUG_VXLAN)
3873 zlog_debug(
3874 "Recv MACIP DEL VNI %u MAC %pEA%s%s Remote VTEP %pI4 from %s",
3875 vni, &macaddr,
3876 ipa_len ? " IP " : "",
3877 ipa_len ?
3878 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
3879 &vtep_ip, zebra_route_string(client->proto));
3880
3881 /* Enqueue to workqueue for processing */
3882 zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
3883 }
3884
3885 stream_failure:
3886 return;
3887 }
3888
3889 /*
3890 * Handle message from client to add a remote MACIP for a VNI. This
3891 * could be just the add of a MAC address or the add of a neighbor
3892 * (IP+MAC).
3893 */
3894 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
3895 {
3896 struct stream *s;
3897 vni_t vni;
3898 struct ethaddr macaddr;
3899 struct ipaddr ip;
3900 struct in_addr vtep_ip;
3901 uint16_t l = 0, ipa_len;
3902 uint8_t flags = 0;
3903 uint32_t seq;
3904 char buf1[INET6_ADDRSTRLEN];
3905 esi_t esi;
3906 char esi_buf[ESI_STR_LEN];
3907
3908 if (!EVPN_ENABLED(zvrf)) {
3909 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
3910 return;
3911 }
3912
3913 s = msg;
3914
3915 while (l < hdr->length) {
3916
3917 int res_length = zebra_vxlan_remote_macip_helper(
3918 true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
3919 &flags, &seq, &esi);
3920
3921 if (res_length == -1)
3922 goto stream_failure;
3923
3924 l += res_length;
3925 if (IS_ZEBRA_DEBUG_VXLAN) {
3926 if (memcmp(&esi, zero_esi, sizeof(esi_t)))
3927 esi_to_str(&esi, esi_buf, sizeof(esi_buf));
3928 else
3929 strlcpy(esi_buf, "-", ESI_STR_LEN);
3930 zlog_debug(
3931 "Recv %sMACIP ADD VNI %u MAC %pEA%s%s flags 0x%x seq %u VTEP %pI4 ESI %s from %s",
3932 (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ?
3933 "sync-" : "",
3934 vni, &macaddr,
3935 ipa_len ? " IP " : "",
3936 ipa_len ?
3937 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
3938 flags, seq, &vtep_ip, esi_buf,
3939 zebra_route_string(client->proto));
3940 }
3941
3942 /* Enqueue to workqueue for processing */
3943 zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags,
3944 seq, vtep_ip, &esi);
3945 }
3946
3947 stream_failure:
3948 return;
3949 }
3950
3951 /*
3952 * Handle remote vtep delete by kernel; re-add the vtep if we have it
3953 */
3954 int zebra_vxlan_check_readd_vtep(struct interface *ifp, vni_t vni,
3955 struct in_addr vtep_ip)
3956 {
3957 struct zebra_if *zif;
3958 struct zebra_vrf *zvrf = NULL;
3959 struct zebra_evpn *zevpn = NULL;
3960 struct zebra_vtep *zvtep = NULL;
3961 struct zebra_vxlan_vni *vnip;
3962
3963 zif = ifp->info;
3964 assert(zif);
3965
3966 /* If EVPN is not enabled, nothing to do. */
3967 if (!is_evpn_enabled())
3968 return 0;
3969
3970 /* Locate VRF corresponding to interface. */
3971 zvrf = ifp->vrf->info;
3972 if (!zvrf)
3973 return -1;
3974
3975 vnip = zebra_vxlan_if_vni_find(zif, vni);
3976 if (!vnip)
3977 return 0;
3978
3979 /* Locate hash entry; it is expected to exist. */
3980 zevpn = zebra_evpn_lookup(vni);
3981 if (!zevpn)
3982 return 0;
3983
3984 /* If the remote vtep entry doesn't exists nothing to do */
3985 zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
3986 if (!zvtep)
3987 return 0;
3988
3989 if (IS_ZEBRA_DEBUG_VXLAN)
3990 zlog_debug(
3991 "Del MAC for remote VTEP %pI4 intf %s(%u) VNI %u - readd",
3992 &vtep_ip, ifp->name, ifp->ifindex, vni);
3993
3994 zebra_evpn_vtep_install(zevpn, zvtep);
3995 return 0;
3996 }
3997
3998 /*
3999 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
4000 * us, this must involve a multihoming scenario. Treat this as implicit delete
4001 * of any prior local MAC.
4002 */
4003 static int zebra_vxlan_check_del_local_mac(struct interface *ifp,
4004 struct interface *br_if,
4005 struct ethaddr *macaddr,
4006 vlanid_t vid, vni_t vni)
4007 {
4008 struct zebra_if *zif;
4009 struct zebra_evpn *zevpn;
4010 struct zebra_mac *mac;
4011
4012 zif = ifp->info;
4013 assert(zif);
4014
4015 /* Check if EVPN is enabled. */
4016 if (!is_evpn_enabled())
4017 return 0;
4018
4019 /* Locate hash entry; it is expected to exist. */
4020 zevpn = zebra_evpn_lookup(vni);
4021 if (!zevpn)
4022 return 0;
4023
4024 /* If entry doesn't exist, nothing to do. */
4025 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4026 if (!mac)
4027 return 0;
4028
4029 /* Is it a local entry? */
4030 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4031 return 0;
4032
4033 if (IS_ZEBRA_DEBUG_VXLAN)
4034 zlog_debug(
4035 "Add/update remote MAC %pEA intf %s(%u) VNI %u flags 0x%x - del local",
4036 macaddr, ifp->name, ifp->ifindex, vni, mac->flags);
4037
4038 /* Remove MAC from BGP. */
4039 zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, mac->flags,
4040 false /* force */);
4041
4042 /*
4043 * If there are no neigh associated with the mac delete the mac
4044 * else mark it as AUTO for forward reference
4045 */
4046 if (!listcount(mac->neigh_list)) {
4047 zebra_evpn_mac_del(zevpn, mac);
4048 } else {
4049 zebra_evpn_mac_clear_fwd_info(mac);
4050 UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
4051 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
4052 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
4053 }
4054
4055 return 0;
4056 }
4057
4058 /* MAC notification from the dataplane with a network dest port -
4059 * 1. This can be a local MAC on a down ES (if fast-failover is not possible
4060 * 2. Or it can be a remote MAC
4061 */
4062 int zebra_vxlan_dp_network_mac_add(struct interface *ifp,
4063 struct interface *br_if,
4064 struct ethaddr *macaddr, vlanid_t vid,
4065 vni_t vni, uint32_t nhg_id, bool sticky,
4066 bool dp_static)
4067 {
4068 struct zebra_evpn_es *es;
4069 struct interface *acc_ifp;
4070
4071 /* If netlink message is with vid, it will have no nexthop.
4072 * So skip it.
4073 */
4074 if (vid) {
4075 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4076 zlog_debug("dpAdd MAC %pEA VID %u - ignore as no nhid",
4077 macaddr, vid);
4078 return 0;
4079 }
4080
4081 /* Get vxlan's vid for netlink message has no it. */
4082 vid = ((struct zebra_if *)ifp->info)->l2info.vxl.access_vlan;
4083
4084 /* if remote mac delete the local entry */
4085 if (!nhg_id || !zebra_evpn_nhg_is_local_es(nhg_id, &es)
4086 || !zebra_evpn_es_local_mac_via_network_port(es)) {
4087 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4088 zlog_debug("dpAdd remote MAC %pEA VID %u", macaddr,
4089 vid);
4090 return zebra_vxlan_check_del_local_mac(ifp, br_if, macaddr, vid,
4091 vni);
4092 }
4093
4094 /* If local MAC on a down local ES translate the network-mac-add
4095 * to a local-active-mac-add
4096 */
4097 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4098 zlog_debug("dpAdd local-nw-MAC %pEA VID %u", macaddr, vid);
4099 acc_ifp = es->zif->ifp;
4100 return zebra_vxlan_local_mac_add_update(
4101 acc_ifp, br_if, macaddr, vid, sticky,
4102 false /* local_inactive */, dp_static);
4103 }
4104
4105 /*
4106 * Handle network MAC delete by kernel -
4107 * 1. readd the remote MAC if we have it
4108 * 2. local MAC with does ES may also need to be re-installed
4109 */
4110 int zebra_vxlan_dp_network_mac_del(struct interface *ifp,
4111 struct interface *br_if,
4112 struct ethaddr *macaddr, vlanid_t vid,
4113 vni_t vni)
4114 {
4115 struct zebra_if *zif = NULL;
4116 struct zebra_evpn *zevpn = NULL;
4117 struct zebra_l3vni *zl3vni = NULL;
4118 struct zebra_mac *mac = NULL;
4119
4120 zif = ifp->info;
4121 assert(zif);
4122
4123 /* Check if EVPN is enabled. */
4124 if (!is_evpn_enabled())
4125 return 0;
4126
4127 /* check if this is a remote RMAC and readd simillar to remote macs */
4128 zl3vni = zl3vni_lookup(vni);
4129 if (zl3vni)
4130 return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
4131
4132 /* Locate hash entry; it is expected to exist. */
4133 zevpn = zebra_evpn_lookup(vni);
4134 if (!zevpn)
4135 return 0;
4136
4137 /* If entry doesn't exist, nothing to do. */
4138 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4139 if (!mac)
4140 return 0;
4141
4142 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
4143 /* If remote entry simply re-install */
4144 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4145 zlog_debug(
4146 "dpDel remote MAC %pEA intf %s(%u) VNI %u - readd",
4147 macaddr, ifp->name, ifp->ifindex, vni);
4148 zebra_evpn_rem_mac_install(zevpn, mac, false /* was_static */);
4149 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) && mac->es
4150 && zebra_evpn_es_local_mac_via_network_port(mac->es)) {
4151 /* If local entry via nw-port call local-del which will
4152 * re-install entry in the dataplane is needed
4153 */
4154 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
4155 zlog_debug("dpDel local-nw-MAC %pEA VNI %u", macaddr,
4156 vni);
4157
4158 zebra_evpn_del_local_mac(zevpn, mac, false);
4159 }
4160
4161 return 0;
4162 }
4163
4164 /*
4165 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
4166 */
4167 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
4168 struct ethaddr *macaddr, vlanid_t vid)
4169 {
4170 struct zebra_evpn *zevpn;
4171 struct zebra_mac *mac;
4172
4173 /* We are interested in MACs only on ports or (port, VLAN) that
4174 * map to a VNI.
4175 */
4176 zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4177 if (!zevpn)
4178 return 0;
4179 if (!zevpn->vxlan_if) {
4180 zlog_debug(
4181 "VNI %u hash %p doesn't have intf upon local MAC DEL",
4182 zevpn->vni, zevpn);
4183 return -1;
4184 }
4185
4186 /* If entry doesn't exist, nothing to do. */
4187 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
4188 if (!mac)
4189 return 0;
4190
4191 /* Is it a local entry? */
4192 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
4193 return 0;
4194
4195 return zebra_evpn_del_local_mac(zevpn, mac, false);
4196 }
4197
4198 /*
4199 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
4200 */
4201 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
4202 struct interface *br_if,
4203 struct ethaddr *macaddr, vlanid_t vid,
4204 bool sticky, bool local_inactive,
4205 bool dp_static)
4206 {
4207 struct zebra_evpn *zevpn;
4208 struct zebra_vrf *zvrf;
4209
4210 assert(ifp);
4211
4212 /* We are interested in MACs only on ports or (port, VLAN) that
4213 * map to an EVPN.
4214 */
4215 zevpn = zebra_evpn_map_vlan(ifp, br_if, vid);
4216 if (!zevpn) {
4217 if (IS_ZEBRA_DEBUG_VXLAN)
4218 zlog_debug(
4219 " Add/Update %sMAC %pEA intf %s(%u) VID %u, could not find EVPN",
4220 sticky ? "sticky " : "", macaddr,
4221 ifp->name, ifp->ifindex, vid);
4222 return 0;
4223 }
4224
4225 if (!zevpn->vxlan_if) {
4226 if (IS_ZEBRA_DEBUG_VXLAN)
4227 zlog_debug(
4228 " VNI %u hash %p doesn't have intf upon local MAC ADD",
4229 zevpn->vni, zevpn);
4230 return -1;
4231 }
4232
4233 zvrf = zebra_vrf_get_evpn();
4234 return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid,
4235 sticky, local_inactive,
4236 dp_static, NULL);
4237 }
4238
4239 /*
4240 * Handle message from client to delete a remote VTEP for an EVPN.
4241 */
4242 void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS)
4243 {
4244 struct stream *s;
4245 unsigned short l = 0;
4246 vni_t vni;
4247 struct in_addr vtep_ip;
4248
4249 if (!is_evpn_enabled()) {
4250 zlog_debug(
4251 "%s: EVPN is not enabled yet we have received a VTEP DEL msg",
4252 __func__);
4253 return;
4254 }
4255
4256 if (!EVPN_ENABLED(zvrf)) {
4257 zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u",
4258 zvrf_id(zvrf));
4259 return;
4260 }
4261
4262 s = msg;
4263
4264 while (l < hdr->length) {
4265 int flood_control __attribute__((unused));
4266
4267 /* Obtain each remote VTEP and process. */
4268 STREAM_GETL(s, vni);
4269 l += 4;
4270 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4271 l += IPV4_MAX_BYTELEN;
4272
4273 /* Flood control is intentionally ignored right now */
4274 STREAM_GETL(s, flood_control);
4275 l += 4;
4276
4277 if (IS_ZEBRA_DEBUG_VXLAN)
4278 zlog_debug("Recv VTEP DEL %pI4 VNI %u from %s",
4279 &vtep_ip, vni,
4280 zebra_route_string(client->proto));
4281
4282 /* Enqueue for processing */
4283 zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip);
4284 }
4285
4286 stream_failure:
4287 return;
4288 }
4289
4290 /*
4291 * Handle message from client to delete a remote VTEP for an EVPN.
4292 */
4293 void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni,
4294 struct in_addr vtep_ip)
4295 {
4296 struct zebra_evpn *zevpn;
4297 struct zebra_vtep *zvtep;
4298 struct interface *ifp;
4299 struct zebra_if *zif;
4300 struct zebra_vrf *zvrf;
4301
4302 if (!is_evpn_enabled()) {
4303 zlog_debug("%s: Can't process vtep del: EVPN is not enabled",
4304 __func__);
4305 return;
4306 }
4307
4308 zvrf = zebra_vrf_lookup_by_id(vrf_id);
4309 if (!zvrf)
4310 return;
4311
4312 if (!EVPN_ENABLED(zvrf)) {
4313 zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u",
4314 zvrf_id(zvrf));
4315 return;
4316 }
4317
4318 /* Locate VNI hash entry - expected to exist. */
4319 zevpn = zebra_evpn_lookup(vni);
4320 if (!zevpn) {
4321 if (IS_ZEBRA_DEBUG_VXLAN)
4322 zlog_debug(
4323 "Failed to locate VNI hash for remote VTEP DEL, VNI %u",
4324 vni);
4325 return;
4326 }
4327
4328 ifp = zevpn->vxlan_if;
4329 if (!ifp) {
4330 zlog_debug(
4331 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
4332 zevpn->vni, zevpn);
4333 return;
4334 }
4335 zif = ifp->info;
4336
4337 /* If down or not mapped to a bridge, we're done. */
4338 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4339 return;
4340
4341 /* If the remote VTEP does not exist, there's nothing more to
4342 * do.
4343 * Otherwise, uninstall any remote MACs pointing to this VTEP
4344 * and then, the VTEP entry itself and remove it.
4345 */
4346 zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4347 if (!zvtep)
4348 return;
4349
4350 zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4351 zebra_evpn_vtep_del(zevpn, zvtep);
4352 }
4353
4354 /*
4355 * Handle message from client to add a remote VTEP for an EVPN.
4356 */
4357 void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
4358 struct in_addr vtep_ip, int flood_control)
4359 {
4360 struct zebra_evpn *zevpn;
4361 struct interface *ifp;
4362 struct zebra_if *zif;
4363 struct zebra_vtep *zvtep;
4364 struct zebra_vrf *zvrf;
4365
4366 if (!is_evpn_enabled()) {
4367 zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD",
4368 __func__);
4369 return;
4370 }
4371
4372 zvrf = zebra_vrf_lookup_by_id(vrf_id);
4373 if (!zvrf)
4374 return;
4375
4376 if (!EVPN_ENABLED(zvrf)) {
4377 zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u",
4378 zvrf_id(zvrf));
4379 return;
4380 }
4381
4382 /* Locate VNI hash entry - expected to exist. */
4383 zevpn = zebra_evpn_lookup(vni);
4384 if (!zevpn) {
4385 flog_err(
4386 EC_ZEBRA_VTEP_ADD_FAILED,
4387 "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
4388 vni);
4389 return;
4390 }
4391
4392 ifp = zevpn->vxlan_if;
4393 if (!ifp) {
4394 flog_err(
4395 EC_ZEBRA_VTEP_ADD_FAILED,
4396 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
4397 zevpn->vni, zevpn);
4398 return;
4399 }
4400
4401 zif = ifp->info;
4402
4403 /* If down or not mapped to a bridge, we're done. */
4404 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4405 return;
4406
4407 zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
4408 if (zvtep) {
4409 /* If the remote VTEP already exists check if
4410 * the flood mode has changed
4411 */
4412 if (zvtep->flood_control != flood_control) {
4413 if (zvtep->flood_control == VXLAN_FLOOD_DISABLED)
4414 /* old mode was head-end-replication but
4415 * is no longer; get rid of the HER fdb
4416 * entry installed before
4417 */
4418 zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
4419 zvtep->flood_control = flood_control;
4420 zebra_evpn_vtep_install(zevpn, zvtep);
4421 }
4422 } else {
4423 zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, flood_control);
4424 if (zvtep)
4425 zebra_evpn_vtep_install(zevpn, zvtep);
4426 else
4427 flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
4428 "Failed to add remote VTEP, VNI %u zevpn %p",
4429 vni, zevpn);
4430 }
4431 }
4432
4433 /*
4434 * Handle message from client to add a remote VTEP for an EVPN.
4435 */
4436 void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS)
4437 {
4438 struct stream *s;
4439 unsigned short l = 0;
4440 vni_t vni;
4441 struct in_addr vtep_ip;
4442 int flood_control;
4443
4444 if (!is_evpn_enabled()) {
4445 zlog_debug(
4446 "%s: EVPN not enabled yet we received a VTEP ADD zapi msg",
4447 __func__);
4448 return;
4449 }
4450
4451 if (!EVPN_ENABLED(zvrf)) {
4452 zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u",
4453 zvrf_id(zvrf));
4454 return;
4455 }
4456
4457 s = msg;
4458
4459 while (l < hdr->length) {
4460 /* Obtain each remote VTEP and process. */
4461 STREAM_GETL(s, vni);
4462 l += 4;
4463 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4464 STREAM_GETL(s, flood_control);
4465 l += IPV4_MAX_BYTELEN + 4;
4466
4467 if (IS_ZEBRA_DEBUG_VXLAN)
4468 zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s",
4469 &vtep_ip, vni, flood_control,
4470 zebra_route_string(client->proto));
4471
4472 /* Enqueue for processing */
4473 zebra_rib_queue_evpn_rem_vtep_add(zvrf_id(zvrf), vni, vtep_ip,
4474 flood_control);
4475 }
4476
4477 stream_failure:
4478 return;
4479 }
4480
4481 /*
4482 * Add/Del gateway macip to evpn
4483 * g/w can be:
4484 * 1. SVI interface on a vlan aware bridge
4485 * 2. SVI interface on a vlan unaware bridge
4486 * 3. vrr interface (MACVLAN) associated to a SVI
4487 * We advertise macip routes for an interface if it is associated to VxLan vlan
4488 */
4489 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p,
4490 int add)
4491 {
4492 struct ipaddr ip;
4493 struct ethaddr macaddr;
4494 struct zebra_evpn *zevpn = NULL;
4495
4496 memset(&ip, 0, sizeof(ip));
4497 memset(&macaddr, 0, sizeof(macaddr));
4498
4499 /* Check if EVPN is enabled. */
4500 if (!is_evpn_enabled())
4501 return 0;
4502
4503 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4504 struct interface *svi_if =
4505 NULL; /* SVI corresponding to the MACVLAN */
4506 struct zebra_if *ifp_zif =
4507 NULL; /* Zebra daemon specific info for MACVLAN */
4508 struct zebra_if *svi_if_zif =
4509 NULL; /* Zebra daemon specific info for SVI*/
4510
4511 ifp_zif = ifp->info;
4512 if (!ifp_zif)
4513 return -1;
4514
4515 /*
4516 * for a MACVLAN interface the link represents the svi_if
4517 */
4518 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4519 ifp_zif->link_ifindex);
4520 if (!svi_if) {
4521 zlog_debug("MACVLAN %s(%u) without link information",
4522 ifp->name, ifp->ifindex);
4523 return -1;
4524 }
4525
4526 if (IS_ZEBRA_IF_VLAN(svi_if)) {
4527 /*
4528 * If it is a vlan aware bridge then the link gives the
4529 * bridge information
4530 */
4531 struct interface *svi_if_link = NULL;
4532
4533 svi_if_zif = svi_if->info;
4534 if (svi_if_zif) {
4535 svi_if_link = if_lookup_by_index_per_ns(
4536 zebra_ns_lookup(NS_DEFAULT),
4537 svi_if_zif->link_ifindex);
4538 zevpn = zebra_evpn_from_svi(svi_if,
4539 svi_if_link);
4540 }
4541 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
4542 /*
4543 * If it is a vlan unaware bridge then svi is the bridge
4544 * itself
4545 */
4546 zevpn = zebra_evpn_from_svi(svi_if, svi_if);
4547 }
4548 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
4549 struct zebra_if *svi_if_zif =
4550 NULL; /* Zebra daemon specific info for SVI */
4551 struct interface *svi_if_link =
4552 NULL; /* link info for the SVI = bridge info */
4553
4554 svi_if_zif = ifp->info;
4555 if (svi_if_zif) {
4556 svi_if_link = if_lookup_by_index_per_ns(
4557 zebra_ns_lookup(NS_DEFAULT),
4558 svi_if_zif->link_ifindex);
4559 if (svi_if_link)
4560 zevpn = zebra_evpn_from_svi(ifp, svi_if_link);
4561 }
4562 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
4563 zevpn = zebra_evpn_from_svi(ifp, ifp);
4564 }
4565
4566 if (!zevpn)
4567 return 0;
4568
4569 if (!zevpn->vxlan_if) {
4570 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
4571 zevpn->vni, zevpn);
4572 return -1;
4573 }
4574
4575 /* VRR IP is advertised only if gw-macip-adv-enabled */
4576 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
4577 if (!advertise_gw_macip_enabled(zevpn))
4578 return 0;
4579 } else {
4580 /* SVI IP is advertised if gw or svi macip-adv-enabled */
4581 if (!advertise_svi_macip_enabled(zevpn)
4582 && !advertise_gw_macip_enabled(zevpn))
4583 return 0;
4584 }
4585
4586 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
4587
4588 if (p->family == AF_INET) {
4589 ip.ipa_type = IPADDR_V4;
4590 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
4591 sizeof(struct in_addr));
4592 } else if (p->family == AF_INET6) {
4593 ip.ipa_type = IPADDR_V6;
4594 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
4595 sizeof(struct in6_addr));
4596 }
4597
4598
4599 if (add)
4600 zebra_evpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
4601 else
4602 zebra_evpn_gw_macip_del(ifp, zevpn, &ip);
4603
4604 return 0;
4605 }
4606
4607 /*
4608 * Handle SVI interface going down.
4609 * SVI can be associated to either L3-VNI or L2-VNI.
4610 * For L2-VNI: At this point, this is a NOP since
4611 * the kernel deletes the neighbor entries on this SVI (if any).
4612 * We only need to update the vrf corresponding to zevpn.
4613 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
4614 * from bgp
4615 */
4616 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
4617 {
4618 struct zebra_l3vni *zl3vni = NULL;
4619
4620 zl3vni = zl3vni_from_svi(ifp, link_if);
4621 if (zl3vni) {
4622
4623 /* process l3-vni down */
4624 zebra_vxlan_process_l3vni_oper_down(zl3vni);
4625
4626 /* remove association with svi-if */
4627 zl3vni->svi_if = NULL;
4628 } else {
4629 struct zebra_evpn *zevpn = NULL;
4630
4631 /* Unlink the SVI from the access VLAN */
4632 zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, false);
4633
4634 /* since we dont have svi corresponding to zevpn, we associate it
4635 * to default vrf. Note: the corresponding neigh entries on the
4636 * SVI would have already been deleted */
4637 zevpn = zebra_evpn_from_svi(ifp, link_if);
4638
4639 if (zevpn) {
4640 /* remove from l3-vni list */
4641 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4642 if (zl3vni)
4643 listnode_delete(zl3vni->l2vnis, zevpn);
4644
4645 zevpn->svi_if = NULL;
4646 zevpn->vrf_id = VRF_DEFAULT;
4647
4648 /* update the tenant vrf in BGP */
4649 if (if_is_operative(zevpn->vxlan_if))
4650 zebra_evpn_send_add_to_client(zevpn);
4651 }
4652 }
4653 return 0;
4654 }
4655
4656 /*
4657 * Handle SVI interface coming up.
4658 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
4659 * vxlan intf).
4660 * For L2-VNI: we need to install any remote neighbors entried (used for
4661 * arp-suppression)
4662 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
4663 */
4664 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
4665 {
4666 struct zebra_evpn *zevpn = NULL;
4667 struct zebra_l3vni *zl3vni = NULL;
4668
4669 zl3vni = zl3vni_from_svi(ifp, link_if);
4670 if (zl3vni) {
4671
4672 /* associate with svi */
4673 zl3vni->svi_if = ifp;
4674
4675 /* process oper-up */
4676 if (is_l3vni_oper_up(zl3vni))
4677 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4678 } else {
4679
4680 /* process SVI up for l2-vni */
4681 struct neigh_walk_ctx n_wctx;
4682
4683 zevpn = zebra_evpn_from_svi(ifp, link_if);
4684 if (!zevpn)
4685 return 0;
4686
4687 if (!zevpn->vxlan_if) {
4688 zlog_debug(
4689 "VNI %u hash %p doesn't have intf upon SVI up",
4690 zevpn->vni, zevpn);
4691 return -1;
4692 }
4693
4694 if (IS_ZEBRA_DEBUG_VXLAN)
4695 zlog_debug(
4696 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
4697 ifp->name, ifp->ifindex, zevpn->vni,
4698 ifp->vrf->name);
4699
4700 /* update the vrf information for l2-vni and inform bgp */
4701 zevpn->svi_if = ifp;
4702 zevpn->vrf_id = ifp->vrf->vrf_id;
4703
4704 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4705 if (zl3vni)
4706 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
4707
4708 if (if_is_operative(zevpn->vxlan_if))
4709 zebra_evpn_send_add_to_client(zevpn);
4710
4711 /* Install any remote neighbors for this VNI. */
4712 memset(&n_wctx, 0, sizeof(n_wctx));
4713 n_wctx.zevpn = zevpn;
4714 hash_iterate(zevpn->neigh_table, zebra_evpn_install_neigh_hash,
4715 &n_wctx);
4716
4717 /* Link the SVI from the access VLAN */
4718 zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, true);
4719
4720 /* Update MACIP routes created by advertise-svi-ip */
4721 if (advertise_svi_macip_enabled(zevpn)) {
4722 zebra_evpn_del_macip_for_intf(ifp, zevpn);
4723 zebra_evpn_add_macip_for_intf(ifp, zevpn);
4724 }
4725 }
4726
4727 return 0;
4728 }
4729
4730 /*
4731 * Handle MAC-VLAN interface going down.
4732 * L3VNI: When MAC-VLAN interface goes down,
4733 * find its associated SVI and update type2/type-5 routes
4734 * with SVI as RMAC
4735 */
4736 void zebra_vxlan_macvlan_down(struct interface *ifp)
4737 {
4738 struct zebra_l3vni *zl3vni = NULL;
4739 struct zebra_if *zif, *link_zif;
4740 struct interface *link_ifp, *link_if;
4741
4742 zif = ifp->info;
4743 assert(zif);
4744 link_ifp = zif->link;
4745 if (!link_ifp) {
4746 if (IS_ZEBRA_DEBUG_VXLAN)
4747 zlog_debug(
4748 "macvlan parent link is not found. Parent index %d ifp %s",
4749 zif->link_ifindex,
4750 ifindex2ifname(zif->link_ifindex,
4751 ifp->vrf->vrf_id));
4752 return;
4753 }
4754 link_zif = link_ifp->info;
4755 assert(link_zif);
4756
4757 link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4758 link_zif->link_ifindex);
4759
4760 zl3vni = zl3vni_from_svi(link_ifp, link_if);
4761 if (zl3vni) {
4762 zl3vni->mac_vlan_if = NULL;
4763 if (is_l3vni_oper_up(zl3vni))
4764 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4765 }
4766 }
4767
4768 /*
4769 * Handle MAC-VLAN interface going up.
4770 * L3VNI: When MAC-VLAN interface comes up,
4771 * find its associated SVI and update type-2 routes
4772 * with MAC-VLAN's MAC as RMAC and for type-5 routes
4773 * use SVI's MAC as RMAC.
4774 */
4775 void zebra_vxlan_macvlan_up(struct interface *ifp)
4776 {
4777 struct zebra_l3vni *zl3vni = NULL;
4778 struct zebra_if *zif, *link_zif;
4779 struct interface *link_ifp, *link_if;
4780
4781 zif = ifp->info;
4782 assert(zif);
4783 link_ifp = zif->link;
4784 link_zif = link_ifp->info;
4785 assert(link_zif);
4786
4787 link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
4788 link_zif->link_ifindex);
4789 zl3vni = zl3vni_from_svi(link_ifp, link_if);
4790 if (zl3vni) {
4791 /* associate with macvlan (VRR) interface */
4792 zl3vni->mac_vlan_if = ifp;
4793
4794 /* process oper-up */
4795 if (is_l3vni_oper_up(zl3vni))
4796 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4797 }
4798 }
4799
4800 /*
4801 * Handle VxLAN interface down
4802 */
4803 int zebra_vxlan_if_down(struct interface *ifp)
4804 {
4805 vni_t vni;
4806 struct zebra_if *zif = NULL;
4807 struct zebra_l3vni *zl3vni = NULL;
4808 struct zebra_evpn *zevpn;
4809 struct zebra_vxlan_vni *vnip;
4810
4811 /* Check if EVPN is enabled. */
4812 if (!is_evpn_enabled())
4813 return 0;
4814
4815 zif = ifp->info;
4816 assert(zif);
4817 vnip = zebra_vxlan_if_vni_find(zif, 0);
4818 vni = vnip->vni;
4819
4820 zl3vni = zl3vni_lookup(vni);
4821 if (zl3vni) {
4822 /* process-if-down for l3-vni */
4823 if (IS_ZEBRA_DEBUG_VXLAN)
4824 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
4825 ifp->ifindex, vni);
4826
4827 zebra_vxlan_process_l3vni_oper_down(zl3vni);
4828 } else {
4829 /* process if-down for l2-vni */
4830 if (IS_ZEBRA_DEBUG_VXLAN)
4831 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
4832 ifp->ifindex, vni);
4833
4834 /* Locate hash entry; it is expected to exist. */
4835 zevpn = zebra_evpn_lookup(vni);
4836 if (!zevpn) {
4837 zlog_debug(
4838 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
4839 ifp->name, ifp->ifindex, vni);
4840 return -1;
4841 }
4842
4843 assert(zevpn->vxlan_if == ifp);
4844
4845 /* remove from l3-vni list */
4846 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4847 if (zl3vni)
4848 listnode_delete(zl3vni->l2vnis, zevpn);
4849
4850 /* Delete this VNI from BGP. */
4851 zebra_evpn_send_del_to_client(zevpn);
4852
4853 /* Free up all neighbors and MACs, if any. */
4854 zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
4855 zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
4856
4857 /* Free up all remote VTEPs, if any. */
4858 zebra_evpn_vtep_del_all(zevpn, 1);
4859 }
4860 return 0;
4861 }
4862
4863 /*
4864 * Handle VxLAN interface up - update BGP if required.
4865 */
4866 int zebra_vxlan_if_up(struct interface *ifp)
4867 {
4868 vni_t vni;
4869 struct zebra_if *zif = NULL;
4870 struct zebra_evpn *zevpn = NULL;
4871 struct zebra_l3vni *zl3vni = NULL;
4872 struct zebra_vxlan_vni *vnip;
4873
4874 /* Check if EVPN is enabled. */
4875 if (!is_evpn_enabled())
4876 return 0;
4877
4878 zif = ifp->info;
4879 assert(zif);
4880 vnip = zebra_vxlan_if_vni_find(zif, 0);
4881 vni = vnip->vni;
4882
4883 zl3vni = zl3vni_lookup(vni);
4884 if (zl3vni) {
4885 /* we need to associate with SVI, if any, we can associate with
4886 * svi-if only after association with vxlan-intf is complete
4887 */
4888 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
4889 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
4890
4891 if (IS_ZEBRA_DEBUG_VXLAN)
4892 zlog_debug("Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s"
4893 , ifp->name, ifp->ifindex, vni,
4894 zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
4895 zl3vni->mac_vlan_if ?
4896 zl3vni->mac_vlan_if->name : "NIL");
4897
4898 if (is_l3vni_oper_up(zl3vni))
4899 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4900 } else {
4901 /* Handle L2-VNI add */
4902 struct interface *vlan_if = NULL;
4903
4904 if (IS_ZEBRA_DEBUG_VXLAN)
4905 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
4906 ifp->ifindex, vni);
4907
4908 /* Locate hash entry; it is expected to exist. */
4909 zevpn = zebra_evpn_lookup(vni);
4910 if (!zevpn) {
4911 zlog_debug(
4912 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
4913 ifp->name, ifp->ifindex, vni);
4914 return -1;
4915 }
4916
4917 assert(zevpn->vxlan_if == ifp);
4918 vlan_if = zvni_map_to_svi(vnip->access_vlan,
4919 zif->brslave_info.br_if);
4920 if (vlan_if) {
4921 zevpn->svi_if = vlan_if;
4922 zevpn->vrf_id = vlan_if->vrf->vrf_id;
4923 zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
4924 if (zl3vni)
4925 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
4926 }
4927
4928 /* If part of a bridge, inform BGP about this VNI. */
4929 /* Also, read and populate local MACs and neighbors. */
4930 if (zif->brslave_info.br_if) {
4931 zebra_evpn_send_add_to_client(zevpn);
4932 zebra_evpn_read_mac_neigh(zevpn, ifp);
4933 }
4934 }
4935
4936 return 0;
4937 }
4938
4939 /*
4940 * Handle VxLAN interface delete. Locate and remove entry in hash table
4941 * and update BGP, if required.
4942 */
4943 int zebra_vxlan_if_del(struct interface *ifp)
4944 {
4945 vni_t vni;
4946 struct zebra_if *zif = NULL;
4947 struct zebra_evpn *zevpn = NULL;
4948 struct zebra_l3vni *zl3vni = NULL;
4949 struct zebra_vxlan_vni *vnip;
4950
4951 /* Check if EVPN is enabled. */
4952 if (!is_evpn_enabled())
4953 return 0;
4954
4955 zif = ifp->info;
4956 assert(zif);
4957 vnip = zebra_vxlan_if_vni_find(zif, 0);
4958 vni = vnip->vni;
4959
4960 zl3vni = zl3vni_lookup(vni);
4961 if (zl3vni) {
4962
4963 if (IS_ZEBRA_DEBUG_VXLAN)
4964 zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
4965 ifp->ifindex);
4966
4967 /* process oper-down for l3-vni */
4968 zebra_vxlan_process_l3vni_oper_down(zl3vni);
4969
4970 /* remove the association with vxlan_if */
4971 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
4972 zl3vni->vxlan_if = NULL;
4973 } else {
4974
4975 /* process if-del for l2-vni*/
4976 if (IS_ZEBRA_DEBUG_VXLAN)
4977 zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name,
4978 ifp->ifindex);
4979
4980 /* Locate hash entry; it is expected to exist. */
4981 zevpn = zebra_evpn_lookup(vni);
4982 if (!zevpn) {
4983 zlog_debug(
4984 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
4985 ifp->name, ifp->ifindex, vni);
4986 return 0;
4987 }
4988
4989 /* remove from l3-vni list */
4990 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
4991 if (zl3vni)
4992 listnode_delete(zl3vni->l2vnis, zevpn);
4993 /* Delete VNI from BGP. */
4994 zebra_evpn_send_del_to_client(zevpn);
4995
4996 /* Free up all neighbors and MAC, if any. */
4997 zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
4998 zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
4999
5000 /* Free up all remote VTEPs, if any. */
5001 zebra_evpn_vtep_del_all(zevpn, 0);
5002
5003 /* Delete the hash entry. */
5004 if (zebra_evpn_vxlan_del(zevpn)) {
5005 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
5006 "Failed to del EVPN hash %p, IF %s(%u) VNI %u",
5007 zevpn, ifp->name, ifp->ifindex, zevpn->vni);
5008 return -1;
5009 }
5010 }
5011 return 0;
5012 }
5013
5014 /*
5015 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
5016 */
5017 int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
5018 {
5019 vni_t vni;
5020 struct zebra_if *zif = NULL;
5021 struct zebra_l2info_vxlan *vxl = NULL;
5022 struct zebra_evpn *zevpn = NULL;
5023 struct zebra_l3vni *zl3vni = NULL;
5024 struct interface *vlan_if = NULL;
5025 struct zebra_vxlan_vni *vnip;
5026
5027 /* Check if EVPN is enabled. */
5028 if (!is_evpn_enabled())
5029 return 0;
5030
5031 zif = ifp->info;
5032 assert(zif);
5033 vnip = zebra_vxlan_if_vni_find(zif, 0);
5034 vni = vnip->vni;
5035
5036 zl3vni = zl3vni_lookup(vni);
5037 if (zl3vni) {
5038
5039 if (IS_ZEBRA_DEBUG_VXLAN)
5040 zlog_debug(
5041 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
5042 vni, ifp->name, ifp->ifindex, vnip->access_vlan,
5043 &vxl->vtep_ip, zif->brslave_info.bridge_ifindex,
5044 chgflags);
5045
5046 /* Removed from bridge? Cleanup and return */
5047 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5048 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
5049 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5050 return 0;
5051 }
5052
5053 if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE)
5054 && if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) {
5055 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5056 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5057 return 0;
5058 }
5059
5060 /* access-vlan change - process oper down, associate with new
5061 * svi_if and then process oper up again
5062 */
5063 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5064 if (if_is_operative(ifp)) {
5065 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5066 zl3vni->svi_if = NULL;
5067 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5068 zl3vni->mac_vlan_if =
5069 zl3vni_map_to_mac_vlan_if(zl3vni);
5070 zl3vni->local_vtep_ip = vxl->vtep_ip;
5071 if (is_l3vni_oper_up(zl3vni))
5072 zebra_vxlan_process_l3vni_oper_up(
5073 zl3vni);
5074 }
5075 }
5076
5077 /*
5078 * local-ip change - process oper down, associate with new
5079 * local-ip and then process oper up again
5080 */
5081 if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) {
5082 if (if_is_operative(ifp)) {
5083 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5084 zl3vni->local_vtep_ip = vxl->vtep_ip;
5085 if (is_l3vni_oper_up(zl3vni))
5086 zebra_vxlan_process_l3vni_oper_up(
5087 zl3vni);
5088 }
5089 }
5090
5091 /* Update local tunnel IP. */
5092 zl3vni->local_vtep_ip = vxl->vtep_ip;
5093
5094 /* if we have a valid new master, process l3-vni oper up */
5095 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
5096 if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni))
5097 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5098 }
5099 } else {
5100
5101 /* Update VNI hash. */
5102 zevpn = zebra_evpn_lookup(vni);
5103 if (!zevpn) {
5104 zlog_debug(
5105 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
5106 ifp->name, ifp->ifindex, vni);
5107 return -1;
5108 }
5109
5110 if (IS_ZEBRA_DEBUG_VXLAN)
5111 zlog_debug(
5112 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
5113 vni, ifp->name, ifp->ifindex, vnip->access_vlan,
5114 &vxl->vtep_ip, zif->brslave_info.bridge_ifindex,
5115 chgflags);
5116
5117 /* Removed from bridge? Cleanup and return */
5118 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5119 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
5120 /* Delete from client, remove all remote VTEPs */
5121 /* Also, free up all MACs and neighbors. */
5122 zevpn->svi_if = NULL;
5123 zebra_evpn_send_del_to_client(zevpn);
5124 zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
5125 zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
5126 zebra_evpn_vtep_del_all(zevpn, 1);
5127 return 0;
5128 }
5129
5130 /* Handle other changes. */
5131 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5132 /* Remove all existing local neigh and MACs for this VNI
5133 * (including from BGP)
5134 */
5135 zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
5136 zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
5137 }
5138
5139 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr
5140 || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
5141 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
5142 zevpn->mcast_grp);
5143 zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp);
5144 zevpn->local_vtep_ip = vxl->vtep_ip;
5145 zevpn->mcast_grp = vnip->mcast_grp;
5146 /* on local vtep-ip check if ES orig-ip
5147 * needs to be updated
5148 */
5149 zebra_evpn_es_set_base_evpn(zevpn);
5150 }
5151 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
5152 vlan_if = zvni_map_to_svi(vnip->access_vlan,
5153 zif->brslave_info.br_if);
5154 if (vlan_if) {
5155 zevpn->svi_if = vlan_if;
5156 zevpn->vrf_id = vlan_if->vrf->vrf_id;
5157 zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
5158 if (zl3vni)
5159 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
5160 }
5161
5162 /* Take further actions needed.
5163 * Note that if we are here, there is a change of interest.
5164 */
5165 /* If down or not mapped to a bridge, we're done. */
5166 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5167 return 0;
5168
5169 /* Inform BGP, if there is a change of interest. */
5170 if (chgflags &
5171 (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE |
5172 ZEBRA_VXLIF_MCAST_GRP_CHANGE | ZEBRA_VXLIF_VLAN_CHANGE))
5173 zebra_evpn_send_add_to_client(zevpn);
5174
5175 /* If there is a valid new master or a VLAN mapping change,
5176 * read and populate local MACs and neighbors.
5177 * Also, reinstall any remote MACs and neighbors
5178 * for this VNI (based on new VLAN).
5179 */
5180 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
5181 zebra_evpn_read_mac_neigh(zevpn, ifp);
5182 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
5183 struct mac_walk_ctx m_wctx;
5184 struct neigh_walk_ctx n_wctx;
5185
5186 zebra_evpn_read_mac_neigh(zevpn, ifp);
5187
5188 memset(&m_wctx, 0, sizeof(m_wctx));
5189 m_wctx.zevpn = zevpn;
5190 hash_iterate(zevpn->mac_table,
5191 zebra_evpn_install_mac_hash, &m_wctx);
5192
5193 memset(&n_wctx, 0, sizeof(n_wctx));
5194 n_wctx.zevpn = zevpn;
5195 hash_iterate(zevpn->neigh_table,
5196 zebra_evpn_install_neigh_hash, &n_wctx);
5197 }
5198 }
5199
5200 return 0;
5201 }
5202
5203 /*
5204 * Handle VxLAN interface add.
5205 */
5206 int zebra_vxlan_if_add(struct interface *ifp)
5207 {
5208 vni_t vni;
5209 struct zebra_if *zif = NULL;
5210 struct zebra_l2info_vxlan *vxl = NULL;
5211 struct zebra_evpn *zevpn = NULL;
5212 struct zebra_l3vni *zl3vni = NULL;
5213 struct zebra_vxlan_vni *vnip;
5214
5215 /* Check if EVPN is enabled. */
5216 if (!is_evpn_enabled())
5217 return 0;
5218
5219 zif = ifp->info;
5220 assert(zif);
5221 vnip = zebra_vxlan_if_vni_find(zif, 0);
5222 vni = vnip->vni;
5223
5224 zl3vni = zl3vni_lookup(vni);
5225 if (zl3vni) {
5226
5227 /* process if-add for l3-vni*/
5228 if (IS_ZEBRA_DEBUG_VXLAN)
5229 zlog_debug(
5230 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
5231 vni, ifp->name, ifp->ifindex, vnip->access_vlan,
5232 &vxl->vtep_ip,
5233 zif->brslave_info.bridge_ifindex);
5234
5235 /* associate with vxlan_if */
5236 zl3vni->local_vtep_ip = vxl->vtep_ip;
5237 zl3vni->vxlan_if = ifp;
5238
5239 /* Associate with SVI, if any. We can associate with svi-if only
5240 * after association with vxlan_if is complete */
5241 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5242
5243 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
5244
5245 if (is_l3vni_oper_up(zl3vni))
5246 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5247 } else {
5248
5249 /* process if-add for l2-vni */
5250 struct interface *vlan_if = NULL;
5251
5252 /* Create or update EVPN hash. */
5253 zevpn = zebra_evpn_lookup(vni);
5254 if (!zevpn)
5255 zevpn = zebra_evpn_add(vni);
5256
5257 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr
5258 || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
5259 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
5260 zevpn->mcast_grp);
5261 zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp);
5262 zevpn->local_vtep_ip = vxl->vtep_ip;
5263 zevpn->mcast_grp = vnip->mcast_grp;
5264 /* on local vtep-ip check if ES orig-ip
5265 * needs to be updated
5266 */
5267 zebra_evpn_es_set_base_evpn(zevpn);
5268 }
5269 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
5270 vlan_if = zvni_map_to_svi(vnip->access_vlan,
5271 zif->brslave_info.br_if);
5272 if (vlan_if) {
5273 zevpn->svi_if = vlan_if;
5274 zevpn->vrf_id = vlan_if->vrf->vrf_id;
5275 zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
5276 if (zl3vni)
5277 listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
5278 }
5279
5280 if (IS_ZEBRA_DEBUG_VXLAN)
5281 zlog_debug(
5282 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
5283 vni,
5284 vlan_if ? vlan_if->vrf->name : VRF_DEFAULT_NAME,
5285 ifp->name, ifp->ifindex, vnip->access_vlan,
5286 &vxl->vtep_ip, &vnip->mcast_grp,
5287 zif->brslave_info.bridge_ifindex);
5288
5289 /* If down or not mapped to a bridge, we're done. */
5290 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5291 return 0;
5292
5293 /* Inform BGP */
5294 zebra_evpn_send_add_to_client(zevpn);
5295
5296 /* Read and populate local MACs and neighbors */
5297 zebra_evpn_read_mac_neigh(zevpn, ifp);
5298 }
5299
5300 return 0;
5301 }
5302
5303 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
5304 char *err, int err_str_sz, int filter,
5305 int add)
5306 {
5307 struct zebra_l3vni *zl3vni = NULL;
5308 struct zebra_vrf *zvrf_evpn = NULL;
5309
5310 zvrf_evpn = zebra_vrf_get_evpn();
5311
5312 if (IS_ZEBRA_DEBUG_VXLAN)
5313 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
5314 add ? "ADD" : "DEL");
5315
5316 if (add) {
5317 /* check if the vni is already present under zvrf */
5318 if (zvrf->l3vni) {
5319 snprintf(err, err_str_sz,
5320 "VNI is already configured under the vrf");
5321 return -1;
5322 }
5323
5324 /* check if this VNI is already present in the system */
5325 zl3vni = zl3vni_lookup(vni);
5326 if (zl3vni) {
5327 snprintf(err, err_str_sz,
5328 "VNI is already configured as L3-VNI");
5329 return -1;
5330 }
5331
5332 /* Remove L2VNI if present */
5333 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5334
5335 /* add the L3-VNI to the global table */
5336 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
5337
5338 /* associate the vrf with vni */
5339 zvrf->l3vni = vni;
5340
5341 /* set the filter in l3vni to denote if we are using l3vni only
5342 * for prefix routes
5343 */
5344 if (filter)
5345 SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
5346
5347 /* associate with vxlan-intf;
5348 * we need to associate with the vxlan-intf first
5349 */
5350 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
5351
5352 /* associate with corresponding SVI interface, we can associate
5353 * with svi-if only after vxlan interface association is
5354 * complete
5355 */
5356 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5357
5358 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
5359
5360 if (IS_ZEBRA_DEBUG_VXLAN)
5361 zlog_debug(
5362 "%s: l3vni %u svi_if %s mac_vlan_if %s",
5363 __func__, vni,
5364 zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
5365 zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
5366 : "NIL");
5367
5368 /* formulate l2vni list */
5369 hash_iterate(zvrf_evpn->evpn_table, zevpn_add_to_l3vni_list,
5370 zl3vni);
5371
5372 if (is_l3vni_oper_up(zl3vni))
5373 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5374
5375 } else {
5376 zl3vni = zl3vni_lookup(vni);
5377 if (!zl3vni) {
5378 snprintf(err, err_str_sz, "VNI doesn't exist");
5379 return -1;
5380 }
5381
5382 if (zvrf->l3vni != vni) {
5383 snprintf(err, err_str_sz,
5384 "VNI %d doesn't exist in VRF: %s",
5385 vni, zvrf->vrf->name);
5386 return -1;
5387 }
5388
5389 if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
5390 snprintf(err, ERR_STR_SZ,
5391 "prefix-routes-only is not set for the vni");
5392 return -1;
5393 }
5394
5395 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5396
5397 /* delete and uninstall all rmacs */
5398 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
5399 zl3vni);
5400
5401 /* delete and uninstall all next-hops */
5402 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
5403 zl3vni);
5404
5405 zvrf->l3vni = 0;
5406 zl3vni_del(zl3vni);
5407
5408 /* Add L2VNI for this VNI */
5409 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
5410 }
5411 return 0;
5412 }
5413
5414 int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
5415 {
5416 struct zebra_l3vni *zl3vni = NULL;
5417
5418 if (zvrf->l3vni)
5419 zl3vni = zl3vni_lookup(zvrf->l3vni);
5420 if (!zl3vni)
5421 return 0;
5422
5423 zl3vni->vrf_id = zvrf_id(zvrf);
5424 if (is_l3vni_oper_up(zl3vni))
5425 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5426 return 0;
5427 }
5428
5429 int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
5430 {
5431 struct zebra_l3vni *zl3vni = NULL;
5432
5433 if (zvrf->l3vni)
5434 zl3vni = zl3vni_lookup(zvrf->l3vni);
5435 if (!zl3vni)
5436 return 0;
5437
5438 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5439
5440 /* delete and uninstall all rmacs */
5441 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry, zl3vni);
5442 /* delete and uninstall all next-hops */
5443 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry, zl3vni);
5444
5445 zl3vni->vrf_id = VRF_UNKNOWN;
5446
5447 return 0;
5448 }
5449
5450 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
5451 {
5452 struct zebra_l3vni *zl3vni = NULL;
5453 vni_t vni;
5454
5455 if (zvrf->l3vni)
5456 zl3vni = zl3vni_lookup(zvrf->l3vni);
5457 if (!zl3vni)
5458 return 0;
5459
5460 vni = zl3vni->vni;
5461 zl3vni_del(zl3vni);
5462 zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
5463
5464 return 0;
5465 }
5466
5467 /*
5468 * Handle message from client to specify the flooding mechanism for
5469 * BUM packets. The default is to do head-end (ingress) replication
5470 * and the other supported option is to disable it. This applies to
5471 * all BUM traffic and disabling it applies to both the transmit and
5472 * receive direction.
5473 */
5474 void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
5475 {
5476 struct stream *s;
5477 enum vxlan_flood_control flood_ctrl;
5478
5479 if (!EVPN_ENABLED(zvrf)) {
5480 zlog_err("EVPN flood control for non-EVPN VRF %u",
5481 zvrf_id(zvrf));
5482 return;
5483 }
5484
5485 s = msg;
5486 STREAM_GETC(s, flood_ctrl);
5487
5488 if (IS_ZEBRA_DEBUG_VXLAN)
5489 zlog_debug("EVPN flood control %u, currently %u",
5490 flood_ctrl, zvrf->vxlan_flood_ctrl);
5491
5492 if (zvrf->vxlan_flood_ctrl == flood_ctrl)
5493 return;
5494
5495 zvrf->vxlan_flood_ctrl = flood_ctrl;
5496
5497 /* Install or uninstall flood entries corresponding to
5498 * remote VTEPs.
5499 */
5500 hash_iterate(zvrf->evpn_table, zebra_evpn_handle_flooding_remote_vteps,
5501 zvrf);
5502
5503 stream_failure:
5504 return;
5505 }
5506
5507 /*
5508 * Handle message from client to enable/disable advertisement of svi macip
5509 * routes
5510 */
5511 void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
5512 {
5513 struct stream *s;
5514 int advertise;
5515 vni_t vni = 0;
5516 struct zebra_evpn *zevpn = NULL;
5517 struct interface *ifp = NULL;
5518
5519 if (!EVPN_ENABLED(zvrf)) {
5520 zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
5521 zvrf_id(zvrf));
5522 return;
5523 }
5524
5525 s = msg;
5526 STREAM_GETC(s, advertise);
5527 STREAM_GETL(s, vni);
5528
5529 if (!vni) {
5530 if (IS_ZEBRA_DEBUG_VXLAN)
5531 zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
5532 advertise ? "enabled" : "disabled",
5533 advertise_svi_macip_enabled(NULL)
5534 ? "enabled"
5535 : "disabled");
5536
5537 if (zvrf->advertise_svi_macip == advertise)
5538 return;
5539
5540
5541 if (advertise) {
5542 zvrf->advertise_svi_macip = advertise;
5543 hash_iterate(zvrf->evpn_table,
5544 zebra_evpn_gw_macip_add_for_evpn_hash,
5545 NULL);
5546 } else {
5547 hash_iterate(zvrf->evpn_table,
5548 zebra_evpn_svi_macip_del_for_evpn_hash,
5549 NULL);
5550 zvrf->advertise_svi_macip = advertise;
5551 }
5552
5553 } else {
5554 struct zebra_if *zif = NULL;
5555 struct interface *vlan_if = NULL;
5556 struct zebra_vxlan_vni *zl2_info_vni;
5557 int old_advertise;
5558
5559 zevpn = zebra_evpn_lookup(vni);
5560 if (!zevpn)
5561 return;
5562
5563 if (IS_ZEBRA_DEBUG_VXLAN)
5564 zlog_debug(
5565 "EVPN SVI macip Adv %s on VNI %d, currently %s",
5566 advertise ? "enabled" : "disabled", vni,
5567 advertise_svi_macip_enabled(zevpn)
5568 ? "enabled"
5569 : "disabled");
5570
5571 old_advertise = advertise_svi_macip_enabled(zevpn);
5572
5573 /* Store flag even though SVI is not present.
5574 * Once SVI comes up triggers self MAC-IP route add.
5575 */
5576 zevpn->advertise_svi_macip = advertise;
5577 if (advertise_svi_macip_enabled(zevpn) == old_advertise)
5578 return;
5579
5580 ifp = zevpn->vxlan_if;
5581 if (!ifp)
5582 return;
5583
5584 zif = ifp->info;
5585
5586 /* If down or not mapped to a bridge, we're done. */
5587 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5588 return;
5589
5590 zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5591 if (!zl2_info_vni)
5592 return;
5593
5594 vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5595 zif->brslave_info.br_if);
5596 if (!vlan_if)
5597 return;
5598
5599 if (advertise) {
5600 /* Add primary SVI MAC-IP */
5601 zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5602 } else {
5603 /* Del primary SVI MAC-IP */
5604 zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5605 }
5606 }
5607
5608 stream_failure:
5609 return;
5610 }
5611
5612 /*
5613 * Handle message from client to enable/disable advertisement of g/w macip
5614 * routes
5615 */
5616 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
5617 {
5618 struct stream *s;
5619 int advertise;
5620 vni_t vni = 0;
5621 struct zebra_evpn *zevpn = NULL;
5622 struct interface *ifp = NULL;
5623 struct zebra_if *zif = NULL;
5624 struct interface *vlan_if = NULL;
5625 struct zebra_vxlan_vni *zl2_info_vni = NULL;
5626
5627 if (!EVPN_ENABLED(zvrf)) {
5628 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5629 zvrf_id(zvrf));
5630 return;
5631 }
5632
5633 s = msg;
5634 STREAM_GETC(s, advertise);
5635 STREAM_GET(&vni, s, 3);
5636
5637 zevpn = zebra_evpn_lookup(vni);
5638 if (!zevpn)
5639 return;
5640
5641 if (zevpn->advertise_subnet == advertise)
5642 return;
5643
5644 if (IS_ZEBRA_DEBUG_VXLAN)
5645 zlog_debug("EVPN subnet Adv %s on VNI %d, currently %s",
5646 advertise ? "enabled" : "disabled", vni,
5647 zevpn->advertise_subnet ? "enabled" : "disabled");
5648
5649
5650 zevpn->advertise_subnet = advertise;
5651
5652 ifp = zevpn->vxlan_if;
5653 if (!ifp)
5654 return;
5655
5656 zif = ifp->info;
5657
5658 /* If down or not mapped to a bridge, we're done. */
5659 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5660 return;
5661
5662 zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5663 if (!zl2_info_vni)
5664 return;
5665
5666 vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5667 zif->brslave_info.br_if);
5668 if (!vlan_if)
5669 return;
5670
5671 if (zevpn->advertise_subnet)
5672 zebra_evpn_advertise_subnet(zevpn, vlan_if, 1);
5673 else
5674 zebra_evpn_advertise_subnet(zevpn, vlan_if, 0);
5675
5676 stream_failure:
5677 return;
5678 }
5679
5680 /*
5681 * Handle message from client to enable/disable advertisement of g/w macip
5682 * routes
5683 */
5684 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
5685 {
5686 struct stream *s;
5687 int advertise;
5688 vni_t vni = 0;
5689 struct zebra_evpn *zevpn = NULL;
5690 struct interface *ifp = NULL;
5691
5692 if (!EVPN_ENABLED(zvrf)) {
5693 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
5694 zvrf_id(zvrf));
5695 return;
5696 }
5697
5698 s = msg;
5699 STREAM_GETC(s, advertise);
5700 STREAM_GETL(s, vni);
5701
5702 if (!vni) {
5703 if (IS_ZEBRA_DEBUG_VXLAN)
5704 zlog_debug("EVPN gateway macip Adv %s, currently %s",
5705 advertise ? "enabled" : "disabled",
5706 advertise_gw_macip_enabled(NULL)
5707 ? "enabled"
5708 : "disabled");
5709
5710 if (zvrf->advertise_gw_macip == advertise)
5711 return;
5712
5713 zvrf->advertise_gw_macip = advertise;
5714
5715 if (advertise_gw_macip_enabled(zevpn))
5716 hash_iterate(zvrf->evpn_table,
5717 zebra_evpn_gw_macip_add_for_evpn_hash,
5718 NULL);
5719 else
5720 hash_iterate(zvrf->evpn_table,
5721 zebra_evpn_gw_macip_del_for_evpn_hash,
5722 NULL);
5723
5724 } else {
5725 struct zebra_if *zif = NULL;
5726 struct interface *vlan_if = NULL;
5727 struct interface *vrr_if = NULL;
5728 struct zebra_vxlan_vni *zl2_info_vni = NULL;
5729 int old_advertise;
5730
5731 zevpn = zebra_evpn_lookup(vni);
5732 if (!zevpn)
5733 return;
5734
5735 if (IS_ZEBRA_DEBUG_VXLAN)
5736 zlog_debug(
5737 "EVPN gateway macip Adv %s on VNI %d, currently %s",
5738 advertise ? "enabled" : "disabled", vni,
5739 advertise_gw_macip_enabled(zevpn) ? "enabled"
5740 : "disabled");
5741
5742 old_advertise = advertise_gw_macip_enabled(zevpn);
5743
5744 zevpn->advertise_gw_macip = advertise;
5745 if (advertise_gw_macip_enabled(zevpn) == old_advertise)
5746 return;
5747
5748 ifp = zevpn->vxlan_if;
5749 if (!ifp)
5750 return;
5751
5752 zif = ifp->info;
5753
5754 /* If down or not mapped to a bridge, we're done. */
5755 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5756 return;
5757
5758 zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
5759 if (!zl2_info_vni)
5760 return;
5761
5762 vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
5763 zif->brslave_info.br_if);
5764 if (!vlan_if)
5765 return;
5766
5767 if (advertise_gw_macip_enabled(zevpn)) {
5768 /* Add primary SVI MAC-IP */
5769 zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
5770
5771 /* Add VRR MAC-IP - if any*/
5772 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5773 if (vrr_if)
5774 zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
5775 } else {
5776 /* Del primary MAC-IP */
5777 zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
5778
5779 /* Del VRR MAC-IP - if any*/
5780 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
5781 if (vrr_if)
5782 zebra_evpn_del_macip_for_intf(vrr_if, zevpn);
5783 }
5784 }
5785
5786 stream_failure:
5787 return;
5788 }
5789
5790 static int macfdb_read_ns(struct ns *ns,
5791 void *_in_param __attribute__((unused)),
5792 void **out_param __attribute__((unused)))
5793 {
5794 struct zebra_ns *zns = ns->info;
5795
5796 macfdb_read(zns);
5797 return NS_WALK_CONTINUE;
5798 }
5799
5800 static int neigh_read_ns(struct ns *ns,
5801 void *_in_param __attribute__((unused)),
5802 void **out_param __attribute__((unused)))
5803 {
5804 struct zebra_ns *zns = ns->info;
5805
5806 neigh_read(zns);
5807 return NS_WALK_CONTINUE;
5808 }
5809
5810 /*
5811 * Handle message from client to learn (or stop learning) about VNIs and MACs.
5812 * When enabled, the VNI hash table will be built and MAC FDB table read;
5813 * when disabled, the entries should be deleted and remote VTEPs and MACs
5814 * uninstalled from the kernel.
5815 * This also informs the setting for BUM handling at the time this change
5816 * occurs; it is relevant only when specifying "learn".
5817 */
5818 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
5819 {
5820 struct stream *s = NULL;
5821 int advertise = 0;
5822 enum vxlan_flood_control flood_ctrl;
5823
5824 /* Mismatch between EVPN VRF and current VRF (should be prevented by
5825 * bgpd's cli) */
5826 if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
5827 return;
5828
5829 s = msg;
5830 STREAM_GETC(s, advertise);
5831 STREAM_GETC(s, flood_ctrl);
5832
5833 if (IS_ZEBRA_DEBUG_VXLAN)
5834 zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
5835 zvrf_name(zvrf), zvrf_id(zvrf),
5836 advertise ? "enabled" : "disabled",
5837 is_evpn_enabled() ? "enabled" : "disabled",
5838 flood_ctrl);
5839
5840 if (zvrf->advertise_all_vni == advertise)
5841 return;
5842
5843 zvrf->advertise_all_vni = advertise;
5844 if (EVPN_ENABLED(zvrf)) {
5845 zrouter.evpn_vrf = zvrf;
5846
5847 /* Note BUM handling */
5848 zvrf->vxlan_flood_ctrl = flood_ctrl;
5849
5850 /* Replay all ESs */
5851 zebra_evpn_es_send_all_to_client(true /* add */);
5852
5853 /* Build EVPN hash table and inform BGP. */
5854 zevpn_build_hash_table();
5855
5856 /* Add all SVI (L3 GW) MACs to BGP*/
5857 hash_iterate(zvrf->evpn_table,
5858 zebra_evpn_gw_macip_add_for_evpn_hash, NULL);
5859
5860 /* Read the MAC FDB */
5861 ns_walk_func(macfdb_read_ns, NULL, NULL);
5862
5863 /* Read neighbors */
5864 ns_walk_func(neigh_read_ns, NULL, NULL);
5865 } else {
5866 /* Cleanup VTEPs for all EVPNs - uninstall from
5867 * kernel and free entries.
5868 */
5869 hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all,
5870 zvrf);
5871
5872 /* Delete all ESs in BGP */
5873 zebra_evpn_es_send_all_to_client(false /* add */);
5874
5875 /* cleanup all l3vnis */
5876 hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
5877
5878 /* Mark as "no EVPN VRF" */
5879 zrouter.evpn_vrf = NULL;
5880 }
5881
5882 stream_failure:
5883 return;
5884 }
5885
5886 /*
5887 * Allocate EVPN hash table for this VRF and do other initialization.
5888 * NOTE: Currently supported only for default VRF.
5889 */
5890 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
5891 {
5892 char buffer[80];
5893
5894 if (!zvrf)
5895 return;
5896
5897 snprintf(buffer, sizeof(buffer), "Zebra VRF EVPN Table: %s",
5898 zvrf->vrf->name);
5899 zvrf->evpn_table = hash_create_size(8, zebra_evpn_hash_keymake,
5900 zebra_evpn_hash_cmp, buffer);
5901
5902 snprintf(buffer, sizeof(buffer), "Zebra VxLAN SG Table: %s",
5903 zvrf->vrf->name);
5904 zvrf->vxlan_sg_table = hash_create_size(8, zebra_vxlan_sg_hash_key_make,
5905 zebra_vxlan_sg_hash_eq, buffer);
5906 }
5907
5908 /* Cleanup EVPN info, but don't free the table. */
5909 void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
5910 {
5911 struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn();
5912
5913 hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5914 zebra_vxlan_cleanup_sg_table(zvrf);
5915
5916 if (zvrf == evpn_zvrf)
5917 zebra_evpn_es_cleanup();
5918 }
5919
5920 /* Close all EVPN handling */
5921 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
5922 {
5923 if (!zvrf)
5924 return;
5925 hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf);
5926 hash_free(zvrf->evpn_table);
5927 if (zvrf->vxlan_sg_table) {
5928 zebra_vxlan_cleanup_sg_table(zvrf);
5929 hash_free(zvrf->vxlan_sg_table);
5930 zvrf->vxlan_sg_table = NULL;
5931 }
5932 }
5933
5934 /* init the l3vni table */
5935 void zebra_vxlan_init(void)
5936 {
5937 zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
5938 "Zebra VRF L3 VNI table");
5939 zrouter.evpn_vrf = NULL;
5940 zebra_evpn_mh_init();
5941 }
5942
5943 /* free l3vni table */
5944 void zebra_vxlan_disable(void)
5945 {
5946 hash_free(zrouter.l3vni_table);
5947 zebra_evpn_mh_terminate();
5948 }
5949
5950 /* get the l3vni svi ifindex */
5951 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
5952 {
5953 struct zebra_l3vni *zl3vni = NULL;
5954
5955 zl3vni = zl3vni_from_vrf(vrf_id);
5956 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5957 return 0;
5958
5959 return zl3vni->svi_if->ifindex;
5960 }
5961
5962 /************************** vxlan SG cache management ************************/
5963 /* Inform PIM about the mcast group */
5964 static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
5965 struct prefix_sg *sg,
5966 char *sg_str, uint16_t cmd)
5967 {
5968 struct zserv *client = NULL;
5969 struct stream *s = NULL;
5970
5971 client = zserv_find_client(ZEBRA_ROUTE_PIM, 0);
5972 if (!client)
5973 return 0;
5974
5975 if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
5976 return 0;
5977
5978 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5979
5980 zclient_create_header(s, cmd, VRF_DEFAULT);
5981 stream_putl(s, IPV4_MAX_BYTELEN);
5982 stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
5983 stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
5984
5985 /* Write packet size. */
5986 stream_putw_at(s, 0, stream_get_endp(s));
5987
5988 if (IS_ZEBRA_DEBUG_VXLAN)
5989 zlog_debug(
5990 "Send %s %s to %s",
5991 (cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", sg_str,
5992 zebra_route_string(client->proto));
5993
5994 if (cmd == ZEBRA_VXLAN_SG_ADD)
5995 client->vxlan_sg_add_cnt++;
5996 else
5997 client->vxlan_sg_del_cnt++;
5998
5999 return zserv_send_message(client, s);
6000 }
6001
6002 static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
6003 {
6004 const struct zebra_vxlan_sg *vxlan_sg = p;
6005
6006 return (jhash_2words(vxlan_sg->sg.src.s_addr,
6007 vxlan_sg->sg.grp.s_addr, 0));
6008 }
6009
6010 static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
6011 {
6012 const struct zebra_vxlan_sg *sg1 = p1;
6013 const struct zebra_vxlan_sg *sg2 = p2;
6014
6015 return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
6016 && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
6017 }
6018
6019 static struct zebra_vxlan_sg *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
6020 struct prefix_sg *sg)
6021 {
6022 struct zebra_vxlan_sg *vxlan_sg;
6023
6024 vxlan_sg = XCALLOC(MTYPE_ZVXLAN_SG, sizeof(*vxlan_sg));
6025
6026 vxlan_sg->zvrf = zvrf;
6027 vxlan_sg->sg = *sg;
6028 prefix_sg2str(sg, vxlan_sg->sg_str);
6029
6030 vxlan_sg = hash_get(zvrf->vxlan_sg_table, vxlan_sg, hash_alloc_intern);
6031
6032 if (IS_ZEBRA_DEBUG_VXLAN)
6033 zlog_debug("vxlan SG %s created", vxlan_sg->sg_str);
6034
6035 return vxlan_sg;
6036 }
6037
6038 static struct zebra_vxlan_sg *zebra_vxlan_sg_find(struct zebra_vrf *zvrf,
6039 struct prefix_sg *sg)
6040 {
6041 struct zebra_vxlan_sg lookup;
6042
6043 lookup.sg = *sg;
6044 return hash_lookup(zvrf->vxlan_sg_table, &lookup);
6045 }
6046
6047 static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
6048 struct prefix_sg *sg)
6049 {
6050 struct zebra_vxlan_sg *vxlan_sg;
6051 struct zebra_vxlan_sg *parent = NULL;
6052 struct in_addr sip;
6053
6054 vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
6055 if (vxlan_sg)
6056 return vxlan_sg;
6057
6058 /* create a *G entry for every BUM group implicitly -
6059 * 1. The SG entry is used by pimd to setup the vxlan-origination-mroute
6060 * 2. the XG entry is used by pimd to setup the
6061 * vxlan-termination-mroute
6062 */
6063 if (sg->src.s_addr != INADDR_ANY) {
6064 memset(&sip, 0, sizeof(sip));
6065 parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
6066 if (!parent)
6067 return NULL;
6068 }
6069
6070 vxlan_sg = zebra_vxlan_sg_new(zvrf, sg);
6071
6072 zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
6073 ZEBRA_VXLAN_SG_ADD);
6074
6075 return vxlan_sg;
6076 }
6077
6078 static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
6079 {
6080 struct in_addr sip;
6081 struct zebra_vrf *zvrf;
6082
6083 zvrf = vrf_info_lookup(VRF_DEFAULT);
6084 if (!zvrf)
6085 return;
6086
6087 /* On SG entry deletion remove the reference to its parent XG
6088 * entry
6089 */
6090 if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
6091 memset(&sip, 0, sizeof(sip));
6092 zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
6093 }
6094
6095 zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
6096 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
6097
6098 hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
6099
6100 if (IS_ZEBRA_DEBUG_VXLAN)
6101 zlog_debug("VXLAN SG %s deleted", vxlan_sg->sg_str);
6102
6103 XFREE(MTYPE_ZVXLAN_SG, vxlan_sg);
6104 }
6105
6106 static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
6107 struct in_addr sip, struct in_addr mcast_grp)
6108 {
6109 struct zebra_vxlan_sg *vxlan_sg;
6110 struct prefix_sg sg;
6111
6112 sg.family = AF_INET;
6113 sg.prefixlen = IPV4_MAX_BYTELEN;
6114 sg.src = sip;
6115 sg.grp = mcast_grp;
6116 vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
6117 if (!vxlan_sg)
6118 return;
6119
6120 if (vxlan_sg->ref_cnt)
6121 --vxlan_sg->ref_cnt;
6122
6123 if (!vxlan_sg->ref_cnt)
6124 zebra_vxlan_sg_del(vxlan_sg);
6125 }
6126
6127 static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
6128 struct in_addr sip,
6129 struct in_addr mcast_grp)
6130 {
6131 struct zebra_vxlan_sg *vxlan_sg;
6132 struct prefix_sg sg;
6133
6134 sg.family = AF_INET;
6135 sg.prefixlen = IPV4_MAX_BYTELEN;
6136 sg.src = sip;
6137 sg.grp = mcast_grp;
6138 vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
6139 if (vxlan_sg)
6140 ++vxlan_sg->ref_cnt;
6141
6142 return vxlan_sg;
6143 }
6144
6145 void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
6146 struct in_addr mcast_grp)
6147 {
6148 struct zebra_vrf *zvrf;
6149
6150 if (local_vtep_ip.s_addr == INADDR_ANY
6151 || mcast_grp.s_addr == INADDR_ANY)
6152 return;
6153
6154 zvrf = vrf_info_lookup(VRF_DEFAULT);
6155 if (!zvrf)
6156 return;
6157
6158 zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
6159 }
6160
6161 void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, struct in_addr mcast_grp)
6162 {
6163 struct zebra_vrf *zvrf;
6164
6165 if (local_vtep_ip.s_addr == INADDR_ANY
6166 || mcast_grp.s_addr == INADDR_ANY)
6167 return;
6168
6169 zvrf = vrf_info_lookup(VRF_DEFAULT);
6170 if (!zvrf)
6171 return;
6172 zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
6173 }
6174
6175 static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg)
6176 {
6177 struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6178
6179 /* increment the ref count against (*,G) to prevent them from being
6180 * deleted
6181 */
6182 if (vxlan_sg->sg.src.s_addr == INADDR_ANY)
6183 ++vxlan_sg->ref_cnt;
6184 }
6185
6186 static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg)
6187 {
6188 struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6189
6190 /* decrement the dummy ref count against (*,G) to delete them */
6191 if (vxlan_sg->sg.src.s_addr == INADDR_ANY) {
6192 if (vxlan_sg->ref_cnt)
6193 --vxlan_sg->ref_cnt;
6194 if (!vxlan_sg->ref_cnt)
6195 zebra_vxlan_sg_del(vxlan_sg);
6196 }
6197 }
6198
6199 static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg)
6200 {
6201 struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6202
6203 zebra_vxlan_sg_del(vxlan_sg);
6204 }
6205
6206 static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf)
6207 {
6208 /* increment the ref count against (*,G) to prevent them from being
6209 * deleted
6210 */
6211 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_pre_cleanup, NULL);
6212
6213 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_cleanup, NULL);
6214
6215 /* decrement the dummy ref count against the XG entries */
6216 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_post_cleanup, NULL);
6217 }
6218
6219 static void zebra_vxlan_sg_replay_send(struct hash_bucket *bucket, void *arg)
6220 {
6221 struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
6222
6223 zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
6224 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
6225 }
6226
6227 /* Handle message from client to replay vxlan SG entries */
6228 void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
6229 {
6230 if (IS_ZEBRA_DEBUG_VXLAN)
6231 zlog_debug("VxLAN SG updates to PIM, start");
6232
6233 SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6234
6235 if (!EVPN_ENABLED(zvrf)) {
6236 if (IS_ZEBRA_DEBUG_VXLAN)
6237 zlog_debug("VxLAN SG replay request on unexpected vrf %d",
6238 zvrf->vrf->vrf_id);
6239 return;
6240 }
6241
6242 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
6243 }
6244
6245
6246 /* Cleanup EVPN configuration of a specific VRF */
6247 static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
6248 {
6249 struct zebra_l3vni *zl3vni = NULL;
6250
6251 zvrf->advertise_all_vni = 0;
6252 zvrf->advertise_gw_macip = 0;
6253 zvrf->advertise_svi_macip = 0;
6254 zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
6255
6256 hash_iterate(zvrf->evpn_table, zebra_evpn_cfg_cleanup, NULL);
6257
6258 if (zvrf->l3vni)
6259 zl3vni = zl3vni_lookup(zvrf->l3vni);
6260 if (zl3vni) {
6261 /* delete and uninstall all rmacs */
6262 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
6263 zl3vni);
6264 /* delete and uninstall all next-hops */
6265 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
6266 zl3vni);
6267 }
6268 }
6269
6270 /* Cleanup BGP EVPN configuration upon client disconnect */
6271 static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
6272 {
6273 struct vrf *vrf;
6274 struct zebra_vrf *zvrf;
6275
6276 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
6277 zvrf = vrf->info;
6278 if (zvrf)
6279 zebra_evpn_vrf_cfg_cleanup(zvrf);
6280 }
6281
6282 return 0;
6283 }
6284
6285 static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
6286 {
6287 struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
6288
6289 if (CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
6290 if (IS_ZEBRA_DEBUG_VXLAN)
6291 zlog_debug("VxLAN SG updates to PIM, stop");
6292 UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
6293 }
6294
6295 return 0;
6296 }
6297
6298 static int zebra_evpn_cfg_clean_up(struct zserv *client)
6299 {
6300 if (client->proto == ZEBRA_ROUTE_BGP)
6301 return zebra_evpn_bgp_cfg_clean_up(client);
6302
6303 if (client->proto == ZEBRA_ROUTE_PIM)
6304 return zebra_evpn_pim_cfg_clean_up(client);
6305
6306 return 0;
6307 }
6308
6309 /*
6310 * Handle results for vxlan dataplane operations.
6311 */
6312 extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx)
6313 {
6314 return;
6315 }
6316
6317 /* Config knob for accepting lower sequence numbers */
6318 void zebra_vxlan_set_accept_bgp_seq(bool set)
6319 {
6320 accept_bgp_seq = set;
6321 }
6322
6323 bool zebra_vxlan_get_accept_bgp_seq(void)
6324 {
6325 return accept_bgp_seq;
6326 }
6327
6328 /* Cleanup BGP EVPN configuration upon client disconnect */
6329 extern void zebra_evpn_init(void)
6330 {
6331 hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
6332 }