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