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