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