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