]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
zebra: Add "show evpn mac vni all detail" command
[mirror_frr.git] / zebra / zebra_vxlan.c
1 /*
2 * Zebra EVPN for VxLAN code
3 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "hash.h"
26 #include "if.h"
27 #include "jhash.h"
28 #include "linklist.h"
29 #include "log.h"
30 #include "memory.h"
31 #include "prefix.h"
32 #include "stream.h"
33 #include "table.h"
34 #include "vlan.h"
35 #include "vxlan.h"
36 #ifdef GNU_LINUX
37 #include <linux/neighbour.h>
38 #endif
39
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_vxlan_private.h"
53 #include "zebra/zserv.h"
54
55 DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
56 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
57 DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
58 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
59 DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
60 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
61
62 /* definitions */
63
64 /* static function declarations */
65 static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
66 uint16_t cmd);
67 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
68 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
69 static void zvni_print_dad_neigh_hash(struct hash_backet *backet, void *ctxt);
70 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
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 zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
77 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
78 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
79 static void zvni_print(zebra_vni_t *zvni, void **ctxt);
80 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
81
82 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
83 struct ipaddr *ip, uint8_t flags,
84 uint32_t seq, uint16_t cmd);
85 static unsigned int neigh_hash_keymake(void *p);
86 static void *zvni_neigh_alloc(void *p);
87 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
88 struct ethaddr *mac);
89 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
90 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
91 struct in_addr *r_vtep_ip);
92 static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
93 uint32_t flags);
94 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
95 static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
96 struct ethaddr *macaddr,
97 uint8_t flags, uint32_t seq);
98 static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
99 struct ethaddr *macaddr,
100 uint8_t flags);
101 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
102 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
103 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
104 struct interface *br_if);
105 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if);
106
107 /* l3-vni next-hop neigh related APIs */
108 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
109 struct ipaddr *ip);
110 static void *zl3vni_nh_alloc(void *p);
111 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
112 struct ipaddr *vtep_ip,
113 struct ethaddr *rmac);
114 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
115 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
116 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
117
118 /* l3-vni rmac related APIs */
119 static void zl3vni_print_rmac_hash(struct hash_backet *, void *);
120 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
121 struct ethaddr *rmac);
122 static void *zl3vni_rmac_alloc(void *p);
123 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
124 struct ethaddr *rmac);
125 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
126 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
127 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
128
129 /* l3-vni related APIs*/
130 static zebra_l3vni_t *zl3vni_lookup(vni_t vni);
131 static void *zl3vni_alloc(void *p);
132 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
133 static int zl3vni_del(zebra_l3vni_t *zl3vni);
134 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t);
135 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni);
136 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni);
137 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni);
138 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni);
139
140 static unsigned int mac_hash_keymake(void *p);
141 static bool mac_cmp(const void *p1, const void *p2);
142 static void *zvni_mac_alloc(void *p);
143 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
144 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
145 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
146 struct in_addr *r_vtep_ip);
147 static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
148 uint32_t flags);
149 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
150 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
151 uint8_t flags, uint32_t seq);
152 static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr);
153 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
154 struct interface *br_if, vlanid_t vid);
155 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
156 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac);
157 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
158
159 static unsigned int vni_hash_keymake(void *p);
160 static void *zvni_alloc(void *p);
161 static zebra_vni_t *zvni_lookup(vni_t vni);
162 static zebra_vni_t *zvni_add(vni_t vni);
163 static int zvni_del(zebra_vni_t *zvni);
164 static int zvni_send_add_to_client(zebra_vni_t *zvni);
165 static int zvni_send_del_to_client(vni_t vni);
166 static void zvni_build_hash_table();
167 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
168 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
169 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
170 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
171 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
172 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
173 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
174 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
175 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
176 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
177 struct ethaddr *macaddr, struct ipaddr *ip);
178 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
179 struct ipaddr *ip);
180 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
181 static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
182 static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
183 zebra_mac_t *old_zmac,
184 zebra_mac_t *new_zmac,
185 zebra_neigh_t *nbr);
186 static int remote_neigh_count(zebra_mac_t *zmac);
187 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac);
188 static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t);
189 static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t);
190 static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
191 zebra_neigh_t *nbr,
192 struct in_addr vtep_ip,
193 bool do_dad,
194 bool *is_dup_detect,
195 bool is_local);
196 static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
197 zebra_mac_t *mac,
198 struct in_addr vtep_ip,
199 bool do_dad,
200 bool *is_dup_detect,
201 bool is_local);
202
203 /* Private functions */
204 static int host_rb_entry_compare(const struct host_rb_entry *hle1,
205 const struct host_rb_entry *hle2)
206 {
207 if (hle1->p.family < hle2->p.family)
208 return -1;
209
210 if (hle1->p.family > hle2->p.family)
211 return 1;
212
213 if (hle1->p.prefixlen < hle2->p.prefixlen)
214 return -1;
215
216 if (hle1->p.prefixlen > hle2->p.prefixlen)
217 return 1;
218
219 if (hle1->p.family == AF_INET) {
220 if (hle1->p.u.prefix4.s_addr < hle2->p.u.prefix4.s_addr)
221 return -1;
222
223 if (hle1->p.u.prefix4.s_addr > hle2->p.u.prefix4.s_addr)
224 return 1;
225
226 return 0;
227 } else if (hle1->p.family == AF_INET6) {
228 return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
229 IPV6_MAX_BYTELEN);
230 } else {
231 zlog_debug("%s: Unexpected family type: %d",
232 __PRETTY_FUNCTION__, hle1->p.family);
233 return 0;
234 }
235 }
236 RB_GENERATE(host_rb_tree_entry, host_rb_entry, hl_entry, host_rb_entry_compare);
237
238 static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe)
239 {
240 struct host_rb_entry *hle;
241 uint32_t count = 0;
242
243 RB_FOREACH (hle, host_rb_tree_entry, hrbe)
244 count++;
245
246 return count;
247 }
248
249 /*
250 * Return number of valid MACs in a VNI's MAC hash table - all
251 * remote MACs and non-internal (auto) local MACs count.
252 */
253 static uint32_t num_valid_macs(zebra_vni_t *zvni)
254 {
255 unsigned int i;
256 uint32_t num_macs = 0;
257 struct hash *hash;
258 struct hash_backet *hb;
259 zebra_mac_t *mac;
260
261 hash = zvni->mac_table;
262 if (!hash)
263 return num_macs;
264 for (i = 0; i < hash->size; i++) {
265 for (hb = hash->index[i]; hb; hb = hb->next) {
266 mac = (zebra_mac_t *)hb->data;
267 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
268 || CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
269 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
270 num_macs++;
271 }
272 }
273
274 return num_macs;
275 }
276
277 static uint32_t num_dup_detected_macs(zebra_vni_t *zvni)
278 {
279 unsigned int i;
280 uint32_t num_macs = 0;
281 struct hash *hash;
282 struct hash_backet *hb;
283 zebra_mac_t *mac;
284
285 hash = zvni->mac_table;
286 if (!hash)
287 return num_macs;
288 for (i = 0; i < hash->size; i++) {
289 for (hb = hash->index[i]; hb; hb = hb->next) {
290 mac = (zebra_mac_t *)hb->data;
291 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
292 num_macs++;
293 }
294 }
295
296 return num_macs;
297 }
298
299 static uint32_t num_dup_detected_neighs(zebra_vni_t *zvni)
300 {
301 unsigned int i;
302 uint32_t num_neighs = 0;
303 struct hash *hash;
304 struct hash_backet *hb;
305 zebra_neigh_t *nbr;
306
307 hash = zvni->neigh_table;
308 if (!hash)
309 return num_neighs;
310 for (i = 0; i < hash->size; i++) {
311 for (hb = hash->index[i]; hb; hb = hb->next) {
312 nbr = (zebra_neigh_t *)hb->data;
313 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
314 num_neighs++;
315 }
316 }
317
318 return num_neighs;
319 }
320
321 static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
322 {
323 struct zebra_vrf *zvrf;
324
325 zvrf = vrf_info_lookup(VRF_DEFAULT);
326 if (zvrf && zvrf->advertise_gw_macip)
327 return 1;
328
329 if (zvni && zvni->advertise_gw_macip)
330 return 1;
331
332 return 0;
333 }
334
335 /* As part Duplicate Address Detection (DAD) for IP mobility
336 * MAC binding changes, ensure to inherit duplicate flag
337 * from MAC.
338 */
339 static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
340 zebra_mac_t *old_zmac,
341 zebra_mac_t *new_zmac,
342 zebra_neigh_t *nbr)
343 {
344 bool is_old_mac_dup = false;
345 bool is_new_mac_dup = false;
346
347 if (!zvrf->dup_addr_detect)
348 return 0;
349 /* Check old or new MAC is detected as duplicate
350 * mark this neigh as duplicate
351 */
352 if (old_zmac)
353 is_old_mac_dup = CHECK_FLAG(old_zmac->flags,
354 ZEBRA_MAC_DUPLICATE);
355 if (new_zmac)
356 is_new_mac_dup = CHECK_FLAG(new_zmac->flags,
357 ZEBRA_MAC_DUPLICATE);
358 /* Old and/or new MAC can be in duplicate state,
359 * based on that IP/Neigh Inherits the flag.
360 * If New MAC is marked duplicate, inherit to the IP.
361 * If old MAC is duplicate but new MAC is not, clear
362 * duplicate flag for IP and reset detection params
363 * and let IP DAD retrigger.
364 */
365 if (is_new_mac_dup && !CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
366 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
367 /* Capture Duplicate detection time */
368 nbr->dad_dup_detect_time = monotime(NULL);
369 return 1;
370 } else if (is_old_mac_dup && !is_new_mac_dup) {
371 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
372 nbr->dad_count = 0;
373 nbr->detect_start_time.tv_sec = 0;
374 nbr->detect_start_time.tv_usec = 0;
375 }
376 return 0;
377 }
378
379 static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
380 zebra_mac_t *mac,
381 struct in_addr vtep_ip,
382 bool do_dad,
383 bool *is_dup_detect,
384 bool is_local)
385 {
386 zebra_neigh_t *nbr;
387 struct listnode *node = NULL;
388 struct timeval elapsed = {0, 0};
389 char buf[ETHER_ADDR_STRLEN];
390 char buf1[INET6_ADDRSTRLEN];
391 bool reset_params = false;
392
393 if (!(zvrf->dup_addr_detect && do_dad))
394 return;
395
396 /* MAC is detected as duplicate,
397 * Local MAC event -> hold on advertising to BGP.
398 * Remote MAC event -> hold on installing it.
399 */
400 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
401 if (IS_ZEBRA_DEBUG_VXLAN)
402 zlog_debug(
403 "%s: duplicate addr MAC %s flags 0x%x skip update to client, learn count %u recover time %u",
404 __PRETTY_FUNCTION__,
405 prefix_mac2str(&mac->macaddr, buf,
406 sizeof(buf)),
407 mac->flags, mac->dad_count,
408 zvrf->dad_freeze_time);
409
410 /* For duplicate MAC do not update
411 * client but update neigh due to
412 * this MAC update.
413 */
414 if (zvrf->dad_freeze)
415 *is_dup_detect = false;
416
417 return;
418 }
419
420 /* Check if detection time (M-secs) expired.
421 * Reset learn count and detection start time.
422 */
423 monotime_since(&mac->detect_start_time, &elapsed);
424 reset_params = (elapsed.tv_sec > zvrf->dad_time);
425 if (is_local && !reset_params) {
426 /* RFC-7432: A PE/VTEP that detects a MAC mobility
427 * event via LOCAL learning starts an M-second timer.
428 *
429 * NOTE: This is the START of the probe with count is
430 * 0 during LOCAL learn event.
431 * (mac->dad_count == 0 || elapsed.tv_sec >= zvrf->dad_time)
432 */
433 reset_params = !mac->dad_count;
434 }
435
436 if (reset_params) {
437 if (IS_ZEBRA_DEBUG_VXLAN)
438 zlog_debug(
439 "%s: duplicate addr MAC %s flags 0x%x detection time passed, reset learn count %u"
440 , __PRETTY_FUNCTION__,
441 prefix_mac2str(&mac->macaddr, buf,
442 sizeof(buf)),
443 mac->flags, mac->dad_count);
444
445 mac->dad_count = 0;
446 /* Start dup. addr detection (DAD) start time,
447 * ONLY during LOCAL learn.
448 */
449 if (is_local)
450 monotime(&mac->detect_start_time);
451
452 } else if (!is_local) {
453 /* For REMOTE MAC, increment detection count
454 * ONLY while in probe window, once window passed,
455 * next local learn event should trigger DAD.
456 */
457 mac->dad_count++;
458 }
459
460 /* For LOCAL MAC learn event, once count is reset above via either
461 * initial/start detection time or passed the probe time, the count
462 * needs to be incremented.
463 */
464 if (is_local)
465 mac->dad_count++;
466
467 zlog_debug("%s: MAC DAD %s dad_count %u ",
468 __PRETTY_FUNCTION__,
469 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
470 mac->dad_count);
471
472 if (mac->dad_count >= zvrf->dad_max_moves) {
473 flog_warn(EC_ZEBRA_DUP_MAC_DETECTED,
474 "VNI %u: MAC %s detected as duplicate during %s VTEP %s",
475 mac->zvni->vni,
476 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
477 is_local ? "local update, last" :
478 "remote update, from", inet_ntoa(vtep_ip));
479
480 SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
481
482 /* Capture Duplicate detection time */
483 mac->dad_dup_detect_time = monotime(NULL);
484
485 /* Mark all IPs/Neighs as duplicate
486 * associcated with this MAC
487 */
488 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
489
490 /* Ony Mark IPs which are Local */
491 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
492 continue;
493
494 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
495
496 nbr->dad_dup_detect_time = monotime(NULL);
497
498 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
499 "VNI %u: MAC %s IP %s detected as duplicate during %s update, inherit duplicate from MAC",
500 mac->zvni->vni,
501 prefix_mac2str(&mac->macaddr,
502 buf, sizeof(buf)),
503 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
504 is_local ? "local" : "remote");
505 }
506
507 /* Start auto recovery timer for this MAC */
508 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
509 if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
510 if (IS_ZEBRA_DEBUG_VXLAN)
511 zlog_debug(
512 "%s: duplicate addr MAC %s flags 0x%x auto recovery time %u start"
513 , __PRETTY_FUNCTION__,
514 prefix_mac2str(&mac->macaddr, buf,
515 sizeof(buf)),
516 mac->flags, zvrf->dad_freeze_time);
517
518 thread_add_timer(zebrad.master,
519 zebra_vxlan_dad_mac_auto_recovery_exp,
520 mac, zvrf->dad_freeze_time,
521 &mac->dad_mac_auto_recovery_timer);
522 }
523
524 /* Do not inform to client (BGPd),
525 * upd_neigh for neigh sequence change.
526 */
527 if (zvrf->dad_freeze)
528 *is_dup_detect = false;
529 }
530 }
531
532 static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
533 zebra_neigh_t *nbr,
534 struct in_addr vtep_ip,
535 bool do_dad,
536 bool *is_dup_detect,
537 bool is_local)
538 {
539
540 struct timeval elapsed = {0, 0};
541 char buf[ETHER_ADDR_STRLEN];
542 char buf1[INET6_ADDRSTRLEN];
543 bool reset_params = false;
544
545 if (!zvrf->dup_addr_detect)
546 return;
547
548 /* IP is detected as duplicate or inherit dup
549 * state, hold on to install as remote entry
550 * only if freeze is enabled.
551 */
552 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
553 if (IS_ZEBRA_DEBUG_VXLAN)
554 zlog_debug(
555 "%s: duplicate addr MAC %s IP %s flags 0x%x skip installing, learn count %u recover time %u",
556 __PRETTY_FUNCTION__,
557 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
558 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
559 nbr->flags, nbr->dad_count,
560 zvrf->dad_freeze_time);
561
562 if (zvrf->dad_freeze)
563 *is_dup_detect = true;
564 /* warn-only action, neigh will be installed.
565 * freeze action, it wil not be installed.
566 */
567 return;
568 }
569
570 if (!do_dad)
571 return;
572
573 /* Check if detection time (M-secs) expired.
574 * Reset learn count and detection start time.
575 * During remote mac add, count should already be 1
576 * via local learning.
577 */
578 monotime_since(&nbr->detect_start_time, &elapsed);
579 reset_params = (elapsed.tv_sec > zvrf->dad_time);
580
581 if (is_local && !reset_params) {
582 /* RFC-7432: A PE/VTEP that detects a MAC mobility
583 * event via LOCAL learning starts an M-second timer.
584 *
585 * NOTE: This is the START of the probe with count is
586 * 0 during LOCAL learn event.
587 */
588 reset_params = !nbr->dad_count;
589 }
590
591 if (reset_params) {
592 if (IS_ZEBRA_DEBUG_VXLAN)
593 zlog_debug(
594 "%s: duplicate addr MAC %s IP %s flags 0x%x detection time passed, reset learn count %u",
595 __PRETTY_FUNCTION__,
596 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
597 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
598 nbr->flags, nbr->dad_count);
599 /* Reset learn count but do not start detection
600 * during REMOTE learn event.
601 */
602 nbr->dad_count = 0;
603 /* Start dup. addr detection (DAD) start time,
604 * ONLY during LOCAL learn.
605 */
606 if (is_local)
607 monotime(&nbr->detect_start_time);
608
609 } else if (!is_local) {
610 /* For REMOTE IP/Neigh, increment detection count
611 * ONLY while in probe window, once window passed,
612 * next local learn event should trigger DAD.
613 */
614 nbr->dad_count++;
615 }
616
617 /* For LOCAL IP/Neigh learn event, once count is reset above via either
618 * initial/start detection time or passed the probe time, the count
619 * needs to be incremented.
620 */
621 if (is_local)
622 nbr->dad_count++;
623
624 if (nbr->dad_count >= zvrf->dad_max_moves) {
625 flog_warn(EC_ZEBRA_DUP_IP_DETECTED,
626 "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s",
627 nbr->zvni->vni,
628 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
629 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
630 is_local ? "local update, last" :
631 "remote update, from",
632 inet_ntoa(vtep_ip));
633
634 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
635
636 /* Capture Duplicate detection time */
637 nbr->dad_dup_detect_time = monotime(NULL);
638
639 /* Start auto recovery timer for this IP */
640 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
641 if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
642 if (IS_ZEBRA_DEBUG_VXLAN)
643 zlog_debug(
644 "%s: duplicate addr MAC %s IP %s flags 0x%x auto recovery time %u start",
645 __PRETTY_FUNCTION__,
646 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
647 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
648 nbr->flags, zvrf->dad_freeze_time);
649
650 thread_add_timer(zebrad.master,
651 zebra_vxlan_dad_ip_auto_recovery_exp,
652 nbr, zvrf->dad_freeze_time,
653 &nbr->dad_ip_auto_recovery_timer);
654 }
655 if (zvrf->dad_freeze)
656 *is_dup_detect = true;
657 }
658 }
659
660 /*
661 * Helper function to determine maximum width of neighbor IP address for
662 * display - just because we're dealing with IPv6 addresses that can
663 * widely vary.
664 */
665 static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
666 {
667 zebra_neigh_t *n;
668 char buf[INET6_ADDRSTRLEN];
669 struct neigh_walk_ctx *wctx = ctxt;
670 int width;
671
672 n = (zebra_neigh_t *)backet->data;
673
674 ipaddr2str(&n->ip, buf, sizeof(buf));
675 width = strlen(buf);
676 if (width > wctx->addr_width)
677 wctx->addr_width = width;
678
679 }
680
681 /*
682 * Print a specific neighbor entry.
683 */
684 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
685 {
686 struct vty *vty;
687 char buf1[ETHER_ADDR_STRLEN];
688 char buf2[INET6_ADDRSTRLEN];
689 const char *type_str;
690 const char *state_str;
691 bool flags_present = false;
692 struct zebra_vrf *zvrf = NULL;
693 struct timeval detect_start_time = {0, 0};
694
695 zvrf = zebra_vrf_lookup_by_id(n->zvni->vrf_id);
696 if (!zvrf)
697 return;
698
699 ipaddr2str(&n->ip, buf2, sizeof(buf2));
700 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
701 type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ?
702 "local" : "remote";
703 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
704 vty = (struct vty *)ctxt;
705 if (json == NULL) {
706 vty_out(vty, "IP: %s\n",
707 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
708 vty_out(vty, " Type: %s\n", type_str);
709 vty_out(vty, " State: %s\n", state_str);
710 vty_out(vty, " MAC: %s\n",
711 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
712 } else {
713 json_object_string_add(json, "ip", buf2);
714 json_object_string_add(json, "type", type_str);
715 json_object_string_add(json, "state", state_str);
716 json_object_string_add(json, "mac", buf1);
717 }
718 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
719 if (json == NULL) {
720 vty_out(vty, " Remote VTEP: %s\n",
721 inet_ntoa(n->r_vtep_ip));
722 } else
723 json_object_string_add(json, "remoteVtep",
724 inet_ntoa(n->r_vtep_ip));
725 }
726 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
727 if (!json) {
728 vty_out(vty, " Flags: Default-gateway");
729 flags_present = true;
730 } else
731 json_object_boolean_true_add(json, "defaultGateway");
732 }
733 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
734 if (!json) {
735 vty_out(vty,
736 flags_present ? " ,Router" : " Flags: Router");
737 flags_present = true;
738 }
739 }
740 if (json == NULL) {
741 if (flags_present)
742 vty_out(vty, "\n");
743 vty_out(vty, " Local Seq: %u Remote Seq: %u\n",
744 n->loc_seq, n->rem_seq);
745
746 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
747 vty_out(vty, " Duplicate, detected at %s",
748 time_to_string(n->dad_dup_detect_time));
749 } else if (n->dad_count) {
750 monotime_since(&n->detect_start_time,
751 &detect_start_time);
752 if (detect_start_time.tv_sec <= zvrf->dad_time) {
753 char *buf = time_to_string(
754 n->detect_start_time.tv_sec);
755 char tmp_buf[30];
756
757 memset(tmp_buf, 0, 30);
758 strncpy(tmp_buf, buf, strlen(buf) - 1);
759 vty_out(vty,
760 " Duplicate detection started at %s, detection count %u\n",
761 tmp_buf, n->dad_count);
762 }
763 }
764 } else {
765 json_object_int_add(json, "localSequence", n->loc_seq);
766 json_object_int_add(json, "remoteSequence", n->rem_seq);
767 json_object_int_add(json, "detectionCount",
768 n->dad_count);
769 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
770 json_object_boolean_true_add(json, "isDuplicate");
771 else
772 json_object_boolean_false_add(json, "isDuplicate");
773
774
775 }
776 }
777
778 /*
779 * Print neighbor hash entry - called for display of all neighbors.
780 */
781 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
782 {
783 struct vty *vty;
784 json_object *json_vni = NULL, *json_row = NULL;
785 zebra_neigh_t *n;
786 char buf1[ETHER_ADDR_STRLEN];
787 char buf2[INET6_ADDRSTRLEN];
788 struct neigh_walk_ctx *wctx = ctxt;
789 const char *state_str;
790
791 vty = wctx->vty;
792 json_vni = wctx->json;
793 n = (zebra_neigh_t *)backet->data;
794
795 if (json_vni)
796 json_row = json_object_new_object();
797
798 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
799 ipaddr2str(&n->ip, buf2, sizeof(buf2));
800 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
801 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
802 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
803 return;
804
805 if (json_vni == NULL) {
806 vty_out(vty, "%*s %-6s %-8s %-17s\n",
807 -wctx->addr_width, buf2, "local",
808 state_str, buf1);
809 } else {
810 json_object_string_add(json_row, "type", "local");
811 json_object_string_add(json_row, "state", state_str);
812 json_object_string_add(json_row, "mac", buf1);
813 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
814 json_object_boolean_true_add(
815 json_row, "defaultGateway");
816 json_object_int_add(json_row, "localSequence",
817 n->loc_seq);
818 json_object_int_add(json_row, "remoteSequence",
819 n->rem_seq);
820 json_object_int_add(json_row, "detectionCount",
821 n->dad_count);
822 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
823 json_object_boolean_true_add(json_row,
824 "isDuplicate");
825 else
826 json_object_boolean_false_add(json_row,
827 "isDuplicate");
828 }
829 wctx->count++;
830 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
831 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
832 !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
833 return;
834
835 if (json_vni == NULL) {
836 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
837 (wctx->count == 0))
838 vty_out(vty,
839 "%*s %-6s %-8s %-17s %-21s\n",
840 -wctx->addr_width, "Neighbor", "Type",
841 "State", "MAC", "Remote VTEP");
842 vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
843 -wctx->addr_width, buf2, "remote", state_str,
844 buf1, inet_ntoa(n->r_vtep_ip));
845 } else {
846 json_object_string_add(json_row, "type", "remote");
847 json_object_string_add(json_row, "state", state_str);
848 json_object_string_add(json_row, "mac", buf1);
849 json_object_string_add(json_row, "remoteVtep",
850 inet_ntoa(n->r_vtep_ip));
851 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
852 json_object_boolean_true_add(json_row,
853 "defaultGateway");
854 json_object_int_add(json_row, "localSequence",
855 n->loc_seq);
856 json_object_int_add(json_row, "remoteSequence",
857 n->rem_seq);
858 json_object_int_add(json_row, "detectionCount",
859 n->dad_count);
860 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
861 json_object_boolean_true_add(json_row,
862 "isDuplicate");
863 else
864 json_object_boolean_false_add(json_row,
865 "isDuplicate");
866 }
867 wctx->count++;
868 }
869
870 if (json_vni)
871 json_object_object_add(json_vni, buf2, json_row);
872 }
873
874 /*
875 * Print neighbors for all VNI.
876 */
877 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
878 void **args)
879 {
880 struct vty *vty;
881 json_object *json = NULL, *json_vni = NULL;
882 zebra_vni_t *zvni;
883 uint32_t num_neigh;
884 struct neigh_walk_ctx wctx;
885 char vni_str[VNI_STR_LEN];
886 uint32_t print_dup;
887
888 vty = (struct vty *)args[0];
889 json = (json_object *)args[1];
890 print_dup = (uint32_t)(uintptr_t)args[2];
891
892 zvni = (zebra_vni_t *)backet->data;
893
894 num_neigh = hashcount(zvni->neigh_table);
895
896 if (print_dup)
897 num_neigh = num_dup_detected_neighs(zvni);
898
899 if (json == NULL) {
900 vty_out(vty,
901 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
902 zvni->vni, num_neigh);
903 } else {
904 json_vni = json_object_new_object();
905 json_object_int_add(json_vni, "numArpNd", num_neigh);
906 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
907 }
908
909 if (!num_neigh) {
910 if (json)
911 json_object_object_add(json, vni_str, json_vni);
912 return;
913 }
914
915 /* Since we have IPv6 addresses to deal with which can vary widely in
916 * size, we try to be a bit more elegant in display by first computing
917 * the maximum width.
918 */
919 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
920 wctx.zvni = zvni;
921 wctx.vty = vty;
922 wctx.addr_width = 15;
923 wctx.json = json_vni;
924 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
925
926 if (json == NULL) {
927 vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
928 -wctx.addr_width, "IP", "Type",
929 "State", "MAC", "Remote VTEP");
930 }
931 if (print_dup)
932 hash_iterate(zvni->neigh_table, zvni_print_dad_neigh_hash,
933 &wctx);
934 else
935 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
936
937 if (json)
938 json_object_object_add(json, vni_str, json_vni);
939 }
940
941 static void zvni_print_dad_neigh_hash(struct hash_backet *backet, void *ctxt)
942 {
943 zebra_neigh_t *nbr;
944
945 nbr = (zebra_neigh_t *)backet->data;
946 if (!nbr)
947 return;
948
949 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
950 zvni_print_neigh_hash(backet, ctxt);
951 }
952
953 /* print a specific next hop for an l3vni */
954 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
955 json_object *json)
956 {
957 char buf1[ETHER_ADDR_STRLEN];
958 char buf2[INET6_ADDRSTRLEN];
959 json_object *json_hosts = NULL;
960 struct host_rb_entry *hle;
961
962 if (!json) {
963 vty_out(vty, "Ip: %s\n",
964 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
965 vty_out(vty, " RMAC: %s\n",
966 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
967 vty_out(vty, " Refcount: %d\n",
968 rb_host_count(&n->host_rb));
969 vty_out(vty, " Prefixes:\n");
970 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
971 vty_out(vty, " %s\n",
972 prefix2str(&hle->p, buf2, sizeof(buf2)));
973 } else {
974 json_hosts = json_object_new_array();
975 json_object_string_add(
976 json, "ip", ipaddr2str(&(n->ip), buf2, sizeof(buf2)));
977 json_object_string_add(
978 json, "routerMac",
979 prefix_mac2str(&n->emac, buf2, sizeof(buf2)));
980 json_object_int_add(json, "refCount",
981 rb_host_count(&n->host_rb));
982 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
983 json_object_array_add(json_hosts,
984 json_object_new_string(prefix2str(
985 &hle->p, buf2, sizeof(buf2))));
986 json_object_object_add(json, "prefixList", json_hosts);
987 }
988 }
989
990 /* Print a specific RMAC entry */
991 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
992 json_object *json)
993 {
994 char buf1[ETHER_ADDR_STRLEN];
995 char buf2[PREFIX_STRLEN];
996 json_object *json_hosts = NULL;
997 struct host_rb_entry *hle;
998
999 if (!json) {
1000 vty_out(vty, "MAC: %s\n",
1001 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
1002 vty_out(vty, " Remote VTEP: %s\n",
1003 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1004 vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb));
1005 vty_out(vty, " Prefixes:\n");
1006 RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
1007 vty_out(vty, " %s\n",
1008 prefix2str(&hle->p, buf2, sizeof(buf2)));
1009 } else {
1010 json_hosts = json_object_new_array();
1011 json_object_string_add(
1012 json, "routerMac",
1013 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
1014 json_object_string_add(json, "vtepIp",
1015 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1016 json_object_int_add(json, "refCount",
1017 rb_host_count(&zrmac->host_rb));
1018 json_object_int_add(json, "localSequence", zrmac->loc_seq);
1019 json_object_int_add(json, "remoteSequence", zrmac->rem_seq);
1020 RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
1021 json_object_array_add(
1022 json_hosts,
1023 json_object_new_string(prefix2str(
1024 &hle->p, buf2, sizeof(buf2))));
1025 json_object_object_add(json, "prefixList", json_hosts);
1026 }
1027 }
1028
1029 /*
1030 * Print a specific MAC entry.
1031 */
1032 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
1033 {
1034 struct vty *vty;
1035 zebra_neigh_t *n = NULL;
1036 struct listnode *node = NULL;
1037 char buf1[20];
1038 char buf2[INET6_ADDRSTRLEN];
1039 struct zebra_vrf *zvrf;
1040 struct timeval detect_start_time = {0, 0};
1041
1042 zvrf = zebra_vrf_lookup_by_id(mac->zvni->vrf_id);
1043
1044 vty = (struct vty *)ctxt;
1045 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1046
1047 if (json) {
1048 json_object *json_mac = json_object_new_object();
1049
1050 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1051 struct zebra_ns *zns;
1052 struct interface *ifp;
1053 ifindex_t ifindex;
1054
1055 ifindex = mac->fwd_info.local.ifindex;
1056 zns = zebra_ns_lookup(NS_DEFAULT);
1057 ifp = if_lookup_by_index_per_ns(zns, ifindex);
1058 if (!ifp)
1059 return;
1060 json_object_string_add(json_mac, "type", "local");
1061 json_object_string_add(json_mac, "intf", ifp->name);
1062 json_object_int_add(json_mac, "ifindex", ifindex);
1063 if (mac->fwd_info.local.vid)
1064 json_object_int_add(json_mac, "vlan",
1065 mac->fwd_info.local.vid);
1066 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1067 json_object_string_add(json_mac, "type", "remote");
1068 json_object_string_add(
1069 json_mac, "remoteVtep",
1070 inet_ntoa(mac->fwd_info.r_vtep_ip));
1071 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
1072 json_object_string_add(json_mac, "type", "auto");
1073
1074 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
1075 json_object_boolean_true_add(json_mac, "stickyMac");
1076
1077 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
1078 json_object_boolean_true_add(json_mac,
1079 "defaultGateway");
1080
1081 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
1082 json_object_boolean_true_add(json_mac,
1083 "remoteGatewayMac");
1084
1085 json_object_int_add(json_mac, "localSequence", mac->loc_seq);
1086 json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
1087
1088 json_object_int_add(json_mac, "detectionCount", mac->dad_count);
1089 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1090 json_object_boolean_true_add(json_mac, "isDuplicate");
1091 else
1092 json_object_boolean_false_add(json_mac, "isDuplicate");
1093
1094 /* print all the associated neigh */
1095 if (!listcount(mac->neigh_list))
1096 json_object_string_add(json_mac, "neighbors", "none");
1097 else {
1098 json_object *json_active_nbrs = json_object_new_array();
1099 json_object *json_inactive_nbrs =
1100 json_object_new_array();
1101 json_object *json_nbrs = json_object_new_object();
1102
1103 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
1104 if (IS_ZEBRA_NEIGH_ACTIVE(n))
1105 json_object_array_add(
1106 json_active_nbrs,
1107 json_object_new_string(
1108 ipaddr2str(
1109 &n->ip, buf2,
1110 sizeof(buf2))));
1111 else
1112 json_object_array_add(
1113 json_inactive_nbrs,
1114 json_object_new_string(
1115 ipaddr2str(
1116 &n->ip, buf2,
1117 sizeof(buf2))));
1118 }
1119
1120 json_object_object_add(json_nbrs, "active",
1121 json_active_nbrs);
1122 json_object_object_add(json_nbrs, "inactive",
1123 json_inactive_nbrs);
1124 json_object_object_add(json_mac, "neighbors",
1125 json_nbrs);
1126 }
1127
1128 json_object_object_add(json, buf1, json_mac);
1129 } else {
1130 vty_out(vty, "MAC: %s\n", buf1);
1131
1132 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1133 struct zebra_ns *zns;
1134 struct interface *ifp;
1135 ifindex_t ifindex;
1136
1137 ifindex = mac->fwd_info.local.ifindex;
1138 zns = zebra_ns_lookup(NS_DEFAULT);
1139 ifp = if_lookup_by_index_per_ns(zns, ifindex);
1140 if (!ifp)
1141 return;
1142 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
1143 if (mac->fwd_info.local.vid)
1144 vty_out(vty, " VLAN: %u",
1145 mac->fwd_info.local.vid);
1146 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1147 vty_out(vty, " Remote VTEP: %s",
1148 inet_ntoa(mac->fwd_info.r_vtep_ip));
1149 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
1150 vty_out(vty, " Auto Mac ");
1151 }
1152
1153 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
1154 vty_out(vty, " Sticky Mac ");
1155
1156 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
1157 vty_out(vty, " Default-gateway Mac ");
1158
1159 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
1160 vty_out(vty, " Remote-gateway Mac ");
1161
1162 vty_out(vty, "\n");
1163 vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq,
1164 mac->rem_seq);
1165 vty_out(vty, "\n");
1166
1167 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
1168 vty_out(vty, " Duplicate, detected at %s",
1169 time_to_string(mac->dad_dup_detect_time));
1170 } else if (mac->dad_count) {
1171 monotime_since(&mac->detect_start_time,
1172 &detect_start_time);
1173 if (detect_start_time.tv_sec <= zvrf->dad_time) {
1174 char *buf = time_to_string(
1175 mac->detect_start_time.tv_sec);
1176 char tmp_buf[30];
1177
1178 memset(tmp_buf, 0, 30);
1179 strncpy(tmp_buf, buf, strlen(buf) - 1);
1180 vty_out(vty,
1181 " Duplicate detection started at %s, detection count %u\n",
1182 tmp_buf, mac->dad_count);
1183 }
1184 }
1185
1186 /* print all the associated neigh */
1187 vty_out(vty, " Neighbors:\n");
1188 if (!listcount(mac->neigh_list))
1189 vty_out(vty, " No Neighbors\n");
1190 else {
1191 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
1192 vty_out(vty, " %s %s\n",
1193 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
1194 (IS_ZEBRA_NEIGH_ACTIVE(n)
1195 ? "Active"
1196 : "Inactive"));
1197 }
1198 }
1199
1200 vty_out(vty, "\n");
1201 }
1202 }
1203
1204 /*
1205 * Print MAC hash entry - called for display of all MACs.
1206 */
1207 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
1208 {
1209 struct vty *vty;
1210 json_object *json_mac_hdr = NULL, *json_mac = NULL;
1211 zebra_mac_t *mac;
1212 char buf1[20];
1213 struct mac_walk_ctx *wctx = ctxt;
1214
1215 vty = wctx->vty;
1216 json_mac_hdr = wctx->json;
1217 mac = (zebra_mac_t *)backet->data;
1218
1219 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1220
1221 if (json_mac_hdr)
1222 json_mac = json_object_new_object();
1223
1224 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1225 struct zebra_ns *zns;
1226 ifindex_t ifindex;
1227 struct interface *ifp;
1228 vlanid_t vid;
1229
1230 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
1231 return;
1232
1233 zns = zebra_ns_lookup(NS_DEFAULT);
1234 ifindex = mac->fwd_info.local.ifindex;
1235 ifp = if_lookup_by_index_per_ns(zns, ifindex);
1236 if (!ifp) // unexpected
1237 return;
1238 vid = mac->fwd_info.local.vid;
1239 if (json_mac_hdr == NULL)
1240 vty_out(vty, "%-17s %-6s %-21s", buf1, "local",
1241 ifp->name);
1242 else {
1243 json_object_string_add(json_mac, "type", "local");
1244 json_object_string_add(json_mac, "intf", ifp->name);
1245 }
1246 if (vid) {
1247 if (json_mac_hdr == NULL)
1248 vty_out(vty, " %-5u", vid);
1249 else
1250 json_object_int_add(json_mac, "vlan", vid);
1251 }
1252 if (json_mac_hdr == NULL) {
1253 vty_out(vty, "\n");
1254 } else {
1255 json_object_int_add(json_mac, "localSequence",
1256 mac->loc_seq);
1257 json_object_int_add(json_mac, "remoteSequence",
1258 mac->rem_seq);
1259 json_object_int_add(json_mac, "detectionCount",
1260 mac->dad_count);
1261 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1262 json_object_boolean_true_add(json_mac,
1263 "isDuplicate");
1264 else
1265 json_object_boolean_false_add(json_mac,
1266 "isDuplicate");
1267 json_object_object_add(json_mac_hdr, buf1, json_mac);
1268 }
1269
1270 wctx->count++;
1271
1272 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1273
1274 if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
1275 !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
1276 &wctx->r_vtep_ip))
1277 return;
1278
1279 if (json_mac_hdr == NULL) {
1280 if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
1281 (wctx->count == 0)) {
1282 vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni);
1283 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC",
1284 "Type", "Intf/Remote VTEP", "VLAN");
1285 }
1286 vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote",
1287 inet_ntoa(mac->fwd_info.r_vtep_ip));
1288 } else {
1289 json_object_string_add(json_mac, "type", "remote");
1290 json_object_string_add(json_mac, "remoteVtep",
1291 inet_ntoa(mac->fwd_info.r_vtep_ip));
1292 json_object_object_add(json_mac_hdr, buf1, json_mac);
1293 json_object_int_add(json_mac, "localSequence",
1294 mac->loc_seq);
1295 json_object_int_add(json_mac, "remoteSequence",
1296 mac->rem_seq);
1297 json_object_int_add(json_mac, "detectionCount",
1298 mac->dad_count);
1299 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1300 json_object_boolean_true_add(json_mac,
1301 "isDuplicate");
1302 else
1303 json_object_boolean_false_add(json_mac,
1304 "isDuplicate");
1305
1306 }
1307
1308 wctx->count++;
1309 }
1310 }
1311
1312 /* Print Duplicate MAC */
1313 static void zvni_print_dad_mac_hash(struct hash_backet *backet, void *ctxt)
1314 {
1315 zebra_mac_t *mac;
1316
1317 mac = (zebra_mac_t *)backet->data;
1318 if (!mac)
1319 return;
1320
1321 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1322 zvni_print_mac_hash(backet, ctxt);
1323 }
1324
1325 /*
1326 * Print MAC hash entry in detail - called for display of all MACs.
1327 */
1328 static void zvni_print_mac_hash_detail(struct hash_backet *backet, void *ctxt)
1329 {
1330 struct vty *vty;
1331 json_object *json_mac_hdr = NULL;
1332 zebra_mac_t *mac;
1333 struct mac_walk_ctx *wctx = ctxt;
1334 char buf1[20];
1335
1336 vty = wctx->vty;
1337 json_mac_hdr = wctx->json;
1338 mac = (zebra_mac_t *)backet->data;
1339 if (!mac)
1340 return;
1341
1342 wctx->count++;
1343 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1344
1345 zvni_print_mac(mac, vty, json_mac_hdr);
1346 }
1347
1348 /* Print Duplicate MAC in detail */
1349 static void zvni_print_dad_mac_hash_detail(struct hash_backet *backet,
1350 void *ctxt)
1351 {
1352 zebra_mac_t *mac;
1353
1354 mac = (zebra_mac_t *)backet->data;
1355 if (!mac)
1356 return;
1357
1358 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1359 zvni_print_mac_hash_detail(backet, ctxt);
1360 }
1361
1362 /*
1363 * Print MACs for all VNI.
1364 */
1365 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
1366 {
1367 struct vty *vty;
1368 json_object *json = NULL, *json_vni = NULL;
1369 json_object *json_mac = NULL;
1370 zebra_vni_t *zvni;
1371 uint32_t num_macs;
1372 struct mac_walk_ctx *wctx = ctxt;
1373 char vni_str[VNI_STR_LEN];
1374
1375 vty = (struct vty *)wctx->vty;
1376 json = (struct json_object *)wctx->json;
1377
1378 zvni = (zebra_vni_t *)backet->data;
1379 wctx->zvni = zvni;
1380
1381 /*We are iterating over a new VNI, set the count to 0*/
1382 wctx->count = 0;
1383
1384 num_macs = num_valid_macs(zvni);
1385 if (!num_macs)
1386 return;
1387
1388 if (wctx->print_dup)
1389 num_macs = num_dup_detected_macs(zvni);
1390
1391 if (json) {
1392 json_vni = json_object_new_object();
1393 json_mac = json_object_new_object();
1394 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
1395 }
1396
1397 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
1398 if (json == NULL) {
1399 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
1400 zvni->vni, num_macs);
1401 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
1402 "Intf/Remote VTEP", "VLAN");
1403 } else
1404 json_object_int_add(json_vni, "numMacs", num_macs);
1405 }
1406
1407 if (!num_macs) {
1408 if (json) {
1409 json_object_int_add(json_vni, "numMacs", num_macs);
1410 json_object_object_add(json, vni_str, json_vni);
1411 }
1412 return;
1413 }
1414
1415 /* assign per-vni to wctx->json object to fill macs
1416 * under the vni. Re-assign primary json object to fill
1417 * next vni information.
1418 */
1419 wctx->json = json_mac;
1420 if (wctx->print_dup)
1421 hash_iterate(zvni->mac_table, zvni_print_dad_mac_hash, wctx);
1422 else
1423 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
1424 wctx->json = json;
1425 if (json) {
1426 if (wctx->count)
1427 json_object_object_add(json_vni, "macs", json_mac);
1428 json_object_object_add(json, vni_str, json_vni);
1429 }
1430 }
1431
1432 /*
1433 * Print MACs in detail for all VNI.
1434 */
1435 static void zvni_print_mac_hash_all_vni_detail(struct hash_backet *backet,
1436 void *ctxt)
1437 {
1438 struct vty *vty;
1439 json_object *json = NULL, *json_vni = NULL;
1440 json_object *json_mac = NULL;
1441 zebra_vni_t *zvni;
1442 uint32_t num_macs;
1443 struct mac_walk_ctx *wctx = ctxt;
1444 char vni_str[VNI_STR_LEN];
1445
1446 vty = (struct vty *)wctx->vty;
1447 json = (struct json_object *)wctx->json;
1448
1449 zvni = (zebra_vni_t *)backet->data;
1450 if (!zvni) {
1451 if (json)
1452 vty_out(vty, "{}\n");
1453 return;
1454 }
1455 wctx->zvni = zvni;
1456
1457 /*We are iterating over a new VNI, set the count to 0*/
1458 wctx->count = 0;
1459
1460 num_macs = num_valid_macs(zvni);
1461 if (!num_macs)
1462 return;
1463
1464 if (wctx->print_dup && (num_dup_detected_macs(zvni) == 0))
1465 return;
1466
1467 if (json) {
1468 json_vni = json_object_new_object();
1469 json_mac = json_object_new_object();
1470 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
1471 }
1472
1473 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
1474 if (json == NULL) {
1475 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
1476 zvni->vni, num_macs);
1477 } else
1478 json_object_int_add(json_vni, "numMacs", num_macs);
1479 }
1480 /* assign per-vni to wctx->json object to fill macs
1481 * under the vni. Re-assign primary json object to fill
1482 * next vni information.
1483 */
1484 wctx->json = json_mac;
1485 if (wctx->print_dup)
1486 hash_iterate(zvni->mac_table, zvni_print_dad_mac_hash_detail,
1487 wctx);
1488 else
1489 hash_iterate(zvni->mac_table, zvni_print_mac_hash_detail, wctx);
1490 wctx->json = json;
1491 if (json) {
1492 if (wctx->count)
1493 json_object_object_add(json_vni, "macs", json_mac);
1494 json_object_object_add(json, vni_str, json_vni);
1495 }
1496 }
1497
1498 static void zl3vni_print_nh_hash(struct hash_backet *backet, void *ctx)
1499 {
1500 struct nh_walk_ctx *wctx = NULL;
1501 struct vty *vty = NULL;
1502 struct json_object *json_vni = NULL;
1503 struct json_object *json_nh = NULL;
1504 zebra_neigh_t *n = NULL;
1505 char buf1[ETHER_ADDR_STRLEN];
1506 char buf2[INET6_ADDRSTRLEN];
1507
1508 wctx = (struct nh_walk_ctx *)ctx;
1509 vty = wctx->vty;
1510 json_vni = wctx->json;
1511 if (json_vni)
1512 json_nh = json_object_new_object();
1513 n = (zebra_neigh_t *)backet->data;
1514
1515 if (!json_vni) {
1516 vty_out(vty, "%-15s %-17s\n",
1517 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
1518 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1519 } else {
1520 json_object_string_add(json_nh, "nexthopIp",
1521 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1522 json_object_string_add(
1523 json_nh, "routerMac",
1524 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1525 json_object_object_add(json_vni,
1526 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
1527 json_nh);
1528 }
1529 }
1530
1531 static void zl3vni_print_nh_hash_all_vni(struct hash_backet *backet,
1532 void **args)
1533 {
1534 struct vty *vty = NULL;
1535 json_object *json = NULL;
1536 json_object *json_vni = NULL;
1537 zebra_l3vni_t *zl3vni = NULL;
1538 uint32_t num_nh = 0;
1539 struct nh_walk_ctx wctx;
1540 char vni_str[VNI_STR_LEN];
1541
1542 vty = (struct vty *)args[0];
1543 json = (struct json_object *)args[1];
1544
1545 zl3vni = (zebra_l3vni_t *)backet->data;
1546
1547 num_nh = hashcount(zl3vni->nh_table);
1548 if (!num_nh)
1549 return;
1550
1551 if (json) {
1552 json_vni = json_object_new_object();
1553 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1554 }
1555
1556 if (json == NULL) {
1557 vty_out(vty, "\nVNI %u #Next-Hops %u\n\n", zl3vni->vni, num_nh);
1558 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
1559 } else
1560 json_object_int_add(json_vni, "numNextHops", num_nh);
1561
1562 memset(&wctx, 0, sizeof(struct nh_walk_ctx));
1563 wctx.vty = vty;
1564 wctx.json = json_vni;
1565 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
1566 if (json)
1567 json_object_object_add(json, vni_str, json_vni);
1568 }
1569
1570 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet *backet,
1571 void **args)
1572 {
1573 struct vty *vty = NULL;
1574 json_object *json = NULL;
1575 json_object *json_vni = NULL;
1576 zebra_l3vni_t *zl3vni = NULL;
1577 uint32_t num_rmacs;
1578 struct rmac_walk_ctx wctx;
1579 char vni_str[VNI_STR_LEN];
1580
1581 vty = (struct vty *)args[0];
1582 json = (struct json_object *)args[1];
1583
1584 zl3vni = (zebra_l3vni_t *)backet->data;
1585
1586 num_rmacs = hashcount(zl3vni->rmac_table);
1587 if (!num_rmacs)
1588 return;
1589
1590 if (json) {
1591 json_vni = json_object_new_object();
1592 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1593 }
1594
1595 if (json == NULL) {
1596 vty_out(vty, "\nVNI %u #RMACs %u\n\n", zl3vni->vni, num_rmacs);
1597 vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
1598 } else
1599 json_object_int_add(json_vni, "numRmacs", num_rmacs);
1600
1601 /* assign per-vni to wctx->json object to fill macs
1602 * under the vni. Re-assign primary json object to fill
1603 * next vni information.
1604 */
1605 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
1606 wctx.vty = vty;
1607 wctx.json = json_vni;
1608 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
1609 if (json)
1610 json_object_object_add(json, vni_str, json_vni);
1611 }
1612
1613 static void zl3vni_print_rmac_hash(struct hash_backet *backet, void *ctx)
1614 {
1615 zebra_mac_t *zrmac = NULL;
1616 struct rmac_walk_ctx *wctx = NULL;
1617 struct vty *vty = NULL;
1618 struct json_object *json = NULL;
1619 struct json_object *json_rmac = NULL;
1620 char buf[ETHER_ADDR_STRLEN];
1621
1622 wctx = (struct rmac_walk_ctx *)ctx;
1623 vty = wctx->vty;
1624 json = wctx->json;
1625 if (json)
1626 json_rmac = json_object_new_object();
1627 zrmac = (zebra_mac_t *)backet->data;
1628
1629 if (!json) {
1630 vty_out(vty, "%-17s %-21s\n",
1631 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
1632 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1633 } else {
1634 json_object_string_add(
1635 json_rmac, "routerMac",
1636 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
1637 json_object_string_add(json_rmac, "vtepIp",
1638 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1639 json_object_object_add(
1640 json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
1641 json_rmac);
1642 }
1643 }
1644
1645 /* print a specific L3 VNI entry */
1646 static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
1647 {
1648 char buf[ETHER_ADDR_STRLEN];
1649 struct vty *vty = NULL;
1650 json_object *json = NULL;
1651 zebra_vni_t *zvni = NULL;
1652 json_object *json_vni_list = NULL;
1653 struct listnode *node = NULL, *nnode = NULL;
1654
1655 vty = ctx[0];
1656 json = ctx[1];
1657
1658 if (!json) {
1659 vty_out(vty, "VNI: %u\n", zl3vni->vni);
1660 vty_out(vty, " Type: %s\n", "L3");
1661 vty_out(vty, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
1662 vty_out(vty, " Local Vtep Ip: %s\n",
1663 inet_ntoa(zl3vni->local_vtep_ip));
1664 vty_out(vty, " Vxlan-Intf: %s\n",
1665 zl3vni_vxlan_if_name(zl3vni));
1666 vty_out(vty, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
1667 vty_out(vty, " State: %s\n", zl3vni_state2str(zl3vni));
1668 vty_out(vty, " VNI Filter: %s\n",
1669 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
1670 ? "prefix-routes-only"
1671 : "none");
1672 vty_out(vty, " Router MAC: %s\n",
1673 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
1674 vty_out(vty, " L2 VNIs: ");
1675 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni))
1676 vty_out(vty, "%u ", zvni->vni);
1677 vty_out(vty, "\n");
1678 } else {
1679 json_vni_list = json_object_new_array();
1680 json_object_int_add(json, "vni", zl3vni->vni);
1681 json_object_string_add(json, "type", "L3");
1682 json_object_string_add(json, "localVtepIp",
1683 inet_ntoa(zl3vni->local_vtep_ip));
1684 json_object_string_add(json, "vxlanIntf",
1685 zl3vni_vxlan_if_name(zl3vni));
1686 json_object_string_add(json, "sviIntf",
1687 zl3vni_svi_if_name(zl3vni));
1688 json_object_string_add(json, "state", zl3vni_state2str(zl3vni));
1689 json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
1690 json_object_string_add(
1691 json, "routerMac",
1692 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
1693 json_object_string_add(
1694 json, "vniFilter",
1695 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
1696 ? "prefix-routes-only"
1697 : "none");
1698 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni)) {
1699 json_object_array_add(json_vni_list,
1700 json_object_new_int(zvni->vni));
1701 }
1702 json_object_object_add(json, "l2Vnis", json_vni_list);
1703 }
1704 }
1705
1706 /*
1707 * Print a specific VNI entry.
1708 */
1709 static void zvni_print(zebra_vni_t *zvni, void **ctxt)
1710 {
1711 struct vty *vty;
1712 zebra_vtep_t *zvtep;
1713 uint32_t num_macs;
1714 uint32_t num_neigh;
1715 json_object *json = NULL;
1716 json_object *json_vtep_list = NULL;
1717 json_object *json_ip_str = NULL;
1718
1719 vty = ctxt[0];
1720 json = ctxt[1];
1721
1722 if (json == NULL) {
1723 vty_out(vty, "VNI: %u\n", zvni->vni);
1724 vty_out(vty, " Type: %s\n", "L2");
1725 vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zvni->vrf_id));
1726 } else {
1727 json_object_int_add(json, "vni", zvni->vni);
1728 json_object_string_add(json, "type", "L2");
1729 json_object_string_add(json, "vrf",
1730 vrf_id_to_name(zvni->vrf_id));
1731 }
1732
1733 if (!zvni->vxlan_if) { // unexpected
1734 if (json == NULL)
1735 vty_out(vty, " VxLAN interface: unknown\n");
1736 return;
1737 }
1738 num_macs = num_valid_macs(zvni);
1739 num_neigh = hashcount(zvni->neigh_table);
1740 if (json == NULL) {
1741 vty_out(vty, " VxLAN interface: %s\n", zvni->vxlan_if->name);
1742 vty_out(vty, " VxLAN ifIndex: %u\n", zvni->vxlan_if->ifindex);
1743 vty_out(vty, " Local VTEP IP: %s\n",
1744 inet_ntoa(zvni->local_vtep_ip));
1745 } else {
1746 json_object_string_add(json, "vxlanInterface",
1747 zvni->vxlan_if->name);
1748 json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
1749 json_object_string_add(json, "vtepIp",
1750 inet_ntoa(zvni->local_vtep_ip));
1751 json_object_string_add(json, "advertiseGatewayMacip",
1752 zvni->advertise_gw_macip ? "Yes" : "No");
1753 json_object_int_add(json, "numMacs", num_macs);
1754 json_object_int_add(json, "numArpNd", num_neigh);
1755 }
1756 if (!zvni->vteps) {
1757 if (json == NULL)
1758 vty_out(vty, " No remote VTEPs known for this VNI\n");
1759 } else {
1760 if (json == NULL)
1761 vty_out(vty, " Remote VTEPs for this VNI:\n");
1762 else
1763 json_vtep_list = json_object_new_array();
1764 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1765 if (json == NULL)
1766 vty_out(vty, " %s\n",
1767 inet_ntoa(zvtep->vtep_ip));
1768 else {
1769 json_ip_str = json_object_new_string(
1770 inet_ntoa(zvtep->vtep_ip));
1771 json_object_array_add(json_vtep_list,
1772 json_ip_str);
1773 }
1774 }
1775 if (json)
1776 json_object_object_add(json, "numRemoteVteps",
1777 json_vtep_list);
1778 }
1779 if (json == NULL) {
1780 vty_out(vty,
1781 " Number of MACs (local and remote) known for this VNI: %u\n",
1782 num_macs);
1783 vty_out(vty,
1784 " Number of ARPs (IPv4 and IPv6, local and remote) "
1785 "known for this VNI: %u\n",
1786 num_neigh);
1787 vty_out(vty, " Advertise-gw-macip: %s\n",
1788 zvni->advertise_gw_macip ? "Yes" : "No");
1789 }
1790 }
1791
1792 /* print a L3 VNI hash entry */
1793 static void zl3vni_print_hash(struct hash_backet *backet, void *ctx[])
1794 {
1795 struct vty *vty = NULL;
1796 json_object *json = NULL;
1797 json_object *json_vni = NULL;
1798 zebra_l3vni_t *zl3vni = NULL;
1799
1800 vty = (struct vty *)ctx[0];
1801 json = (json_object *)ctx[1];
1802
1803 zl3vni = (zebra_l3vni_t *)backet->data;
1804
1805 if (!json) {
1806 vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
1807 zl3vni->vni, "L3", zl3vni_vxlan_if_name(zl3vni),
1808 hashcount(zl3vni->rmac_table),
1809 hashcount(zl3vni->nh_table), "n/a",
1810 zl3vni_vrf_name(zl3vni));
1811 } else {
1812 char vni_str[VNI_STR_LEN];
1813
1814 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1815 json_vni = json_object_new_object();
1816 json_object_int_add(json_vni, "vni", zl3vni->vni);
1817 json_object_string_add(json_vni, "vxlanIf",
1818 zl3vni_vxlan_if_name(zl3vni));
1819 json_object_int_add(json_vni, "numMacs",
1820 hashcount(zl3vni->rmac_table));
1821 json_object_int_add(json_vni, "numArpNd",
1822 hashcount(zl3vni->nh_table));
1823 json_object_string_add(json_vni, "numRemoteVteps", "n/a");
1824 json_object_string_add(json_vni, "type", "L3");
1825 json_object_string_add(json_vni, "tenantVrf",
1826 zl3vni_vrf_name(zl3vni));
1827 json_object_object_add(json, vni_str, json_vni);
1828 }
1829 }
1830
1831 /*
1832 * Print a VNI hash entry - called for display of all VNIs.
1833 */
1834 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
1835 {
1836 struct vty *vty;
1837 zebra_vni_t *zvni;
1838 zebra_vtep_t *zvtep;
1839 uint32_t num_vteps = 0;
1840 uint32_t num_macs = 0;
1841 uint32_t num_neigh = 0;
1842 json_object *json = NULL;
1843 json_object *json_vni = NULL;
1844 json_object *json_ip_str = NULL;
1845 json_object *json_vtep_list = NULL;
1846
1847 vty = ctxt[0];
1848 json = ctxt[1];
1849
1850 zvni = (zebra_vni_t *)backet->data;
1851
1852 zvtep = zvni->vteps;
1853 while (zvtep) {
1854 num_vteps++;
1855 zvtep = zvtep->next;
1856 }
1857
1858 num_macs = num_valid_macs(zvni);
1859 num_neigh = hashcount(zvni->neigh_table);
1860 if (json == NULL)
1861 vty_out(vty, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
1862 zvni->vni, "L2",
1863 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
1864 num_macs, num_neigh, num_vteps,
1865 vrf_id_to_name(zvni->vrf_id));
1866 else {
1867 char vni_str[VNI_STR_LEN];
1868 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
1869 json_vni = json_object_new_object();
1870 json_object_int_add(json_vni, "vni", zvni->vni);
1871 json_object_string_add(json_vni, "type", "L2");
1872 json_object_string_add(json_vni, "vxlanIf",
1873 zvni->vxlan_if ? zvni->vxlan_if->name
1874 : "unknown");
1875 json_object_int_add(json_vni, "numMacs", num_macs);
1876 json_object_int_add(json_vni, "numArpNd", num_neigh);
1877 json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
1878 json_object_string_add(json_vni, "tenantVrf",
1879 vrf_id_to_name(zvni->vrf_id));
1880 if (num_vteps) {
1881 json_vtep_list = json_object_new_array();
1882 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1883 json_ip_str = json_object_new_string(
1884 inet_ntoa(zvtep->vtep_ip));
1885 json_object_array_add(json_vtep_list,
1886 json_ip_str);
1887 }
1888 json_object_object_add(json_vni, "remoteVteps",
1889 json_vtep_list);
1890 }
1891 json_object_object_add(json, vni_str, json_vni);
1892 }
1893 }
1894
1895 /*
1896 * Inform BGP about local MACIP.
1897 */
1898 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
1899 struct ipaddr *ip, uint8_t flags,
1900 uint32_t seq, uint16_t cmd)
1901 {
1902 char buf[ETHER_ADDR_STRLEN];
1903 char buf2[INET6_ADDRSTRLEN];
1904 int ipa_len;
1905 struct zserv *client = NULL;
1906 struct stream *s = NULL;
1907
1908 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
1909 /* BGP may not be running. */
1910 if (!client)
1911 return 0;
1912
1913 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1914
1915 zclient_create_header(s, cmd, VRF_DEFAULT);
1916 stream_putl(s, vni);
1917 stream_put(s, macaddr->octet, ETH_ALEN);
1918 if (ip) {
1919 ipa_len = 0;
1920 if (IS_IPADDR_V4(ip))
1921 ipa_len = IPV4_MAX_BYTELEN;
1922 else if (IS_IPADDR_V6(ip))
1923 ipa_len = IPV6_MAX_BYTELEN;
1924
1925 stream_putl(s, ipa_len); /* IP address length */
1926 if (ipa_len)
1927 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
1928 } else
1929 stream_putl(s, 0); /* Just MAC. */
1930
1931 if (cmd == ZEBRA_MACIP_ADD) {
1932 stream_putc(s, flags); /* sticky mac/gateway mac */
1933 stream_putl(s, seq); /* sequence number */
1934 }
1935
1936
1937 /* Write packet size. */
1938 stream_putw_at(s, 0, stream_get_endp(s));
1939
1940 if (IS_ZEBRA_DEBUG_VXLAN)
1941 zlog_debug(
1942 "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s",
1943 (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags,
1944 prefix_mac2str(macaddr, buf, sizeof(buf)),
1945 ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni,
1946 zebra_route_string(client->proto));
1947
1948 if (cmd == ZEBRA_MACIP_ADD)
1949 client->macipadd_cnt++;
1950 else
1951 client->macipdel_cnt++;
1952
1953 return zserv_send_message(client, s);
1954 }
1955
1956 /*
1957 * Make hash key for neighbors.
1958 */
1959 static unsigned int neigh_hash_keymake(void *p)
1960 {
1961 zebra_neigh_t *n = p;
1962 struct ipaddr *ip = &n->ip;
1963
1964 if (IS_IPADDR_V4(ip))
1965 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
1966
1967 return jhash2(ip->ipaddr_v6.s6_addr32,
1968 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
1969 }
1970
1971 /*
1972 * Compare two neighbor hash structures.
1973 */
1974 static bool neigh_cmp(const void *p1, const void *p2)
1975 {
1976 const zebra_neigh_t *n1 = p1;
1977 const zebra_neigh_t *n2 = p2;
1978
1979 if (n1 == NULL && n2 == NULL)
1980 return true;
1981
1982 if (n1 == NULL || n2 == NULL)
1983 return false;
1984
1985 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
1986 }
1987
1988 static int neigh_list_cmp(void *p1, void *p2)
1989 {
1990 const zebra_neigh_t *n1 = p1;
1991 const zebra_neigh_t *n2 = p2;
1992
1993 return memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr));
1994 }
1995
1996 /*
1997 * Callback to allocate neighbor hash entry.
1998 */
1999 static void *zvni_neigh_alloc(void *p)
2000 {
2001 const zebra_neigh_t *tmp_n = p;
2002 zebra_neigh_t *n;
2003
2004 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
2005 *n = *tmp_n;
2006
2007 return ((void *)n);
2008 }
2009
2010 /*
2011 * Add neighbor entry.
2012 */
2013 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
2014 struct ethaddr *mac)
2015 {
2016 zebra_neigh_t tmp_n;
2017 zebra_neigh_t *n = NULL;
2018 zebra_mac_t *zmac = NULL;
2019
2020 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
2021 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
2022 n = hash_get(zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
2023 assert(n);
2024
2025 memcpy(&n->emac, mac, ETH_ALEN);
2026 n->state = ZEBRA_NEIGH_INACTIVE;
2027
2028 /* Associate the neigh to mac */
2029 zmac = zvni_mac_lookup(zvni, mac);
2030 if (zmac)
2031 listnode_add_sort(zmac->neigh_list, n);
2032
2033 return n;
2034 }
2035
2036 /*
2037 * Delete neighbor entry.
2038 */
2039 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
2040 {
2041 zebra_neigh_t *tmp_n;
2042 zebra_mac_t *zmac = NULL;
2043
2044 zmac = zvni_mac_lookup(zvni, &n->emac);
2045 if (zmac)
2046 listnode_delete(zmac->neigh_list, n);
2047
2048 /* Free the VNI hash entry and allocated memory. */
2049 tmp_n = hash_release(zvni->neigh_table, n);
2050 if (tmp_n)
2051 XFREE(MTYPE_NEIGH, tmp_n);
2052
2053 return 0;
2054 }
2055
2056 /*
2057 * Free neighbor hash entry (callback)
2058 */
2059 static void zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
2060 {
2061 struct neigh_walk_ctx *wctx = arg;
2062 zebra_neigh_t *n = backet->data;
2063
2064 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
2065 || ((wctx->flags & DEL_REMOTE_NEIGH)
2066 && (n->flags & ZEBRA_NEIGH_REMOTE))
2067 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
2068 && (n->flags & ZEBRA_NEIGH_REMOTE)
2069 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
2070 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
2071 zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip,
2072 &n->emac, 0);
2073
2074 if (wctx->uninstall)
2075 zvni_neigh_uninstall(wctx->zvni, n);
2076
2077 zvni_neigh_del(wctx->zvni, n);
2078 }
2079
2080 return;
2081 }
2082
2083 /*
2084 * Delete all neighbor entries from specific VTEP for a particular VNI.
2085 */
2086 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
2087 struct in_addr *r_vtep_ip)
2088 {
2089 struct neigh_walk_ctx wctx;
2090
2091 if (!zvni->neigh_table)
2092 return;
2093
2094 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2095 wctx.zvni = zvni;
2096 wctx.uninstall = uninstall;
2097 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
2098 wctx.r_vtep_ip = *r_vtep_ip;
2099
2100 hash_iterate(zvni->neigh_table, zvni_neigh_del_hash_entry, &wctx);
2101 }
2102
2103 /*
2104 * Delete all neighbor entries for this VNI.
2105 */
2106 static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
2107 uint32_t flags)
2108 {
2109 struct neigh_walk_ctx wctx;
2110
2111 if (!zvni->neigh_table)
2112 return;
2113
2114 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2115 wctx.zvni = zvni;
2116 wctx.uninstall = uninstall;
2117 wctx.upd_client = upd_client;
2118 wctx.flags = flags;
2119
2120 hash_iterate(zvni->neigh_table, zvni_neigh_del_hash_entry, &wctx);
2121 }
2122
2123 /*
2124 * Look up neighbor hash entry.
2125 */
2126 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
2127 {
2128 zebra_neigh_t tmp;
2129 zebra_neigh_t *n;
2130
2131 memset(&tmp, 0, sizeof(tmp));
2132 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
2133 n = hash_lookup(zvni->neigh_table, &tmp);
2134
2135 return n;
2136 }
2137
2138 /*
2139 * Process all neighbors associated with a MAC upon the MAC being learnt
2140 * locally or undergoing any other change (such as sequence number).
2141 */
2142 static void zvni_process_neigh_on_local_mac_change(zebra_vni_t *zvni,
2143 zebra_mac_t *zmac,
2144 bool seq_change)
2145 {
2146 zebra_neigh_t *n = NULL;
2147 struct listnode *node = NULL;
2148 struct zebra_vrf *zvrf = NULL;
2149 char buf[ETHER_ADDR_STRLEN];
2150
2151 zvrf = vrf_info_lookup(zvni->vrf_id);
2152
2153 if (IS_ZEBRA_DEBUG_VXLAN)
2154 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
2155 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2156 seq_change ? "CHANGE" : "ADD", zvni->vni);
2157
2158 /* Walk all neighbors and mark any inactive local neighbors as
2159 * active and/or update sequence number upon a move, and inform BGP.
2160 * The action for remote neighbors is TBD.
2161 * NOTE: We can't simply uninstall remote neighbors as the kernel may
2162 * accidentally end up deleting a just-learnt local neighbor.
2163 */
2164 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2165 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2166 if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change) {
2167 ZEBRA_NEIGH_SET_ACTIVE(n);
2168 n->loc_seq = zmac->loc_seq;
2169 if (!(zvrf->dup_addr_detect &&
2170 zvrf->dad_freeze && !!CHECK_FLAG(n->flags,
2171 ZEBRA_NEIGH_DUPLICATE)))
2172 zvni_neigh_send_add_to_client(
2173 zvni->vni, &n->ip, &n->emac,
2174 n->flags, n->loc_seq);
2175 }
2176 }
2177 }
2178 }
2179
2180 /*
2181 * Process all neighbors associated with a local MAC upon the MAC being
2182 * deleted.
2183 */
2184 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
2185 zebra_mac_t *zmac)
2186 {
2187 zebra_neigh_t *n = NULL;
2188 struct listnode *node = NULL;
2189 char buf[ETHER_ADDR_STRLEN];
2190
2191 if (IS_ZEBRA_DEBUG_VXLAN)
2192 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
2193 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2194 zvni->vni);
2195
2196 /* Walk all local neighbors and mark as inactive and inform
2197 * BGP, if needed.
2198 * TBD: There is currently no handling for remote neighbors. We
2199 * don't expect them to exist, if they do, do we install the MAC
2200 * as a remote MAC and the neighbor as remote?
2201 */
2202 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2203 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2204 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
2205 ZEBRA_NEIGH_SET_INACTIVE(n);
2206 n->loc_seq = 0;
2207 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
2208 &n->emac, 0);
2209 }
2210 }
2211 }
2212 }
2213
2214 /*
2215 * Process all neighbors associated with a MAC upon the MAC being remotely
2216 * learnt.
2217 */
2218 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
2219 zebra_mac_t *zmac)
2220 {
2221 zebra_neigh_t *n = NULL;
2222 struct listnode *node = NULL;
2223 char buf[ETHER_ADDR_STRLEN];
2224
2225 if (IS_ZEBRA_DEBUG_VXLAN)
2226 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
2227 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2228 zvni->vni);
2229
2230 /* Walk all local neighbors and mark as inactive and inform
2231 * BGP, if needed.
2232 */
2233 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2234 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2235 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
2236 ZEBRA_NEIGH_SET_INACTIVE(n);
2237 n->loc_seq = 0;
2238 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
2239 &n->emac, 0);
2240 }
2241 }
2242 }
2243 }
2244
2245 /*
2246 * Process all neighbors associated with a remote MAC upon the MAC being
2247 * deleted.
2248 */
2249 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
2250 zebra_mac_t *zmac)
2251 {
2252 /* NOTE: Currently a NO-OP. */
2253 }
2254
2255 /*
2256 * Inform BGP about local neighbor addition.
2257 */
2258 static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
2259 struct ethaddr *macaddr,
2260 uint8_t neigh_flags,
2261 uint32_t seq)
2262 {
2263 uint8_t flags = 0;
2264
2265 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
2266 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
2267 /* Set router flag (R-bit) based on local neigh entry add */
2268 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
2269 SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
2270
2271 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
2272 seq, ZEBRA_MACIP_ADD);
2273 }
2274
2275 /*
2276 * Inform BGP about local neighbor deletion.
2277 */
2278 static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
2279 struct ethaddr *macaddr, uint8_t flags)
2280 {
2281 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
2282 0, ZEBRA_MACIP_DEL);
2283 }
2284
2285 /*
2286 * Install remote neighbor into the kernel.
2287 */
2288 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
2289 {
2290 struct zebra_if *zif;
2291 struct zebra_l2info_vxlan *vxl;
2292 struct interface *vlan_if;
2293 #ifdef GNU_LINUX
2294 uint8_t flags;
2295 #endif
2296 int ret = 0;
2297
2298 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2299 return 0;
2300
2301 zif = zvni->vxlan_if->info;
2302 if (!zif)
2303 return -1;
2304 vxl = &zif->l2info.vxl;
2305
2306 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2307 if (!vlan_if)
2308 return -1;
2309 #ifdef GNU_LINUX
2310 flags = NTF_EXT_LEARNED;
2311 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
2312 flags |= NTF_ROUTER;
2313 ZEBRA_NEIGH_SET_ACTIVE(n);
2314 ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
2315 #endif
2316 return ret;
2317 }
2318
2319 /*
2320 * Uninstall remote neighbor from the kernel.
2321 */
2322 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
2323 {
2324 struct zebra_if *zif;
2325 struct zebra_l2info_vxlan *vxl;
2326 struct interface *vlan_if;
2327
2328 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2329 return 0;
2330
2331 if (!zvni->vxlan_if) {
2332 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2333 zvni->vni, zvni);
2334 return -1;
2335 }
2336
2337 zif = zvni->vxlan_if->info;
2338 if (!zif)
2339 return -1;
2340 vxl = &zif->l2info.vxl;
2341 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2342 if (!vlan_if)
2343 return -1;
2344
2345 ZEBRA_NEIGH_SET_INACTIVE(n);
2346 n->loc_seq = 0;
2347 return kernel_del_neigh(vlan_if, &n->ip);
2348 }
2349
2350 /*
2351 * Install neighbor hash entry - called upon access VLAN change.
2352 */
2353 static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
2354 {
2355 zebra_neigh_t *n;
2356 struct neigh_walk_ctx *wctx = ctxt;
2357
2358 n = (zebra_neigh_t *)backet->data;
2359
2360 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2361 zvni_neigh_install(wctx->zvni, n);
2362 }
2363
2364 /* Get the VRR interface for SVI if any */
2365 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
2366 {
2367 struct zebra_vrf *zvrf = NULL;
2368 struct interface *tmp_if = NULL;
2369 struct zebra_if *zif = NULL;
2370
2371 zvrf = vrf_info_lookup(ifp->vrf_id);
2372 assert(zvrf);
2373
2374 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
2375 zif = tmp_if->info;
2376 if (!zif)
2377 continue;
2378
2379 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
2380 continue;
2381
2382 if (zif->link == ifp)
2383 return tmp_if;
2384 }
2385
2386 return NULL;
2387 }
2388
2389 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
2390 {
2391 struct listnode *cnode = NULL, *cnnode = NULL;
2392 struct connected *c = NULL;
2393 struct ethaddr macaddr;
2394
2395 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2396
2397 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2398 struct ipaddr ip;
2399
2400 memset(&ip, 0, sizeof(struct ipaddr));
2401 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2402 continue;
2403
2404 if (c->address->family == AF_INET) {
2405 ip.ipa_type = IPADDR_V4;
2406 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2407 sizeof(struct in_addr));
2408 } else if (c->address->family == AF_INET6) {
2409 ip.ipa_type = IPADDR_V6;
2410 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2411 sizeof(struct in6_addr));
2412 } else {
2413 continue;
2414 }
2415
2416 zvni_gw_macip_del(ifp, zvni, &ip);
2417 }
2418
2419 return 0;
2420 }
2421
2422 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
2423 {
2424 struct listnode *cnode = NULL, *cnnode = NULL;
2425 struct connected *c = NULL;
2426 struct ethaddr macaddr;
2427
2428 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2429
2430 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2431 struct ipaddr ip;
2432
2433 memset(&ip, 0, sizeof(struct ipaddr));
2434 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2435 continue;
2436
2437 if (c->address->family == AF_INET) {
2438 ip.ipa_type = IPADDR_V4;
2439 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2440 sizeof(struct in_addr));
2441 } else if (c->address->family == AF_INET6) {
2442 ip.ipa_type = IPADDR_V6;
2443 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2444 sizeof(struct in6_addr));
2445 } else {
2446 continue;
2447 }
2448
2449 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
2450 }
2451 return 0;
2452 }
2453
2454
2455 static int zvni_advertise_subnet(zebra_vni_t *zvni, struct interface *ifp,
2456 int advertise)
2457 {
2458 struct listnode *cnode = NULL, *cnnode = NULL;
2459 struct connected *c = NULL;
2460 struct ethaddr macaddr;
2461
2462 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2463
2464 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2465 struct prefix p;
2466
2467 memcpy(&p, c->address, sizeof(struct prefix));
2468
2469 /* skip link local address */
2470 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
2471 continue;
2472
2473 apply_mask(&p);
2474 if (advertise)
2475 ip_prefix_send_to_client(ifp->vrf_id, &p,
2476 ZEBRA_IP_PREFIX_ROUTE_ADD);
2477 else
2478 ip_prefix_send_to_client(ifp->vrf_id, &p,
2479 ZEBRA_IP_PREFIX_ROUTE_DEL);
2480 }
2481 return 0;
2482 }
2483
2484 /*
2485 * zvni_gw_macip_add_to_client
2486 */
2487 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
2488 struct ethaddr *macaddr, struct ipaddr *ip)
2489 {
2490 char buf[ETHER_ADDR_STRLEN];
2491 char buf2[INET6_ADDRSTRLEN];
2492 zebra_neigh_t *n = NULL;
2493 zebra_mac_t *mac = NULL;
2494 struct zebra_if *zif = NULL;
2495 struct zebra_l2info_vxlan *vxl = NULL;
2496
2497 zif = zvni->vxlan_if->info;
2498 if (!zif)
2499 return -1;
2500
2501 vxl = &zif->l2info.vxl;
2502
2503 mac = zvni_mac_lookup(zvni, macaddr);
2504 if (!mac) {
2505 mac = zvni_mac_add(zvni, macaddr);
2506 if (!mac) {
2507 flog_err(EC_ZEBRA_MAC_ADD_FAILED,
2508 "Failed to add MAC %s intf %s(%u) VID %u",
2509 prefix_mac2str(macaddr, buf, sizeof(buf)),
2510 ifp->name, ifp->ifindex, vxl->access_vlan);
2511 return -1;
2512 }
2513 }
2514
2515 /* Set "local" forwarding info. */
2516 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2517 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2518 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
2519 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2520 mac->fwd_info.local.ifindex = ifp->ifindex;
2521 mac->fwd_info.local.vid = vxl->access_vlan;
2522
2523 n = zvni_neigh_lookup(zvni, ip);
2524 if (!n) {
2525 n = zvni_neigh_add(zvni, ip, macaddr);
2526 if (!n) {
2527 flog_err(
2528 EC_ZEBRA_MAC_ADD_FAILED,
2529 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2530 ipaddr2str(ip, buf2, sizeof(buf2)),
2531 prefix_mac2str(macaddr, buf, sizeof(buf)),
2532 ifp->name, ifp->ifindex, zvni->vni);
2533 return -1;
2534 }
2535 }
2536
2537 /* Set "local" forwarding info. */
2538 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2539 SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
2540 ZEBRA_NEIGH_SET_ACTIVE(n);
2541 /* Set Router flag (R-bit) */
2542 if (ip->ipa_type == IPADDR_V6)
2543 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2544 memcpy(&n->emac, macaddr, ETH_ALEN);
2545 n->ifindex = ifp->ifindex;
2546
2547 /* Only advertise in BGP if the knob is enabled */
2548 if (!advertise_gw_macip_enabled(zvni))
2549 return 0;
2550
2551 if (IS_ZEBRA_DEBUG_VXLAN)
2552 zlog_debug(
2553 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
2554 ifp->name, ifp->ifindex, zvni->vni,
2555 prefix_mac2str(macaddr, buf, sizeof(buf)),
2556 ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
2557
2558 zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
2559 n->flags, n->loc_seq);
2560
2561 return 0;
2562 }
2563
2564 /*
2565 * zvni_gw_macip_del_from_client
2566 */
2567 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
2568 struct ipaddr *ip)
2569 {
2570 char buf1[ETHER_ADDR_STRLEN];
2571 char buf2[INET6_ADDRSTRLEN];
2572 zebra_neigh_t *n = NULL;
2573 zebra_mac_t *mac = NULL;
2574
2575 /* If the neigh entry is not present nothing to do*/
2576 n = zvni_neigh_lookup(zvni, ip);
2577 if (!n)
2578 return 0;
2579
2580 /* mac entry should be present */
2581 mac = zvni_mac_lookup(zvni, &n->emac);
2582 if (!mac) {
2583 zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u",
2584 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
2585 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
2586 return -1;
2587 }
2588
2589 /* If the entry is not local nothing to do*/
2590 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
2591 return -1;
2592
2593 /* only need to delete the entry from bgp if we sent it before */
2594 if (IS_ZEBRA_DEBUG_VXLAN)
2595 zlog_debug(
2596 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
2597 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
2598 prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
2599 ipaddr2str(ip, buf2, sizeof(buf2)));
2600
2601 /* Remove neighbor from BGP. */
2602 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
2603 ZEBRA_MACIP_TYPE_GW);
2604
2605 /* Delete this neighbor entry. */
2606 zvni_neigh_del(zvni, n);
2607
2608 /* see if the mac needs to be deleted as well*/
2609 if (mac)
2610 zvni_deref_ip2mac(zvni, mac);
2611
2612 return 0;
2613 }
2614
2615 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
2616 void *ctxt)
2617 {
2618 zebra_vni_t *zvni = NULL;
2619 struct zebra_if *zif = NULL;
2620 struct zebra_l2info_vxlan zl2_info;
2621 struct interface *vlan_if = NULL;
2622 struct interface *vrr_if = NULL;
2623 struct interface *ifp;
2624
2625 /* Add primary SVI MAC*/
2626 zvni = (zebra_vni_t *)backet->data;
2627
2628 ifp = zvni->vxlan_if;
2629 if (!ifp)
2630 return;
2631 zif = ifp->info;
2632
2633 /* If down or not mapped to a bridge, we're done. */
2634 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
2635 return;
2636
2637 zl2_info = zif->l2info.vxl;
2638
2639 vlan_if =
2640 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
2641 if (!vlan_if)
2642 return;
2643
2644 /* Del primary MAC-IP */
2645 zvni_del_macip_for_intf(vlan_if, zvni);
2646
2647 /* Del VRR MAC-IP - if any*/
2648 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2649 if (vrr_if)
2650 zvni_del_macip_for_intf(vrr_if, zvni);
2651
2652 return;
2653 }
2654
2655 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
2656 void *ctxt)
2657 {
2658 zebra_vni_t *zvni = NULL;
2659 struct zebra_if *zif = NULL;
2660 struct zebra_l2info_vxlan zl2_info;
2661 struct interface *vlan_if = NULL;
2662 struct interface *vrr_if = NULL;
2663 struct interface *ifp = NULL;
2664
2665 zvni = (zebra_vni_t *)backet->data;
2666
2667 ifp = zvni->vxlan_if;
2668 if (!ifp)
2669 return;
2670 zif = ifp->info;
2671
2672 /* If down or not mapped to a bridge, we're done. */
2673 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
2674 return;
2675 zl2_info = zif->l2info.vxl;
2676
2677 vlan_if =
2678 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
2679 if (!vlan_if)
2680 return;
2681
2682 /* Add primary SVI MAC-IP */
2683 zvni_add_macip_for_intf(vlan_if, zvni);
2684
2685 /* Add VRR MAC-IP - if any*/
2686 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2687 if (vrr_if)
2688 zvni_add_macip_for_intf(vrr_if, zvni);
2689
2690 return;
2691 }
2692
2693 static int zvni_local_neigh_update(zebra_vni_t *zvni,
2694 struct interface *ifp,
2695 struct ipaddr *ip,
2696 struct ethaddr *macaddr,
2697 bool is_router)
2698 {
2699 char buf[ETHER_ADDR_STRLEN];
2700 char buf2[INET6_ADDRSTRLEN];
2701 struct zebra_vrf *zvrf;
2702 zebra_neigh_t *n = NULL;
2703 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
2704 uint32_t old_mac_seq = 0, mac_new_seq = 0;
2705 bool upd_mac_seq = false;
2706 bool neigh_mac_change = false;
2707 bool neigh_on_hold = false;
2708 bool neigh_was_remote = false;
2709 bool do_dad = false;
2710 struct in_addr vtep_ip = {.s_addr = 0};
2711
2712 /* Check if the MAC exists. */
2713 zmac = zvni_mac_lookup(zvni, macaddr);
2714 if (!zmac) {
2715 /* create a dummy MAC if the MAC is not already present */
2716 if (IS_ZEBRA_DEBUG_VXLAN)
2717 zlog_debug(
2718 "AUTO MAC %s created for neigh %s on VNI %u",
2719 prefix_mac2str(macaddr, buf, sizeof(buf)),
2720 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
2721
2722 zmac = zvni_mac_add(zvni, macaddr);
2723 if (!zmac) {
2724 zlog_debug("Failed to add MAC %s VNI %u",
2725 prefix_mac2str(macaddr, buf, sizeof(buf)),
2726 zvni->vni);
2727 return -1;
2728 }
2729
2730 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
2731 memset(&zmac->flags, 0, sizeof(uint32_t));
2732 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
2733 } else {
2734 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
2735 /*
2736 * We don't change the MAC to local upon a neighbor
2737 * learn event, we wait for the explicit local MAC
2738 * learn. However, we have to compute its sequence
2739 * number in preparation for when it actually turns
2740 * local.
2741 */
2742 upd_mac_seq = true;
2743 }
2744 }
2745
2746 zvrf = vrf_info_lookup(zvni->vrf_id);
2747 if (!zvrf)
2748 return -1;
2749
2750 /* Check if the neighbor exists. */
2751 n = zvni_neigh_lookup(zvni, ip);
2752 if (!n) {
2753 /* New neighbor - create */
2754 n = zvni_neigh_add(zvni, ip, macaddr);
2755 if (!n) {
2756 flog_err(
2757 EC_ZEBRA_MAC_ADD_FAILED,
2758 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2759 ipaddr2str(ip, buf2, sizeof(buf2)),
2760 prefix_mac2str(macaddr, buf, sizeof(buf)),
2761 ifp->name, ifp->ifindex, zvni->vni);
2762 return -1;
2763 }
2764 /* Set "local" forwarding info. */
2765 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2766 n->ifindex = ifp->ifindex;
2767 } else {
2768 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2769 bool mac_different;
2770 bool cur_is_router;
2771
2772 /* Note any changes and see if of interest to BGP. */
2773 mac_different = (memcmp(n->emac.octet,
2774 macaddr->octet, ETH_ALEN) != 0) ? 1 : 0;
2775 cur_is_router = !!CHECK_FLAG(n->flags,
2776 ZEBRA_NEIGH_ROUTER_FLAG);
2777 if (!mac_different && is_router == cur_is_router) {
2778 n->ifindex = ifp->ifindex;
2779 return 0;
2780 }
2781
2782 if (!mac_different) {
2783 bool is_neigh_freezed = false;
2784
2785 /* Only the router flag has changed. */
2786 if (is_router)
2787 SET_FLAG(n->flags,
2788 ZEBRA_NEIGH_ROUTER_FLAG);
2789 else
2790 UNSET_FLAG(n->flags,
2791 ZEBRA_NEIGH_ROUTER_FLAG);
2792
2793 /* Neigh is in freeze state and freeze action
2794 * is enabled, do not send update to client.
2795 */
2796 is_neigh_freezed = (zvrf->dup_addr_detect &&
2797 zvrf->dad_freeze &&
2798 CHECK_FLAG(n->flags,
2799 ZEBRA_NEIGH_DUPLICATE));
2800
2801 if (IS_ZEBRA_NEIGH_ACTIVE(n) &&
2802 !is_neigh_freezed)
2803 return zvni_neigh_send_add_to_client(
2804 zvni->vni, ip, macaddr,
2805 n->flags, n->loc_seq);
2806 return 0;
2807 }
2808
2809 /* The MAC has changed, need to issue a delete
2810 * first as this means a different MACIP route.
2811 * Also, need to do some unlinking/relinking.
2812 * We also need to update the MAC's sequence number
2813 * in different situations.
2814 */
2815 if (IS_ZEBRA_NEIGH_ACTIVE(n))
2816 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
2817 &n->emac, 0);
2818 old_zmac = zvni_mac_lookup(zvni, &n->emac);
2819 if (old_zmac) {
2820 old_mac_seq = CHECK_FLAG(old_zmac->flags,
2821 ZEBRA_MAC_REMOTE) ?
2822 old_zmac->rem_seq : old_zmac->loc_seq;
2823 neigh_mac_change = upd_mac_seq = true;
2824 listnode_delete(old_zmac->neigh_list, n);
2825 zvni_deref_ip2mac(zvni, old_zmac);
2826 }
2827
2828 /* Update the forwarding info. */
2829 n->ifindex = ifp->ifindex;
2830 memcpy(&n->emac, macaddr, ETH_ALEN);
2831
2832 /* Link to new MAC */
2833 listnode_add_sort(zmac->neigh_list, n);
2834 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2835 /*
2836 * Neighbor has moved from remote to local. Its
2837 * MAC could have also changed as part of the move.
2838 */
2839 if (memcmp(n->emac.octet, macaddr->octet,
2840 ETH_ALEN) != 0) {
2841 old_zmac = zvni_mac_lookup(zvni, &n->emac);
2842 if (old_zmac) {
2843 old_mac_seq = CHECK_FLAG(
2844 old_zmac->flags,
2845 ZEBRA_MAC_REMOTE) ?
2846 old_zmac->rem_seq :
2847 old_zmac->loc_seq;
2848 neigh_mac_change = upd_mac_seq = true;
2849 listnode_delete(old_zmac->neigh_list,
2850 n);
2851 zvni_deref_ip2mac(zvni, old_zmac);
2852 }
2853
2854 /* Link to new MAC */
2855 memcpy(&n->emac, macaddr, ETH_ALEN);
2856 listnode_add_sort(zmac->neigh_list, n);
2857 }
2858 /* Based on Mobility event Scenario-B from the
2859 * draft, neigh's previous state was remote treat this
2860 * event for DAD.
2861 */
2862 neigh_was_remote = true;
2863 vtep_ip = n->r_vtep_ip;
2864 /* Mark appropriately */
2865 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2866 n->r_vtep_ip.s_addr = 0;
2867 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2868 n->ifindex = ifp->ifindex;
2869 }
2870 }
2871
2872 /* If MAC was previously remote, or the neighbor had a different
2873 * MAC earlier, recompute the sequence number.
2874 */
2875 if (upd_mac_seq) {
2876 uint32_t seq1, seq2;
2877
2878 seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ?
2879 zmac->rem_seq + 1 : zmac->loc_seq;
2880 seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
2881 mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ?
2882 MAX(seq1, seq2) : zmac->loc_seq;
2883 }
2884
2885 /* Mark Router flag (R-bit) */
2886 if (is_router)
2887 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2888 else
2889 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2890
2891 /* Check old and/or new MAC detected as duplicate mark
2892 * the neigh as duplicate
2893 */
2894 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
2895 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
2896 "VNI %u: MAC %s IP %s detected as duplicate during local update, inherit duplicate from MAC",
2897 zvni->vni,
2898 prefix_mac2str(macaddr, buf, sizeof(buf)),
2899 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
2900 }
2901
2902 /* For IP Duplicate Address Detection (DAD) is trigger,
2903 * when the event is extended mobility based on scenario-B
2904 * from the draft, IP/Neigh's MAC binding changed and
2905 * neigh's previous state was remote.
2906 */
2907 if (neigh_mac_change && neigh_was_remote)
2908 do_dad = true;
2909
2910 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
2911 &neigh_on_hold, true);
2912
2913 /* Before we program this in BGP, we need to check if MAC is locally
2914 * learnt. If not, force neighbor to be inactive and reset its seq.
2915 */
2916 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
2917 ZEBRA_NEIGH_SET_INACTIVE(n);
2918 n->loc_seq = 0;
2919 zmac->loc_seq = mac_new_seq;
2920 return 0;
2921 }
2922
2923 /* If the MAC's sequence number has changed, inform the MAC and all
2924 * neighbors associated with the MAC to BGP, else just inform this
2925 * neighbor.
2926 */
2927 if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
2928 if (IS_ZEBRA_DEBUG_VXLAN)
2929 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
2930 prefix_mac2str(macaddr, buf, sizeof(buf)),
2931 zvni->vni, zmac->loc_seq, mac_new_seq);
2932 zmac->loc_seq = mac_new_seq;
2933 if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
2934 zmac->flags, zmac->loc_seq))
2935 return -1;
2936 zvni_process_neigh_on_local_mac_change(zvni, zmac, 1);
2937 return 0;
2938 }
2939
2940 ZEBRA_NEIGH_SET_ACTIVE(n);
2941 n->loc_seq = zmac->loc_seq;
2942
2943 if (!neigh_on_hold)
2944 return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
2945 n->flags, n->loc_seq);
2946 return 0;
2947 }
2948
2949 static int zvni_remote_neigh_update(zebra_vni_t *zvni,
2950 struct interface *ifp,
2951 struct ipaddr *ip,
2952 struct ethaddr *macaddr,
2953 uint16_t state)
2954 {
2955 char buf[ETHER_ADDR_STRLEN];
2956 char buf2[INET6_ADDRSTRLEN];
2957 zebra_neigh_t *n = NULL;
2958 zebra_mac_t *zmac = NULL;
2959
2960 /* If the neighbor is unknown, there is no further action. */
2961 n = zvni_neigh_lookup(zvni, ip);
2962 if (!n)
2963 return 0;
2964
2965 /* If a remote entry, see if it needs to be refreshed */
2966 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2967 #ifdef GNU_LINUX
2968 if (state & NUD_STALE)
2969 zvni_neigh_install(zvni, n);
2970 #endif
2971 } else {
2972 /* We got a "remote" neighbor notification for an entry
2973 * we think is local. This can happen in a multihoming
2974 * scenario - but only if the MAC is already "remote".
2975 * Just mark our entry as "remote".
2976 */
2977 zmac = zvni_mac_lookup(zvni, macaddr);
2978 if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
2979 zlog_debug(
2980 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
2981 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
2982 prefix_mac2str(macaddr, buf, sizeof(buf)),
2983 zvni->vni);
2984 return -1;
2985 }
2986
2987 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2988 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2989 ZEBRA_NEIGH_SET_ACTIVE(n);
2990 n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
2991 }
2992
2993 return 0;
2994 }
2995
2996 /*
2997 * Make hash key for MAC.
2998 */
2999 static unsigned int mac_hash_keymake(void *p)
3000 {
3001 zebra_mac_t *pmac = p;
3002 const void *pnt = (void *)pmac->macaddr.octet;
3003
3004 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
3005 }
3006
3007 /*
3008 * Compare two MAC addresses.
3009 */
3010 static bool mac_cmp(const void *p1, const void *p2)
3011 {
3012 const zebra_mac_t *pmac1 = p1;
3013 const zebra_mac_t *pmac2 = p2;
3014
3015 if (pmac1 == NULL && pmac2 == NULL)
3016 return true;
3017
3018 if (pmac1 == NULL || pmac2 == NULL)
3019 return false;
3020
3021 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN)
3022 == 0);
3023 }
3024
3025 /*
3026 * Callback to allocate MAC hash entry.
3027 */
3028 static void *zvni_mac_alloc(void *p)
3029 {
3030 const zebra_mac_t *tmp_mac = p;
3031 zebra_mac_t *mac;
3032
3033 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
3034 *mac = *tmp_mac;
3035
3036 return ((void *)mac);
3037 }
3038
3039 /*
3040 * Add MAC entry.
3041 */
3042 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
3043 {
3044 zebra_mac_t tmp_mac;
3045 zebra_mac_t *mac = NULL;
3046
3047 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
3048 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
3049 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
3050 assert(mac);
3051
3052 mac->neigh_list = list_new();
3053 mac->neigh_list->cmp = neigh_list_cmp;
3054
3055 return mac;
3056 }
3057
3058 /*
3059 * Delete MAC entry.
3060 */
3061 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
3062 {
3063 zebra_mac_t *tmp_mac;
3064
3065 list_delete(&mac->neigh_list);
3066
3067 /* Free the VNI hash entry and allocated memory. */
3068 tmp_mac = hash_release(zvni->mac_table, mac);
3069 if (tmp_mac)
3070 XFREE(MTYPE_MAC, tmp_mac);
3071
3072 return 0;
3073 }
3074
3075 /*
3076 * Free MAC hash entry (callback)
3077 */
3078 static void zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
3079 {
3080 struct mac_walk_ctx *wctx = arg;
3081 zebra_mac_t *mac = backet->data;
3082
3083 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
3084 || ((wctx->flags & DEL_REMOTE_MAC)
3085 && (mac->flags & ZEBRA_MAC_REMOTE))
3086 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
3087 && (mac->flags & ZEBRA_MAC_REMOTE)
3088 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
3089 &wctx->r_vtep_ip))) {
3090 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
3091 zvni_mac_send_del_to_client(wctx->zvni->vni,
3092 &mac->macaddr);
3093 }
3094
3095 if (wctx->uninstall)
3096 zvni_mac_uninstall(wctx->zvni, mac);
3097
3098 zvni_mac_del(wctx->zvni, mac);
3099 }
3100
3101 return;
3102 }
3103
3104 /*
3105 * Delete all MAC entries from specific VTEP for a particular VNI.
3106 */
3107 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
3108 struct in_addr *r_vtep_ip)
3109 {
3110 struct mac_walk_ctx wctx;
3111
3112 if (!zvni->mac_table)
3113 return;
3114
3115 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
3116 wctx.zvni = zvni;
3117 wctx.uninstall = uninstall;
3118 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
3119 wctx.r_vtep_ip = *r_vtep_ip;
3120
3121 hash_iterate(zvni->mac_table, zvni_mac_del_hash_entry, &wctx);
3122 }
3123
3124 /*
3125 * Delete all MAC entries for this VNI.
3126 */
3127 static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
3128 uint32_t flags)
3129 {
3130 struct mac_walk_ctx wctx;
3131
3132 if (!zvni->mac_table)
3133 return;
3134
3135 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
3136 wctx.zvni = zvni;
3137 wctx.uninstall = uninstall;
3138 wctx.upd_client = upd_client;
3139 wctx.flags = flags;
3140
3141 hash_iterate(zvni->mac_table, zvni_mac_del_hash_entry, &wctx);
3142 }
3143
3144 /*
3145 * Look up MAC hash entry.
3146 */
3147 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
3148 {
3149 zebra_mac_t tmp;
3150 zebra_mac_t *pmac;
3151
3152 memset(&tmp, 0, sizeof(tmp));
3153 memcpy(&tmp.macaddr, mac, ETH_ALEN);
3154 pmac = hash_lookup(zvni->mac_table, &tmp);
3155
3156 return pmac;
3157 }
3158
3159 /*
3160 * Inform BGP about local MAC addition.
3161 */
3162 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
3163 uint8_t mac_flags, uint32_t seq)
3164 {
3165 uint8_t flags = 0;
3166
3167 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
3168 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
3169 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
3170 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
3171
3172 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
3173 seq, ZEBRA_MACIP_ADD);
3174 }
3175
3176 /*
3177 * Inform BGP about local MAC deletion.
3178 */
3179 static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
3180 {
3181 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
3182 0 /* seq */, ZEBRA_MACIP_DEL);
3183 }
3184
3185 /*
3186 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
3187 * notifications, to see if they are of interest.
3188 */
3189 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
3190 struct interface *br_if, vlanid_t vid)
3191 {
3192 struct zebra_ns *zns;
3193 struct route_node *rn;
3194 struct interface *tmp_if = NULL;
3195 struct zebra_if *zif;
3196 struct zebra_l2info_bridge *br;
3197 struct zebra_l2info_vxlan *vxl = NULL;
3198 uint8_t bridge_vlan_aware;
3199 zebra_vni_t *zvni;
3200 int found = 0;
3201
3202 /* Determine if bridge is VLAN-aware or not */
3203 zif = br_if->info;
3204 assert(zif);
3205 br = &zif->l2info.br;
3206 bridge_vlan_aware = br->vlan_aware;
3207
3208 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3209 /* TODO: Optimize with a hash. */
3210 zns = zebra_ns_lookup(NS_DEFAULT);
3211 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3212 tmp_if = (struct interface *)rn->info;
3213 if (!tmp_if)
3214 continue;
3215 zif = tmp_if->info;
3216 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3217 continue;
3218 if (!if_is_operative(tmp_if))
3219 continue;
3220 vxl = &zif->l2info.vxl;
3221
3222 if (zif->brslave_info.br_if != br_if)
3223 continue;
3224
3225 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3226 found = 1;
3227 break;
3228 }
3229 }
3230
3231 if (!found)
3232 return NULL;
3233
3234 zvni = zvni_lookup(vxl->vni);
3235 return zvni;
3236 }
3237
3238 /*
3239 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3240 * neighbor notifications, to see if they are of interest.
3241 */
3242 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
3243 struct interface *br_if)
3244 {
3245 struct zebra_ns *zns;
3246 struct route_node *rn;
3247 struct interface *tmp_if = NULL;
3248 struct zebra_if *zif;
3249 struct zebra_l2info_bridge *br;
3250 struct zebra_l2info_vxlan *vxl = NULL;
3251 uint8_t bridge_vlan_aware;
3252 vlanid_t vid = 0;
3253 zebra_vni_t *zvni;
3254 int found = 0;
3255
3256 if (!br_if)
3257 return NULL;
3258
3259 /* Make sure the linked interface is a bridge. */
3260 if (!IS_ZEBRA_IF_BRIDGE(br_if))
3261 return NULL;
3262
3263 /* Determine if bridge is VLAN-aware or not */
3264 zif = br_if->info;
3265 assert(zif);
3266 br = &zif->l2info.br;
3267 bridge_vlan_aware = br->vlan_aware;
3268 if (bridge_vlan_aware) {
3269 struct zebra_l2info_vlan *vl;
3270
3271 if (!IS_ZEBRA_IF_VLAN(ifp))
3272 return NULL;
3273
3274 zif = ifp->info;
3275 assert(zif);
3276 vl = &zif->l2info.vl;
3277 vid = vl->vid;
3278 }
3279
3280 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3281 /* TODO: Optimize with a hash. */
3282 zns = zebra_ns_lookup(NS_DEFAULT);
3283 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3284 tmp_if = (struct interface *)rn->info;
3285 if (!tmp_if)
3286 continue;
3287 zif = tmp_if->info;
3288 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3289 continue;
3290 if (!if_is_operative(tmp_if))
3291 continue;
3292 vxl = &zif->l2info.vxl;
3293
3294 if (zif->brslave_info.br_if != br_if)
3295 continue;
3296
3297 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3298 found = 1;
3299 break;
3300 }
3301 }
3302
3303 if (!found)
3304 return NULL;
3305
3306 zvni = zvni_lookup(vxl->vni);
3307 return zvni;
3308 }
3309
3310 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
3311 * of two cases:
3312 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
3313 * linked to the bridge
3314 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
3315 * itself
3316 */
3317 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
3318 {
3319 struct zebra_ns *zns;
3320 struct route_node *rn;
3321 struct interface *tmp_if = NULL;
3322 struct zebra_if *zif;
3323 struct zebra_l2info_bridge *br;
3324 struct zebra_l2info_vlan *vl;
3325 uint8_t bridge_vlan_aware;
3326 int found = 0;
3327
3328 /* Defensive check, caller expected to invoke only with valid bridge. */
3329 if (!br_if)
3330 return NULL;
3331
3332 /* Determine if bridge is VLAN-aware or not */
3333 zif = br_if->info;
3334 assert(zif);
3335 br = &zif->l2info.br;
3336 bridge_vlan_aware = br->vlan_aware;
3337
3338 /* Check oper status of the SVI. */
3339 if (!bridge_vlan_aware)
3340 return if_is_operative(br_if) ? br_if : NULL;
3341
3342 /* Identify corresponding VLAN interface. */
3343 /* TODO: Optimize with a hash. */
3344 zns = zebra_ns_lookup(NS_DEFAULT);
3345 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3346 tmp_if = (struct interface *)rn->info;
3347 /* Check oper status of the SVI. */
3348 if (!tmp_if || !if_is_operative(tmp_if))
3349 continue;
3350 zif = tmp_if->info;
3351 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
3352 || zif->link != br_if)
3353 continue;
3354 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
3355
3356 if (vl->vid == vid) {
3357 found = 1;
3358 break;
3359 }
3360 }
3361
3362 return found ? tmp_if : NULL;
3363 }
3364
3365 /*
3366 * Install remote MAC into the kernel.
3367 */
3368 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
3369 {
3370 struct zebra_if *zif;
3371 struct zebra_l2info_vxlan *vxl;
3372 bool sticky;
3373
3374 if (!(mac->flags & ZEBRA_MAC_REMOTE))
3375 return 0;
3376
3377 zif = zvni->vxlan_if->info;
3378 if (!zif)
3379 return -1;
3380 vxl = &zif->l2info.vxl;
3381
3382 sticky = !!CHECK_FLAG(mac->flags,
3383 (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
3384
3385 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
3386 mac->fwd_info.r_vtep_ip, sticky);
3387 }
3388
3389 /*
3390 * Uninstall remote MAC from the kernel.
3391 */
3392 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac)
3393 {
3394 struct zebra_if *zif;
3395 struct zebra_l2info_vxlan *vxl;
3396 struct in_addr vtep_ip;
3397 struct interface *ifp;
3398
3399 if (!(mac->flags & ZEBRA_MAC_REMOTE))
3400 return 0;
3401
3402 if (!zvni->vxlan_if) {
3403 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3404 zvni->vni, zvni);
3405 return -1;
3406 }
3407
3408 zif = zvni->vxlan_if->info;
3409 if (!zif)
3410 return -1;
3411 vxl = &zif->l2info.vxl;
3412
3413 ifp = zvni->vxlan_if;
3414 vtep_ip = mac->fwd_info.r_vtep_ip;
3415
3416 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip);
3417 }
3418
3419 /*
3420 * Install MAC hash entry - called upon access VLAN change.
3421 */
3422 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
3423 {
3424 zebra_mac_t *mac;
3425 struct mac_walk_ctx *wctx = ctxt;
3426
3427 mac = (zebra_mac_t *)backet->data;
3428
3429 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
3430 zvni_mac_install(wctx->zvni, mac);
3431 }
3432
3433 /*
3434 * Count of remote neighbors referencing this MAC.
3435 */
3436 static int remote_neigh_count(zebra_mac_t *zmac)
3437 {
3438 zebra_neigh_t *n = NULL;
3439 struct listnode *node = NULL;
3440 int count = 0;
3441
3442 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
3443 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
3444 count++;
3445 }
3446
3447 return count;
3448 }
3449
3450 /*
3451 * Decrement neighbor refcount of MAC; uninstall and free it if
3452 * appropriate.
3453 */
3454 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac)
3455 {
3456 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
3457 return;
3458
3459 /* If all remote neighbors referencing a remote MAC go away,
3460 * we need to uninstall the MAC.
3461 */
3462 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
3463 remote_neigh_count(mac) == 0) {
3464 zvni_mac_uninstall(zvni, mac);
3465 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3466 }
3467
3468 /* If no neighbors, delete the MAC. */
3469 if (list_isempty(mac->neigh_list))
3470 zvni_mac_del(zvni, mac);
3471 }
3472
3473 /*
3474 * Read and populate local MACs and neighbors corresponding to this VNI.
3475 */
3476 static void zvni_read_mac_neigh(zebra_vni_t *zvni, struct interface *ifp)
3477 {
3478 struct zebra_ns *zns;
3479 struct zebra_if *zif;
3480 struct interface *vlan_if;
3481 struct zebra_l2info_vxlan *vxl;
3482 struct interface *vrr_if;
3483
3484 zif = ifp->info;
3485 vxl = &zif->l2info.vxl;
3486 zns = zebra_ns_lookup(NS_DEFAULT);
3487
3488 if (IS_ZEBRA_DEBUG_VXLAN)
3489 zlog_debug(
3490 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
3491 ifp->name, ifp->ifindex, zvni->vni,
3492 zif->brslave_info.bridge_ifindex);
3493
3494 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
3495 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
3496 if (vlan_if) {
3497
3498 /* Add SVI MAC-IP */
3499 zvni_add_macip_for_intf(vlan_if, zvni);
3500
3501 /* Add VRR MAC-IP - if any*/
3502 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
3503 if (vrr_if)
3504 zvni_add_macip_for_intf(vrr_if, zvni);
3505
3506 neigh_read_for_vlan(zns, vlan_if);
3507 }
3508 }
3509
3510 /*
3511 * Hash function for VNI.
3512 */
3513 static unsigned int vni_hash_keymake(void *p)
3514 {
3515 const zebra_vni_t *zvni = p;
3516
3517 return (jhash_1word(zvni->vni, 0));
3518 }
3519
3520 /*
3521 * Compare 2 VNI hash entries.
3522 */
3523 static bool vni_hash_cmp(const void *p1, const void *p2)
3524 {
3525 const zebra_vni_t *zvni1 = p1;
3526 const zebra_vni_t *zvni2 = p2;
3527
3528 return (zvni1->vni == zvni2->vni);
3529 }
3530
3531 static int vni_list_cmp(void *p1, void *p2)
3532 {
3533 const zebra_vni_t *zvni1 = p1;
3534 const zebra_vni_t *zvni2 = p2;
3535
3536 if (zvni1->vni == zvni2->vni)
3537 return 0;
3538 return (zvni1->vni < zvni2->vni) ? -1 : 1;
3539 }
3540
3541 /*
3542 * Callback to allocate VNI hash entry.
3543 */
3544 static void *zvni_alloc(void *p)
3545 {
3546 const zebra_vni_t *tmp_vni = p;
3547 zebra_vni_t *zvni;
3548
3549 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
3550 zvni->vni = tmp_vni->vni;
3551 return ((void *)zvni);
3552 }
3553
3554 /*
3555 * Look up VNI hash entry.
3556 */
3557 static zebra_vni_t *zvni_lookup(vni_t vni)
3558 {
3559 struct zebra_vrf *zvrf;
3560 zebra_vni_t tmp_vni;
3561 zebra_vni_t *zvni = NULL;
3562
3563 zvrf = vrf_info_lookup(VRF_DEFAULT);
3564 assert(zvrf);
3565 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
3566 tmp_vni.vni = vni;
3567 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
3568
3569 return zvni;
3570 }
3571
3572 /*
3573 * Add VNI hash entry.
3574 */
3575 static zebra_vni_t *zvni_add(vni_t vni)
3576 {
3577 struct zebra_vrf *zvrf;
3578 zebra_vni_t tmp_zvni;
3579 zebra_vni_t *zvni = NULL;
3580
3581 zvrf = vrf_info_lookup(VRF_DEFAULT);
3582 assert(zvrf);
3583 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
3584 tmp_zvni.vni = vni;
3585 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
3586 assert(zvni);
3587
3588 /* Create hash table for MAC */
3589 zvni->mac_table =
3590 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
3591
3592 /* Create hash table for neighbors */
3593 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
3594 "Zebra VNI Neighbor Table");
3595
3596 return zvni;
3597 }
3598
3599 /*
3600 * Delete VNI hash entry.
3601 */
3602 static int zvni_del(zebra_vni_t *zvni)
3603 {
3604 struct zebra_vrf *zvrf;
3605 zebra_vni_t *tmp_zvni;
3606
3607 zvrf = vrf_info_lookup(VRF_DEFAULT);
3608 assert(zvrf);
3609
3610 zvni->vxlan_if = NULL;
3611
3612 /* Free the neighbor hash table. */
3613 hash_free(zvni->neigh_table);
3614 zvni->neigh_table = NULL;
3615
3616 /* Free the MAC hash table. */
3617 hash_free(zvni->mac_table);
3618 zvni->mac_table = NULL;
3619
3620 /* Free the VNI hash entry and allocated memory. */
3621 tmp_zvni = hash_release(zvrf->vni_table, zvni);
3622 if (tmp_zvni)
3623 XFREE(MTYPE_ZVNI, tmp_zvni);
3624
3625 return 0;
3626 }
3627
3628 /*
3629 * Inform BGP about local VNI addition.
3630 */
3631 static int zvni_send_add_to_client(zebra_vni_t *zvni)
3632 {
3633 struct zserv *client;
3634 struct stream *s;
3635
3636 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
3637 /* BGP may not be running. */
3638 if (!client)
3639 return 0;
3640
3641 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
3642
3643 zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
3644 stream_putl(s, zvni->vni);
3645 stream_put_in_addr(s, &zvni->local_vtep_ip);
3646 stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
3647
3648 /* Write packet size. */
3649 stream_putw_at(s, 0, stream_get_endp(s));
3650
3651 if (IS_ZEBRA_DEBUG_VXLAN)
3652 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni->vni,
3653 inet_ntoa(zvni->local_vtep_ip),
3654 vrf_id_to_name(zvni->vrf_id),
3655 zebra_route_string(client->proto));
3656
3657 client->vniadd_cnt++;
3658 return zserv_send_message(client, s);
3659 }
3660
3661 /*
3662 * Inform BGP about local VNI deletion.
3663 */
3664 static int zvni_send_del_to_client(vni_t vni)
3665 {
3666 struct zserv *client;
3667 struct stream *s;
3668
3669 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
3670 /* BGP may not be running. */
3671 if (!client)
3672 return 0;
3673
3674 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
3675 stream_reset(s);
3676
3677 zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
3678 stream_putl(s, vni);
3679
3680 /* Write packet size. */
3681 stream_putw_at(s, 0, stream_get_endp(s));
3682
3683 if (IS_ZEBRA_DEBUG_VXLAN)
3684 zlog_debug("Send VNI_DEL %u to %s", vni,
3685 zebra_route_string(client->proto));
3686
3687 client->vnidel_cnt++;
3688 return zserv_send_message(client, s);
3689 }
3690
3691 /*
3692 * Build the VNI hash table by going over the VxLAN interfaces. This
3693 * is called when EVPN (advertise-all-vni) is enabled.
3694 */
3695 static void zvni_build_hash_table()
3696 {
3697 struct zebra_ns *zns;
3698 struct route_node *rn;
3699 struct interface *ifp;
3700
3701 /* Walk VxLAN interfaces and create VNI hash. */
3702 zns = zebra_ns_lookup(NS_DEFAULT);
3703 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3704 vni_t vni;
3705 zebra_vni_t *zvni = NULL;
3706 zebra_l3vni_t *zl3vni = NULL;
3707 struct zebra_if *zif;
3708 struct zebra_l2info_vxlan *vxl;
3709
3710 ifp = (struct interface *)rn->info;
3711 if (!ifp)
3712 continue;
3713 zif = ifp->info;
3714 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3715 continue;
3716
3717 vxl = &zif->l2info.vxl;
3718 vni = vxl->vni;
3719
3720 /* L3-VNI and L2-VNI are handled seperately */
3721 zl3vni = zl3vni_lookup(vni);
3722 if (zl3vni) {
3723
3724 if (IS_ZEBRA_DEBUG_VXLAN)
3725 zlog_debug(
3726 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
3727 ifp->name, ifp->ifindex, vni);
3728
3729 /* associate with vxlan_if */
3730 zl3vni->local_vtep_ip = vxl->vtep_ip;
3731 zl3vni->vxlan_if = ifp;
3732
3733 /*
3734 * we need to associate with SVI.
3735 * we can associate with svi-if only after association
3736 * with vxlan-intf is complete
3737 */
3738 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
3739
3740 if (is_l3vni_oper_up(zl3vni))
3741 zebra_vxlan_process_l3vni_oper_up(zl3vni);
3742
3743 } else {
3744 struct interface *vlan_if = NULL;
3745
3746 if (IS_ZEBRA_DEBUG_VXLAN)
3747 zlog_debug(
3748 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
3749 ifp->name, ifp->ifindex, vni,
3750 inet_ntoa(vxl->vtep_ip));
3751
3752 /* VNI hash entry is not expected to exist. */
3753 zvni = zvni_lookup(vni);
3754 if (zvni) {
3755 zlog_debug(
3756 "VNI hash already present for IF %s(%u) L2-VNI %u",
3757 ifp->name, ifp->ifindex, vni);
3758 continue;
3759 }
3760
3761 zvni = zvni_add(vni);
3762 if (!zvni) {
3763 zlog_debug(
3764 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
3765 ifp->name, ifp->ifindex, vni);
3766 return;
3767 }
3768
3769 zvni->local_vtep_ip = vxl->vtep_ip;
3770 zvni->vxlan_if = ifp;
3771 vlan_if = zvni_map_to_svi(vxl->access_vlan,
3772 zif->brslave_info.br_if);
3773 if (vlan_if) {
3774 zvni->vrf_id = vlan_if->vrf_id;
3775 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
3776 if (zl3vni)
3777 listnode_add_sort(zl3vni->l2vnis, zvni);
3778 }
3779
3780
3781 /* Inform BGP if intf is up and mapped to bridge. */
3782 if (if_is_operative(ifp) && zif->brslave_info.br_if)
3783 zvni_send_add_to_client(zvni);
3784 }
3785 }
3786 }
3787
3788 /*
3789 * See if remote VTEP matches with prefix.
3790 */
3791 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
3792 {
3793 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
3794 }
3795
3796 /*
3797 * Locate remote VTEP in VNI hash table.
3798 */
3799 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
3800 {
3801 zebra_vtep_t *zvtep;
3802
3803 if (!zvni)
3804 return NULL;
3805
3806 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
3807 if (zvni_vtep_match(vtep_ip, zvtep))
3808 break;
3809 }
3810
3811 return zvtep;
3812 }
3813
3814 /*
3815 * Add remote VTEP to VNI hash table.
3816 */
3817 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
3818 {
3819 zebra_vtep_t *zvtep;
3820
3821 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
3822
3823 zvtep->vtep_ip = *vtep_ip;
3824
3825 if (zvni->vteps)
3826 zvni->vteps->prev = zvtep;
3827 zvtep->next = zvni->vteps;
3828 zvni->vteps = zvtep;
3829
3830 return zvtep;
3831 }
3832
3833 /*
3834 * Remove remote VTEP from VNI hash table.
3835 */
3836 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
3837 {
3838 if (zvtep->next)
3839 zvtep->next->prev = zvtep->prev;
3840 if (zvtep->prev)
3841 zvtep->prev->next = zvtep->next;
3842 else
3843 zvni->vteps = zvtep->next;
3844
3845 zvtep->prev = zvtep->next = NULL;
3846 XFREE(MTYPE_ZVNI_VTEP, zvtep);
3847
3848 return 0;
3849 }
3850
3851 /*
3852 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
3853 * uninstall from kernel if asked to.
3854 */
3855 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
3856 {
3857 zebra_vtep_t *zvtep, *zvtep_next;
3858
3859 if (!zvni)
3860 return -1;
3861
3862 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
3863 zvtep_next = zvtep->next;
3864 if (uninstall)
3865 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
3866 zvni_vtep_del(zvni, zvtep);
3867 }
3868
3869 return 0;
3870 }
3871
3872 /*
3873 * Install remote VTEP into the kernel.
3874 */
3875 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
3876 {
3877 if (is_vxlan_flooding_head_end())
3878 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
3879 return 0;
3880 }
3881
3882 /*
3883 * Uninstall remote VTEP from the kernel.
3884 */
3885 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
3886 {
3887 if (!zvni->vxlan_if) {
3888 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3889 zvni->vni, zvni);
3890 return -1;
3891 }
3892
3893 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
3894 }
3895
3896 /*
3897 * Install or uninstall flood entries in the kernel corresponding to
3898 * remote VTEPs. This is invoked upon change to BUM handling.
3899 */
3900 static void zvni_handle_flooding_remote_vteps(struct hash_backet *backet,
3901 void *zvrf)
3902 {
3903 zebra_vni_t *zvni;
3904 zebra_vtep_t *zvtep;
3905
3906 zvni = (zebra_vni_t *)backet->data;
3907 if (!zvni)
3908 return;
3909
3910 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
3911 if (is_vxlan_flooding_head_end())
3912 zvni_vtep_install(zvni, &zvtep->vtep_ip);
3913 else
3914 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
3915 }
3916 }
3917
3918 /*
3919 * Cleanup VNI/VTEP and update kernel
3920 */
3921 static void zvni_cleanup_all(struct hash_backet *backet, void *arg)
3922 {
3923 zebra_vni_t *zvni = NULL;
3924 zebra_l3vni_t *zl3vni = NULL;
3925 struct zebra_vrf *zvrf = (struct zebra_vrf *)arg;
3926
3927 zvni = (zebra_vni_t *)backet->data;
3928
3929 /* remove from l3-vni list */
3930 if (zvrf->l3vni)
3931 zl3vni = zl3vni_lookup(zvrf->l3vni);
3932 if (zl3vni)
3933 listnode_delete(zl3vni->l2vnis, zvni);
3934
3935 /* Free up all neighbors and MACs, if any. */
3936 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
3937 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
3938
3939 /* Free up all remote VTEPs, if any. */
3940 zvni_vtep_del_all(zvni, 1);
3941
3942 /* Delete the hash entry. */
3943 zvni_del(zvni);
3944 }
3945
3946 /* cleanup L3VNI */
3947 static void zl3vni_cleanup_all(struct hash_backet *backet, void *args)
3948 {
3949 zebra_l3vni_t *zl3vni = NULL;
3950
3951 zl3vni = (zebra_l3vni_t *)backet->data;
3952
3953 zebra_vxlan_process_l3vni_oper_down(zl3vni);
3954 }
3955
3956 static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
3957 struct prefix *host)
3958 {
3959 struct host_rb_entry lookup;
3960 struct host_rb_entry *hle;
3961
3962 memset(&lookup, 0, sizeof(lookup));
3963 memcpy(&lookup.p, host, sizeof(*host));
3964
3965 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
3966 if (hle)
3967 return;
3968
3969 hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
3970 memcpy(hle, &lookup, sizeof(lookup));
3971
3972 RB_INSERT(host_rb_tree_entry, hrbe, hle);
3973 }
3974
3975 static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
3976 {
3977 struct host_rb_entry lookup;
3978 struct host_rb_entry *hle;
3979
3980 memset(&lookup, 0, sizeof(lookup));
3981 memcpy(&lookup.p, host, sizeof(*host));
3982
3983 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
3984 if (hle) {
3985 RB_REMOVE(host_rb_tree_entry, hrbe, hle);
3986 XFREE(MTYPE_HOST_PREFIX, hle);
3987 }
3988
3989 return;
3990 }
3991
3992 /*
3993 * Look up MAC hash entry.
3994 */
3995 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
3996 struct ethaddr *rmac)
3997 {
3998 zebra_mac_t tmp;
3999 zebra_mac_t *pmac;
4000
4001 memset(&tmp, 0, sizeof(tmp));
4002 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
4003 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
4004
4005 return pmac;
4006 }
4007
4008 /*
4009 * Callback to allocate RMAC hash entry.
4010 */
4011 static void *zl3vni_rmac_alloc(void *p)
4012 {
4013 const zebra_mac_t *tmp_rmac = p;
4014 zebra_mac_t *zrmac;
4015
4016 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
4017 *zrmac = *tmp_rmac;
4018
4019 return ((void *)zrmac);
4020 }
4021
4022 /*
4023 * Add RMAC entry to l3-vni
4024 */
4025 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac)
4026 {
4027 zebra_mac_t tmp_rmac;
4028 zebra_mac_t *zrmac = NULL;
4029
4030 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
4031 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
4032 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
4033 assert(zrmac);
4034
4035 RB_INIT(host_rb_tree_entry, &zrmac->host_rb);
4036
4037 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
4038 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
4039
4040 return zrmac;
4041 }
4042
4043 /*
4044 * Delete MAC entry.
4045 */
4046 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4047 {
4048 zebra_mac_t *tmp_rmac;
4049 struct host_rb_entry *hle;
4050
4051 while (!RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
4052 hle = RB_ROOT(host_rb_tree_entry, &zrmac->host_rb);
4053
4054 RB_REMOVE(host_rb_tree_entry, &zrmac->host_rb, hle);
4055 XFREE(MTYPE_HOST_PREFIX, hle);
4056 }
4057
4058 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
4059 if (tmp_rmac)
4060 XFREE(MTYPE_MAC, tmp_rmac);
4061
4062 return 0;
4063 }
4064
4065 /*
4066 * Install remote RMAC into the kernel.
4067 */
4068 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4069 {
4070 struct zebra_if *zif = NULL;
4071 struct zebra_l2info_vxlan *vxl = NULL;
4072
4073 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
4074 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
4075 return 0;
4076
4077 zif = zl3vni->vxlan_if->info;
4078 if (!zif)
4079 return -1;
4080
4081 vxl = &zif->l2info.vxl;
4082
4083 return kernel_add_mac(zl3vni->vxlan_if, vxl->access_vlan,
4084 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
4085 }
4086
4087 /*
4088 * Uninstall remote RMAC from the kernel.
4089 */
4090 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4091 {
4092 char buf[ETHER_ADDR_STRLEN];
4093 struct zebra_if *zif = NULL;
4094 struct zebra_l2info_vxlan *vxl = NULL;
4095
4096 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
4097 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
4098 return 0;
4099
4100 if (!zl3vni->vxlan_if) {
4101 zlog_debug(
4102 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
4103 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
4104 zl3vni->vni, zl3vni);
4105 return -1;
4106 }
4107
4108 zif = zl3vni->vxlan_if->info;
4109 if (!zif)
4110 return -1;
4111
4112 vxl = &zif->l2info.vxl;
4113
4114 return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
4115 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
4116 }
4117
4118 /* handle rmac add */
4119 static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
4120 struct ipaddr *vtep_ip,
4121 struct prefix *host_prefix)
4122 {
4123 char buf[ETHER_ADDR_STRLEN];
4124 char buf1[INET6_ADDRSTRLEN];
4125 zebra_mac_t *zrmac = NULL;
4126
4127 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
4128 if (!zrmac) {
4129
4130 zrmac = zl3vni_rmac_add(zl3vni, rmac);
4131 if (!zrmac) {
4132 zlog_debug(
4133 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
4134 prefix_mac2str(rmac, buf, sizeof(buf)),
4135 zl3vni->vni,
4136 ipaddr2str(vtep_ip, buf1, sizeof(buf1)));
4137 return -1;
4138 }
4139 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
4140 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
4141
4142 /* install rmac in kernel */
4143 zl3vni_rmac_install(zl3vni, zrmac);
4144 }
4145
4146 rb_find_or_add_host(&zrmac->host_rb, host_prefix);
4147
4148 return 0;
4149 }
4150
4151
4152 /* handle rmac delete */
4153 static void zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac,
4154 struct prefix *host_prefix)
4155 {
4156 rb_delete_host(&zrmac->host_rb, host_prefix);
4157
4158 if (RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
4159 /* uninstall from kernel */
4160 zl3vni_rmac_uninstall(zl3vni, zrmac);
4161
4162 /* del the rmac entry */
4163 zl3vni_rmac_del(zl3vni, zrmac);
4164 }
4165 }
4166
4167 /*
4168 * Look up nh hash entry on a l3-vni.
4169 */
4170 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
4171 {
4172 zebra_neigh_t tmp;
4173 zebra_neigh_t *n;
4174
4175 memset(&tmp, 0, sizeof(tmp));
4176 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
4177 n = hash_lookup(zl3vni->nh_table, &tmp);
4178
4179 return n;
4180 }
4181
4182
4183 /*
4184 * Callback to allocate NH hash entry on L3-VNI.
4185 */
4186 static void *zl3vni_nh_alloc(void *p)
4187 {
4188 const zebra_neigh_t *tmp_n = p;
4189 zebra_neigh_t *n;
4190
4191 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
4192 *n = *tmp_n;
4193
4194 return ((void *)n);
4195 }
4196
4197 /*
4198 * Add neighbor entry.
4199 */
4200 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *ip,
4201 struct ethaddr *mac)
4202 {
4203 zebra_neigh_t tmp_n;
4204 zebra_neigh_t *n = NULL;
4205
4206 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
4207 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
4208 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
4209 assert(n);
4210
4211 RB_INIT(host_rb_tree_entry, &n->host_rb);
4212
4213 memcpy(&n->emac, mac, ETH_ALEN);
4214 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
4215 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
4216
4217 return n;
4218 }
4219
4220 /*
4221 * Delete neighbor entry.
4222 */
4223 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4224 {
4225 zebra_neigh_t *tmp_n;
4226 struct host_rb_entry *hle;
4227
4228 while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
4229 hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
4230
4231 RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
4232 XFREE(MTYPE_HOST_PREFIX, hle);
4233 }
4234
4235 tmp_n = hash_release(zl3vni->nh_table, n);
4236 if (tmp_n)
4237 XFREE(MTYPE_NEIGH, tmp_n);
4238
4239 return 0;
4240 }
4241
4242 /*
4243 * Install remote nh as neigh into the kernel.
4244 */
4245 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4246 {
4247 #ifdef GNU_LINUX
4248 uint8_t flags;
4249 #endif
4250 int ret = 0;
4251
4252 if (!is_l3vni_oper_up(zl3vni))
4253 return -1;
4254
4255 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
4256 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
4257 return 0;
4258 #ifdef GNU_LINUX
4259 flags = NTF_EXT_LEARNED;
4260 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
4261 flags |= NTF_ROUTER;
4262 ret = kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac, flags);
4263 #endif
4264 return ret;
4265 }
4266
4267 /*
4268 * Uninstall remote nh from the kernel.
4269 */
4270 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4271 {
4272 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
4273 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
4274 return 0;
4275
4276 if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
4277 return 0;
4278
4279 return kernel_del_neigh(zl3vni->svi_if, &n->ip);
4280 }
4281
4282 /* add remote vtep as a neigh entry */
4283 static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
4284 struct ethaddr *rmac,
4285 struct prefix *host_prefix)
4286 {
4287 char buf[ETHER_ADDR_STRLEN];
4288 char buf1[INET6_ADDRSTRLEN];
4289 zebra_neigh_t *nh = NULL;
4290
4291 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
4292 if (!nh) {
4293 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
4294 if (!nh) {
4295
4296 zlog_debug(
4297 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
4298 ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
4299 prefix_mac2str(rmac, buf, sizeof(buf)),
4300 zl3vni->vni);
4301 return -1;
4302 }
4303
4304 /* install the nh neigh in kernel */
4305 zl3vni_nh_install(zl3vni, nh);
4306 }
4307
4308 rb_find_or_add_host(&nh->host_rb, host_prefix);
4309
4310 return 0;
4311 }
4312
4313 /* handle nh neigh delete */
4314 static void zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *nh,
4315 struct prefix *host_prefix)
4316 {
4317 rb_delete_host(&nh->host_rb, host_prefix);
4318
4319 if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
4320 /* uninstall from kernel */
4321 zl3vni_nh_uninstall(zl3vni, nh);
4322
4323 /* delete the nh entry */
4324 zl3vni_nh_del(zl3vni, nh);
4325 }
4326 }
4327
4328 /* handle neigh update from kernel - the only thing of interest is to
4329 * readd stale entries.
4330 */
4331 static int zl3vni_local_nh_add_update(zebra_l3vni_t *zl3vni, struct ipaddr *ip,
4332 uint16_t state)
4333 {
4334 #ifdef GNU_LINUX
4335 zebra_neigh_t *n = NULL;
4336
4337 n = zl3vni_nh_lookup(zl3vni, ip);
4338 if (!n)
4339 return 0;
4340
4341 /* all next hop neigh are remote and installed by frr.
4342 * If the kernel has aged this entry, re-install.
4343 */
4344 if (state & NUD_STALE)
4345 zl3vni_nh_install(zl3vni, n);
4346 #endif
4347 return 0;
4348 }
4349
4350 /* handle neigh delete from kernel */
4351 static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
4352 {
4353 zebra_neigh_t *n = NULL;
4354
4355 n = zl3vni_nh_lookup(zl3vni, ip);
4356 if (!n)
4357 return 0;
4358
4359 /* all next hop neigh are remote and installed by frr.
4360 * If we get an age out notification for these neigh entries, we have to
4361 * install it back
4362 */
4363 zl3vni_nh_install(zl3vni, n);
4364
4365 return 0;
4366 }
4367
4368 /*
4369 * Hash function for L3 VNI.
4370 */
4371 static unsigned int l3vni_hash_keymake(void *p)
4372 {
4373 const zebra_l3vni_t *zl3vni = p;
4374
4375 return jhash_1word(zl3vni->vni, 0);
4376 }
4377
4378 /*
4379 * Compare 2 L3 VNI hash entries.
4380 */
4381 static bool l3vni_hash_cmp(const void *p1, const void *p2)
4382 {
4383 const zebra_l3vni_t *zl3vni1 = p1;
4384 const zebra_l3vni_t *zl3vni2 = p2;
4385
4386 return (zl3vni1->vni == zl3vni2->vni);
4387 }
4388
4389 /*
4390 * Callback to allocate L3 VNI hash entry.
4391 */
4392 static void *zl3vni_alloc(void *p)
4393 {
4394 zebra_l3vni_t *zl3vni = NULL;
4395 const zebra_l3vni_t *tmp_l3vni = p;
4396
4397 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(zebra_l3vni_t));
4398 zl3vni->vni = tmp_l3vni->vni;
4399 return ((void *)zl3vni);
4400 }
4401
4402 /*
4403 * Look up L3 VNI hash entry.
4404 */
4405 static zebra_l3vni_t *zl3vni_lookup(vni_t vni)
4406 {
4407 zebra_l3vni_t tmp_l3vni;
4408 zebra_l3vni_t *zl3vni = NULL;
4409
4410 memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t));
4411 tmp_l3vni.vni = vni;
4412 zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
4413
4414 return zl3vni;
4415 }
4416
4417 /*
4418 * Add L3 VNI hash entry.
4419 */
4420 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
4421 {
4422 zebra_l3vni_t tmp_zl3vni;
4423 zebra_l3vni_t *zl3vni = NULL;
4424
4425 memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t));
4426 tmp_zl3vni.vni = vni;
4427
4428 zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
4429 assert(zl3vni);
4430
4431 zl3vni->vrf_id = vrf_id;
4432 zl3vni->svi_if = NULL;
4433 zl3vni->vxlan_if = NULL;
4434 zl3vni->l2vnis = list_new();
4435 zl3vni->l2vnis->cmp = vni_list_cmp;
4436
4437 /* Create hash table for remote RMAC */
4438 zl3vni->rmac_table = hash_create(mac_hash_keymake, mac_cmp,
4439 "Zebra L3-VNI RMAC-Table");
4440
4441 /* Create hash table for neighbors */
4442 zl3vni->nh_table = hash_create(neigh_hash_keymake, neigh_cmp,
4443 "Zebra L3-VNI next-hop table");
4444
4445 return zl3vni;
4446 }
4447
4448 /*
4449 * Delete L3 VNI hash entry.
4450 */
4451 static int zl3vni_del(zebra_l3vni_t *zl3vni)
4452 {
4453 zebra_l3vni_t *tmp_zl3vni;
4454
4455 /* free the list of l2vnis */
4456 list_delete(&zl3vni->l2vnis);
4457 zl3vni->l2vnis = NULL;
4458
4459 /* Free the rmac table */
4460 hash_free(zl3vni->rmac_table);
4461 zl3vni->rmac_table = NULL;
4462
4463 /* Free the nh table */
4464 hash_free(zl3vni->nh_table);
4465 zl3vni->nh_table = NULL;
4466
4467 /* Free the VNI hash entry and allocated memory. */
4468 tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
4469 if (tmp_zl3vni)
4470 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
4471
4472 return 0;
4473 }
4474
4475 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
4476 {
4477 struct zebra_ns *zns = NULL;
4478 struct route_node *rn = NULL;
4479 struct interface *ifp = NULL;
4480
4481 /* loop through all vxlan-interface */
4482 zns = zebra_ns_lookup(NS_DEFAULT);
4483 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4484
4485 struct zebra_if *zif = NULL;
4486 struct zebra_l2info_vxlan *vxl = NULL;
4487
4488 ifp = (struct interface *)rn->info;
4489 if (!ifp)
4490 continue;
4491
4492 zif = ifp->info;
4493 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4494 continue;
4495
4496 vxl = &zif->l2info.vxl;
4497 if (vxl->vni == zl3vni->vni) {
4498 zl3vni->local_vtep_ip = vxl->vtep_ip;
4499 return ifp;
4500 }
4501 }
4502
4503 return NULL;
4504 }
4505
4506 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
4507 {
4508 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
4509 struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
4510
4511 if (!zl3vni)
4512 return NULL;
4513
4514 if (!zl3vni->vxlan_if)
4515 return NULL;
4516
4517 zif = zl3vni->vxlan_if->info;
4518 if (!zif)
4519 return NULL;
4520
4521 vxl = &zif->l2info.vxl;
4522
4523 return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
4524 }
4525
4526 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id)
4527 {
4528 struct zebra_vrf *zvrf = NULL;
4529
4530 zvrf = zebra_vrf_lookup_by_id(vrf_id);
4531 if (!zvrf)
4532 return NULL;
4533
4534 return zl3vni_lookup(zvrf->l3vni);
4535 }
4536
4537 /*
4538 * Map SVI and associated bridge to a VNI. This is invoked upon getting
4539 * neighbor notifications, to see if they are of interest.
4540 */
4541 static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp,
4542 struct interface *br_if)
4543 {
4544 int found = 0;
4545 vlanid_t vid = 0;
4546 uint8_t bridge_vlan_aware = 0;
4547 zebra_l3vni_t *zl3vni = NULL;
4548 struct zebra_ns *zns = NULL;
4549 struct route_node *rn = NULL;
4550 struct zebra_if *zif = NULL;
4551 struct interface *tmp_if = NULL;
4552 struct zebra_l2info_bridge *br = NULL;
4553 struct zebra_l2info_vxlan *vxl = NULL;
4554
4555 if (!br_if)
4556 return NULL;
4557
4558 /* Make sure the linked interface is a bridge. */
4559 if (!IS_ZEBRA_IF_BRIDGE(br_if))
4560 return NULL;
4561
4562 /* Determine if bridge is VLAN-aware or not */
4563 zif = br_if->info;
4564 assert(zif);
4565 br = &zif->l2info.br;
4566 bridge_vlan_aware = br->vlan_aware;
4567 if (bridge_vlan_aware) {
4568 struct zebra_l2info_vlan *vl;
4569
4570 if (!IS_ZEBRA_IF_VLAN(ifp))
4571 return NULL;
4572
4573 zif = ifp->info;
4574 assert(zif);
4575 vl = &zif->l2info.vl;
4576 vid = vl->vid;
4577 }
4578
4579 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
4580 /* TODO: Optimize with a hash. */
4581 zns = zebra_ns_lookup(NS_DEFAULT);
4582 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4583 tmp_if = (struct interface *)rn->info;
4584 if (!tmp_if)
4585 continue;
4586 zif = tmp_if->info;
4587 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4588 continue;
4589 if (!if_is_operative(tmp_if))
4590 continue;
4591 vxl = &zif->l2info.vxl;
4592
4593 if (zif->brslave_info.br_if != br_if)
4594 continue;
4595
4596 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
4597 found = 1;
4598 break;
4599 }
4600 }
4601
4602 if (!found)
4603 return NULL;
4604
4605 zl3vni = zl3vni_lookup(vxl->vni);
4606 return zl3vni;
4607 }
4608
4609 /*
4610 * Inform BGP about l3-vni.
4611 */
4612 static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
4613 {
4614 struct stream *s = NULL;
4615 struct zserv *client = NULL;
4616 struct ethaddr rmac;
4617 char buf[ETHER_ADDR_STRLEN];
4618
4619 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4620 /* BGP may not be running. */
4621 if (!client)
4622 return 0;
4623
4624 /* get the rmac */
4625 memset(&rmac, 0, sizeof(struct ethaddr));
4626 zl3vni_get_rmac(zl3vni, &rmac);
4627
4628 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4629
4630 zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
4631 stream_putl(s, zl3vni->vni);
4632 stream_put(s, &rmac, sizeof(struct ethaddr));
4633 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
4634 stream_put(s, &zl3vni->filter, sizeof(int));
4635
4636 /* Write packet size. */
4637 stream_putw_at(s, 0, stream_get_endp(s));
4638
4639 if (IS_ZEBRA_DEBUG_VXLAN)
4640 zlog_debug(
4641 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
4642 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
4643 prefix_mac2str(&rmac, buf, sizeof(buf)),
4644 inet_ntoa(zl3vni->local_vtep_ip),
4645 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
4646 ? "prefix-routes-only"
4647 : "none",
4648 zebra_route_string(client->proto));
4649
4650 client->l3vniadd_cnt++;
4651 return zserv_send_message(client, s);
4652 }
4653
4654 /*
4655 * Inform BGP about local l3-VNI deletion.
4656 */
4657 static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
4658 {
4659 struct stream *s = NULL;
4660 struct zserv *client = NULL;
4661
4662 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4663 /* BGP may not be running. */
4664 if (!client)
4665 return 0;
4666
4667 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4668
4669 zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
4670 stream_putl(s, zl3vni->vni);
4671
4672 /* Write packet size. */
4673 stream_putw_at(s, 0, stream_get_endp(s));
4674
4675 if (IS_ZEBRA_DEBUG_VXLAN)
4676 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
4677 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
4678 zebra_route_string(client->proto));
4679
4680 client->l3vnidel_cnt++;
4681 return zserv_send_message(client, s);
4682 }
4683
4684 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
4685 {
4686 if (!zl3vni)
4687 return;
4688
4689 /* send l3vni add to BGP */
4690 zl3vni_send_add_to_client(zl3vni);
4691 }
4692
4693 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
4694 {
4695 if (!zl3vni)
4696 return;
4697
4698 /* send l3-vni del to BGP*/
4699 zl3vni_send_del_to_client(zl3vni);
4700 }
4701
4702 static void zvni_add_to_l3vni_list(struct hash_backet *backet, void *ctxt)
4703 {
4704 zebra_vni_t *zvni = (zebra_vni_t *)backet->data;
4705 zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)ctxt;
4706
4707 if (zvni->vrf_id == zl3vni_vrf_id(zl3vni))
4708 listnode_add_sort(zl3vni->l2vnis, zvni);
4709 }
4710
4711 /*
4712 * handle transition of vni from l2 to l3 and vice versa
4713 */
4714 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
4715 int add)
4716 {
4717 zebra_vni_t *zvni = NULL;
4718
4719 /* There is a possibility that VNI notification was already received
4720 * from kernel and we programmed it as L2-VNI
4721 * In such a case we need to delete this L2-VNI first, so
4722 * that it can be reprogrammed as L3-VNI in the system. It is also
4723 * possible that the vrf-vni mapping is removed from FRR while the vxlan
4724 * interface is still present in kernel. In this case to keep it
4725 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
4726 */
4727 if (add) {
4728 /* Locate hash entry */
4729 zvni = zvni_lookup(vni);
4730 if (!zvni)
4731 return 0;
4732
4733 if (IS_ZEBRA_DEBUG_VXLAN)
4734 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
4735
4736 /* Delete VNI from BGP. */
4737 zvni_send_del_to_client(zvni->vni);
4738
4739 /* Free up all neighbors and MAC, if any. */
4740 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
4741 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
4742
4743 /* Free up all remote VTEPs, if any. */
4744 zvni_vtep_del_all(zvni, 0);
4745
4746 /* Delete the hash entry. */
4747 if (zvni_del(zvni)) {
4748 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
4749 "Failed to del VNI hash %p, VNI %u", zvni,
4750 zvni->vni);
4751 return -1;
4752 }
4753 } else {
4754 /* TODO_MITESH: This needs to be thought through. We don't have
4755 * enough information at this point to reprogram the vni as
4756 * l2-vni. One way is to store the required info in l3-vni and
4757 * used it solely for this purpose
4758 */
4759 }
4760
4761 return 0;
4762 }
4763
4764 /* delete and uninstall rmac hash entry */
4765 static void zl3vni_del_rmac_hash_entry(struct hash_backet *backet, void *ctx)
4766 {
4767 zebra_mac_t *zrmac = NULL;
4768 zebra_l3vni_t *zl3vni = NULL;
4769
4770 zrmac = (zebra_mac_t *)backet->data;
4771 zl3vni = (zebra_l3vni_t *)ctx;
4772 zl3vni_rmac_uninstall(zl3vni, zrmac);
4773 zl3vni_rmac_del(zl3vni, zrmac);
4774 }
4775
4776 /* delete and uninstall nh hash entry */
4777 static void zl3vni_del_nh_hash_entry(struct hash_backet *backet, void *ctx)
4778 {
4779 zebra_neigh_t *n = NULL;
4780 zebra_l3vni_t *zl3vni = NULL;
4781
4782 n = (zebra_neigh_t *)backet->data;
4783 zl3vni = (zebra_l3vni_t *)ctx;
4784 zl3vni_nh_uninstall(zl3vni, n);
4785 zl3vni_nh_del(zl3vni, n);
4786 }
4787
4788 static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
4789 uint16_t cmd)
4790 {
4791 struct zserv *client = NULL;
4792 struct stream *s = NULL;
4793 char buf[PREFIX_STRLEN];
4794
4795 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4796 /* BGP may not be running. */
4797 if (!client)
4798 return 0;
4799
4800 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4801
4802 zclient_create_header(s, cmd, vrf_id);
4803 stream_put(s, p, sizeof(struct prefix));
4804
4805 /* Write packet size. */
4806 stream_putw_at(s, 0, stream_get_endp(s));
4807
4808 if (IS_ZEBRA_DEBUG_VXLAN)
4809 zlog_debug("Send ip prefix %s %s on vrf %s",
4810 prefix2str(p, buf, sizeof(buf)),
4811 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
4812 vrf_id_to_name(vrf_id));
4813
4814 if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
4815 client->prefixadd_cnt++;
4816 else
4817 client->prefixdel_cnt++;
4818
4819 return zserv_send_message(client, s);
4820 }
4821
4822 /* re-add remote rmac if needed */
4823 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
4824 struct ethaddr *rmac)
4825 {
4826 char buf[ETHER_ADDR_STRLEN];
4827 zebra_mac_t *zrmac = NULL;
4828
4829 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
4830 if (!zrmac)
4831 return 0;
4832
4833 if (IS_ZEBRA_DEBUG_VXLAN)
4834 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
4835 prefix_mac2str(rmac, buf, sizeof(buf)), zl3vni->vni);
4836
4837 zl3vni_rmac_install(zl3vni, zrmac);
4838 return 0;
4839 }
4840
4841 /* Process a remote MACIP add from BGP. */
4842 static void process_remote_macip_add(vni_t vni,
4843 struct ethaddr *macaddr,
4844 uint16_t ipa_len,
4845 struct ipaddr *ipaddr,
4846 uint8_t flags,
4847 uint32_t seq,
4848 struct in_addr vtep_ip)
4849 {
4850 zebra_vni_t *zvni;
4851 zebra_vtep_t *zvtep;
4852 zebra_mac_t *mac = NULL, *old_mac = NULL;
4853 zebra_neigh_t *n = NULL;
4854 int update_mac = 0, update_neigh = 0;
4855 char buf[ETHER_ADDR_STRLEN];
4856 char buf1[INET6_ADDRSTRLEN];
4857 struct interface *ifp = NULL;
4858 struct zebra_if *zif = NULL;
4859 struct zebra_vrf *zvrf;
4860 uint32_t tmp_seq;
4861 bool sticky;
4862 bool remote_gw;
4863 bool is_router;
4864 bool do_dad = false;
4865 bool is_dup_detect = false;
4866
4867 /* Locate VNI hash entry - expected to exist. */
4868 zvni = zvni_lookup(vni);
4869 if (!zvni) {
4870 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni);
4871 return;
4872 }
4873
4874 ifp = zvni->vxlan_if;
4875 if (ifp)
4876 zif = ifp->info;
4877 if (!ifp ||
4878 !if_is_operative(ifp) ||
4879 !zif ||
4880 !zif->brslave_info.br_if) {
4881 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
4882 vni);
4883 return;
4884 }
4885
4886 /* The remote VTEP specified should normally exist, but it is
4887 * possible that when peering comes up, peer may advertise MACIP
4888 * routes before advertising type-3 routes.
4889 */
4890 zvtep = zvni_vtep_find(zvni, &vtep_ip);
4891 if (!zvtep) {
4892 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
4893 flog_err(
4894 EC_ZEBRA_VTEP_ADD_FAILED,
4895 "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
4896 vni, zvni);
4897 return;
4898 }
4899
4900 zvni_vtep_install(zvni, &vtep_ip);
4901 }
4902
4903 sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
4904 remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
4905 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
4906
4907 mac = zvni_mac_lookup(zvni, macaddr);
4908
4909 /* Ignore if the mac is already present as a gateway mac */
4910 if (mac &&
4911 CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
4912 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
4913 if (IS_ZEBRA_DEBUG_VXLAN)
4914 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
4915 vni,
4916 prefix_mac2str(macaddr, buf, sizeof(buf)),
4917 ipa_len ? " IP " : "",
4918 ipa_len ?
4919 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
4920 return;
4921 }
4922
4923 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
4924 if (!zvrf)
4925 return;
4926
4927 /* check if the remote MAC is unknown or has a change.
4928 * If so, that needs to be updated first. Note that client could
4929 * install MAC and MACIP separately or just install the latter.
4930 */
4931 if (!mac
4932 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
4933 || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
4934 || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
4935 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
4936 || seq != mac->rem_seq)
4937 update_mac = 1;
4938
4939 if (update_mac) {
4940 if (!mac) {
4941 mac = zvni_mac_add(zvni, macaddr);
4942 if (!mac) {
4943 zlog_warn(
4944 "Failed to add MAC %s VNI %u Remote VTEP %s",
4945 prefix_mac2str(macaddr, buf,
4946 sizeof(buf)),
4947 vni, inet_ntoa(vtep_ip));
4948 return;
4949 }
4950
4951 /* Is this MAC created for a MACIP? */
4952 if (ipa_len)
4953 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
4954 } else {
4955 const char *mac_type;
4956
4957 /* When host moves but changes its (MAC,IP)
4958 * binding, BGP may install a MACIP entry that
4959 * corresponds to "older" location of the host
4960 * in transient situations (because {IP1,M1}
4961 * is a different route from {IP1,M2}). Check
4962 * the sequence number and ignore this update
4963 * if appropriate.
4964 */
4965 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
4966 tmp_seq = mac->loc_seq;
4967 mac_type = "local";
4968 } else {
4969 tmp_seq = mac->rem_seq;
4970 mac_type = "remote";
4971 }
4972 if (seq < tmp_seq) {
4973 if (IS_ZEBRA_DEBUG_VXLAN)
4974 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
4975 vni,
4976 prefix_mac2str(macaddr,
4977 buf, sizeof(buf)),
4978 ipa_len ? " IP " : "",
4979 ipa_len ?
4980 ipaddr2str(ipaddr,
4981 buf1, sizeof(buf1)) : "",
4982 mac_type,
4983 tmp_seq);
4984 return;
4985 }
4986 }
4987
4988 /* Check MAC's curent state is local (this is the case
4989 * where MAC has moved from L->R) and check previous
4990 * detection started via local learning.
4991 * RFC-7432: A PE/VTEP that detects a MAC mobility
4992 * event via local learning starts an M-second timer.
4993 *
4994 * VTEP-IP or seq. change along is not considered
4995 * for dup. detection.
4996 */
4997 if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) &&
4998 mac->dad_count)
4999 do_dad = true;
5000
5001 /* Remove local MAC from BGP. */
5002 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5003 zvni_mac_send_del_to_client(zvni->vni, macaddr);
5004
5005 /* Set "auto" and "remote" forwarding info. */
5006 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5007 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5008 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5009 mac->fwd_info.r_vtep_ip = vtep_ip;
5010
5011 if (sticky)
5012 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5013 else
5014 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5015
5016 if (remote_gw)
5017 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
5018 else
5019 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
5020
5021 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac,
5022 mac->fwd_info.r_vtep_ip,
5023 do_dad, &is_dup_detect,
5024 false);
5025
5026 zvni_process_neigh_on_remote_mac_add(zvni, mac);
5027
5028 /* Install the entry. */
5029 if (!is_dup_detect)
5030 zvni_mac_install(zvni, mac);
5031 }
5032
5033 /* Update seq number. */
5034 mac->rem_seq = seq;
5035
5036 /* If there is no IP, return after clearing AUTO flag of MAC. */
5037 if (!ipa_len) {
5038 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5039 return;
5040 }
5041
5042 /* Reset flag */
5043 do_dad = false;
5044
5045 /* Check if the remote neighbor itself is unknown or has a
5046 * change. If so, create or update and then install the entry.
5047 */
5048 n = zvni_neigh_lookup(zvni, ipaddr);
5049 if (!n
5050 || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5051 || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
5052 || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0)
5053 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)
5054 || seq != n->rem_seq)
5055 update_neigh = 1;
5056
5057 if (update_neigh) {
5058 if (!n) {
5059 n = zvni_neigh_add(zvni, ipaddr, macaddr);
5060 if (!n) {
5061 zlog_warn(
5062 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5063 ipaddr2str(ipaddr, buf1,
5064 sizeof(buf1)),
5065 prefix_mac2str(macaddr, buf,
5066 sizeof(buf)),
5067 vni, inet_ntoa(vtep_ip));
5068 return;
5069 }
5070
5071 } else {
5072 const char *n_type;
5073
5074 /* When host moves but changes its (MAC,IP)
5075 * binding, BGP may install a MACIP entry that
5076 * corresponds to "older" location of the host
5077 * in transient situations (because {IP1,M1}
5078 * is a different route from {IP1,M2}). Check
5079 * the sequence number and ignore this update
5080 * if appropriate.
5081 */
5082 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
5083 tmp_seq = n->loc_seq;
5084 n_type = "local";
5085 } else {
5086 tmp_seq = n->rem_seq;
5087 n_type = "remote";
5088 }
5089 if (seq < tmp_seq) {
5090 if (IS_ZEBRA_DEBUG_VXLAN)
5091 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
5092 vni,
5093 prefix_mac2str(macaddr,
5094 buf, sizeof(buf)),
5095 " IP ",
5096 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
5097 n_type,
5098 tmp_seq);
5099 return;
5100 }
5101 if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) {
5102 /* MAC change, send a delete for old
5103 * neigh if learnt locally.
5104 */
5105 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) &&
5106 IS_ZEBRA_NEIGH_ACTIVE(n))
5107 zvni_neigh_send_del_to_client(
5108 zvni->vni, &n->ip,
5109 &n->emac, 0);
5110
5111 /* update neigh list for macs */
5112 old_mac = zvni_mac_lookup(zvni, &n->emac);
5113 if (old_mac) {
5114 listnode_delete(old_mac->neigh_list, n);
5115 zvni_deref_ip2mac(zvni, old_mac);
5116 }
5117 listnode_add_sort(mac->neigh_list, n);
5118 memcpy(&n->emac, macaddr, ETH_ALEN);
5119
5120 /* Check Neigh's curent state is local
5121 * (this is the case where neigh/host has moved
5122 * from L->R) and check previous detction
5123 * started via local learning.
5124 *
5125 * RFC-7432: A PE/VTEP that detects a MAC
5126 * mobilit event via local learning starts
5127 * an M-second timer.
5128 * VTEP-IP or seq. change along is not
5129 * considered for dup. detection.
5130 *
5131 * Mobilty event scenario-B IP-MAC binding
5132 * changed.
5133 */
5134 if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
5135 && n->dad_count)
5136 do_dad = true;
5137
5138 }
5139 }
5140
5141 /* Set "remote" forwarding info. */
5142 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
5143 n->r_vtep_ip = vtep_ip;
5144 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
5145
5146 /* Set router flag (R-bit) to this Neighbor entry */
5147 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
5148 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
5149 else
5150 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
5151
5152 /* Check old or new MAC detected as duplicate,
5153 * inherit duplicate flag to this neigh.
5154 */
5155 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_mac,
5156 mac, n)) {
5157 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
5158 "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
5159 zvni->vni,
5160 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
5161 ipaddr2str(&n->ip, buf1, sizeof(buf1)));
5162 }
5163
5164 /* Check duplicate address detection for IP */
5165 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n,
5166 n->r_vtep_ip,
5167 do_dad,
5168 &is_dup_detect,
5169 false);
5170 /* Install the entry. */
5171 if (!is_dup_detect)
5172 zvni_neigh_install(zvni, n);
5173 }
5174
5175 /* Update seq number. */
5176 n->rem_seq = seq;
5177 }
5178
5179 /* Process a remote MACIP delete from BGP. */
5180 static void process_remote_macip_del(vni_t vni,
5181 struct ethaddr *macaddr,
5182 uint16_t ipa_len,
5183 struct ipaddr *ipaddr,
5184 struct in_addr vtep_ip)
5185 {
5186 zebra_vni_t *zvni;
5187 zebra_mac_t *mac = NULL;
5188 zebra_neigh_t *n = NULL;
5189 struct interface *ifp = NULL;
5190 struct zebra_if *zif = NULL;
5191 char buf[ETHER_ADDR_STRLEN];
5192 char buf1[INET6_ADDRSTRLEN];
5193
5194 /* Locate VNI hash entry - expected to exist. */
5195 zvni = zvni_lookup(vni);
5196 if (!zvni) {
5197 if (IS_ZEBRA_DEBUG_VXLAN)
5198 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
5199 return;
5200 }
5201
5202 ifp = zvni->vxlan_if;
5203 if (ifp)
5204 zif = ifp->info;
5205 if (!ifp ||
5206 !if_is_operative(ifp) ||
5207 !zif ||
5208 !zif->brslave_info.br_if) {
5209 if (IS_ZEBRA_DEBUG_VXLAN)
5210 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
5211 vni);
5212 return;
5213 }
5214
5215 /* The remote VTEP specified is normally expected to exist, but
5216 * it is possible that the peer may delete the VTEP before deleting
5217 * any MACs referring to the VTEP, in which case the handler (see
5218 * remote_vtep_del) would have already deleted the MACs.
5219 */
5220 if (!zvni_vtep_find(zvni, &vtep_ip))
5221 return;
5222
5223 mac = zvni_mac_lookup(zvni, macaddr);
5224 if (ipa_len)
5225 n = zvni_neigh_lookup(zvni, ipaddr);
5226
5227 if (n && !mac) {
5228 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
5229 prefix_mac2str(macaddr, buf, sizeof(buf)),
5230 ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni);
5231 return;
5232 }
5233
5234 /* If the remote mac or neighbor doesn't exist there is nothing
5235 * more to do. Otherwise, uninstall the entry and then remove it.
5236 */
5237 if (!mac && !n)
5238 return;
5239
5240 /* Ignore the delete if this mac is a gateway mac-ip */
5241 if (mac
5242 && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
5243 && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
5244 zlog_warn(
5245 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
5246 vni,
5247 prefix_mac2str(macaddr, buf, sizeof(buf)),
5248 ipa_len ? " IP " : "",
5249 ipa_len ?
5250 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
5251 return;
5252 }
5253
5254 /* Uninstall remote neighbor or MAC. */
5255 if (n) {
5256 /* When the MAC changes for an IP, it is possible the
5257 * client may update the new MAC before trying to delete the
5258 * "old" neighbor (as these are two different MACIP routes).
5259 * Do the delete only if the MAC matches.
5260 */
5261 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5262 && (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) {
5263 zvni_neigh_uninstall(zvni, n);
5264 zvni_neigh_del(zvni, n);
5265 zvni_deref_ip2mac(zvni, mac);
5266 }
5267 } else {
5268 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5269 zvni_process_neigh_on_remote_mac_del(zvni, mac);
5270 /*
5271 * the remote sequence number in the auto mac entry
5272 * needs to be reset to 0 as the mac entry may have
5273 * been removed on all VTEPs (including
5274 * the originating one)
5275 */
5276 mac->rem_seq = 0;
5277
5278 /* If all remote neighbors referencing a remote MAC
5279 * go away, we need to uninstall the MAC.
5280 */
5281 if (remote_neigh_count(mac) == 0) {
5282 zvni_mac_uninstall(zvni, mac);
5283 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5284 }
5285 if (list_isempty(mac->neigh_list))
5286 zvni_mac_del(zvni, mac);
5287 else
5288 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5289 }
5290 }
5291 }
5292
5293
5294 /* Public functions */
5295
5296 int is_l3vni_for_prefix_routes_only(vni_t vni)
5297 {
5298 zebra_l3vni_t *zl3vni = NULL;
5299
5300 zl3vni = zl3vni_lookup(vni);
5301 if (!zl3vni)
5302 return 0;
5303
5304 return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
5305 }
5306
5307 /* handle evpn route in vrf table */
5308 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
5309 struct ipaddr *vtep_ip,
5310 struct prefix *host_prefix)
5311 {
5312 zebra_l3vni_t *zl3vni = NULL;
5313 struct ipaddr ipv4_vtep;
5314
5315 zl3vni = zl3vni_from_vrf(vrf_id);
5316 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5317 return;
5318
5319 /*
5320 * add the next hop neighbor -
5321 * neigh to be installed is the ipv6 nexthop neigh
5322 */
5323 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
5324
5325 /*
5326 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
5327 * address. Rmac is programmed against the ipv4 vtep because we only
5328 * support ipv4 tunnels in the h/w right now
5329 */
5330 memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
5331 ipv4_vtep.ipa_type = IPADDR_V4;
5332 if (vtep_ip->ipa_type == IPADDR_V6)
5333 ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
5334 &(ipv4_vtep.ipaddr_v4));
5335 else
5336 memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
5337 sizeof(struct in_addr));
5338
5339 /*
5340 * add the rmac - remote rmac to be installed is against the ipv4
5341 * nexthop address
5342 */
5343 zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
5344 }
5345
5346 /* handle evpn vrf route delete */
5347 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
5348 struct ipaddr *vtep_ip,
5349 struct prefix *host_prefix)
5350 {
5351 zebra_l3vni_t *zl3vni = NULL;
5352 zebra_neigh_t *nh = NULL;
5353 zebra_mac_t *zrmac = NULL;
5354
5355 zl3vni = zl3vni_from_vrf(vrf_id);
5356 if (!zl3vni)
5357 return;
5358
5359 /* find the next hop entry and rmac entry */
5360 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
5361 if (!nh)
5362 return;
5363 zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
5364
5365 /* delete the next hop entry */
5366 zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
5367
5368 /* delete the rmac entry */
5369 if (zrmac)
5370 zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix);
5371
5372 }
5373
5374 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
5375 struct ethaddr *rmac, bool use_json)
5376 {
5377 zebra_l3vni_t *zl3vni = NULL;
5378 zebra_mac_t *zrmac = NULL;
5379 json_object *json = NULL;
5380
5381 if (!is_evpn_enabled()) {
5382 if (use_json)
5383 vty_out(vty, "{}\n");
5384 return;
5385 }
5386
5387 if (use_json)
5388 json = json_object_new_object();
5389
5390 zl3vni = zl3vni_lookup(l3vni);
5391 if (!zl3vni) {
5392 if (use_json)
5393 vty_out(vty, "{}\n");
5394 else
5395 vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
5396 return;
5397 }
5398
5399 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
5400 if (!zrmac) {
5401 if (use_json)
5402 vty_out(vty, "{}\n");
5403 else
5404 vty_out(vty,
5405 "%% Requested RMAC doesn't exist in L3-VNI %u",
5406 l3vni);
5407 return;
5408 }
5409
5410 zl3vni_print_rmac(zrmac, vty, json);
5411
5412 if (use_json) {
5413 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5414 json, JSON_C_TO_STRING_PRETTY));
5415 json_object_free(json);
5416 }
5417 }
5418
5419 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
5420 {
5421 zebra_l3vni_t *zl3vni;
5422 uint32_t num_rmacs;
5423 struct rmac_walk_ctx wctx;
5424 json_object *json = NULL;
5425
5426 if (!is_evpn_enabled())
5427 return;
5428
5429 zl3vni = zl3vni_lookup(l3vni);
5430 if (!zl3vni) {
5431 if (use_json)
5432 vty_out(vty, "{}\n");
5433 else
5434 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5435 return;
5436 }
5437 num_rmacs = hashcount(zl3vni->rmac_table);
5438 if (!num_rmacs)
5439 return;
5440
5441 if (use_json)
5442 json = json_object_new_object();
5443
5444 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
5445 wctx.vty = vty;
5446 wctx.json = json;
5447 if (!use_json) {
5448 vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
5449 num_rmacs);
5450 vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
5451 } else
5452 json_object_int_add(json, "numRmacs", num_rmacs);
5453
5454 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
5455
5456 if (use_json) {
5457 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5458 json, JSON_C_TO_STRING_PRETTY));
5459 json_object_free(json);
5460 }
5461 }
5462
5463 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
5464 {
5465 json_object *json = NULL;
5466 void *args[2];
5467
5468 if (!is_evpn_enabled()) {
5469 if (use_json)
5470 vty_out(vty, "{}\n");
5471 return;
5472 }
5473
5474 if (use_json)
5475 json = json_object_new_object();
5476
5477 args[0] = vty;
5478 args[1] = json;
5479 hash_iterate(zrouter.l3vni_table,
5480 (void (*)(struct hash_backet *,
5481 void *))zl3vni_print_rmac_hash_all_vni,
5482 args);
5483
5484 if (use_json) {
5485 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5486 json, JSON_C_TO_STRING_PRETTY));
5487 json_object_free(json);
5488 }
5489 }
5490
5491 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
5492 struct ipaddr *ip, bool use_json)
5493 {
5494 zebra_l3vni_t *zl3vni = NULL;
5495 zebra_neigh_t *n = NULL;
5496 json_object *json = NULL;
5497
5498 if (!is_evpn_enabled()) {
5499 if (use_json)
5500 vty_out(vty, "{}\n");
5501 return;
5502 }
5503
5504 if (use_json)
5505 json = json_object_new_object();
5506
5507 zl3vni = zl3vni_lookup(l3vni);
5508 if (!zl3vni) {
5509 if (use_json)
5510 vty_out(vty, "{}\n");
5511 else
5512 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5513 return;
5514 }
5515
5516 n = zl3vni_nh_lookup(zl3vni, ip);
5517 if (!n) {
5518 if (use_json)
5519 vty_out(vty, "{}\n");
5520 else
5521 vty_out(vty,
5522 "%% Requested next-hop not present for L3-VNI %u",
5523 l3vni);
5524 return;
5525 }
5526
5527 zl3vni_print_nh(n, vty, json);
5528
5529 if (use_json) {
5530 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5531 json, JSON_C_TO_STRING_PRETTY));
5532 json_object_free(json);
5533 }
5534 }
5535
5536 void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
5537 {
5538 uint32_t num_nh;
5539 struct nh_walk_ctx wctx;
5540 json_object *json = NULL;
5541 zebra_l3vni_t *zl3vni = NULL;
5542
5543 if (!is_evpn_enabled())
5544 return;
5545
5546 zl3vni = zl3vni_lookup(l3vni);
5547 if (!zl3vni) {
5548 if (use_json)
5549 vty_out(vty, "{}\n");
5550 else
5551 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5552 return;
5553 }
5554
5555 num_nh = hashcount(zl3vni->nh_table);
5556 if (!num_nh)
5557 return;
5558
5559 if (use_json)
5560 json = json_object_new_object();
5561
5562 wctx.vty = vty;
5563 wctx.json = json;
5564 if (!use_json) {
5565 vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
5566 num_nh);
5567 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
5568 } else
5569 json_object_int_add(json, "numNextHops", num_nh);
5570
5571 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
5572
5573 if (use_json) {
5574 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5575 json, JSON_C_TO_STRING_PRETTY));
5576 json_object_free(json);
5577 }
5578 }
5579
5580 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
5581 {
5582 json_object *json = NULL;
5583 void *args[2];
5584
5585 if (!is_evpn_enabled()) {
5586 if (use_json)
5587 vty_out(vty, "{}\n");
5588 return;
5589 }
5590
5591 if (use_json)
5592 json = json_object_new_object();
5593
5594 args[0] = vty;
5595 args[1] = json;
5596 hash_iterate(zrouter.l3vni_table,
5597 (void (*)(struct hash_backet *,
5598 void *))zl3vni_print_nh_hash_all_vni,
5599 args);
5600
5601 if (use_json) {
5602 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5603 json, JSON_C_TO_STRING_PRETTY));
5604 json_object_free(json);
5605 }
5606 }
5607
5608 /*
5609 * Display L3 VNI information (VTY command handler).
5610 */
5611 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
5612 {
5613 void *args[2];
5614 json_object *json = NULL;
5615 zebra_l3vni_t *zl3vni = NULL;
5616
5617 if (!is_evpn_enabled()) {
5618 if (use_json)
5619 vty_out(vty, "{}\n");
5620 return;
5621 }
5622
5623 zl3vni = zl3vni_lookup(vni);
5624 if (!zl3vni) {
5625 if (use_json)
5626 vty_out(vty, "{}\n");
5627 else
5628 vty_out(vty, "%% VNI %u does not exist\n", vni);
5629 return;
5630 }
5631
5632 if (use_json)
5633 json = json_object_new_object();
5634
5635 args[0] = vty;
5636 args[1] = json;
5637 zl3vni_print(zl3vni, (void *)args);
5638
5639 if (use_json) {
5640 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5641 json, JSON_C_TO_STRING_PRETTY));
5642 json_object_free(json);
5643 }
5644 }
5645
5646 void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
5647 json_object *json_vrfs)
5648 {
5649 char buf[ETHER_ADDR_STRLEN];
5650 zebra_l3vni_t *zl3vni = NULL;
5651
5652 zl3vni = zl3vni_lookup(zvrf->l3vni);
5653 if (!zl3vni)
5654 return;
5655
5656 if (!json_vrfs) {
5657 vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
5658 zvrf_name(zvrf), zl3vni->vni,
5659 zl3vni_vxlan_if_name(zl3vni),
5660 zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
5661 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
5662 } else {
5663 json_object *json_vrf = NULL;
5664
5665 json_vrf = json_object_new_object();
5666 json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
5667 json_object_int_add(json_vrf, "vni", zl3vni->vni);
5668 json_object_string_add(json_vrf, "vxlanIntf",
5669 zl3vni_vxlan_if_name(zl3vni));
5670 json_object_string_add(json_vrf, "sviIntf",
5671 zl3vni_svi_if_name(zl3vni));
5672 json_object_string_add(json_vrf, "state",
5673 zl3vni_state2str(zl3vni));
5674 json_object_string_add(
5675 json_vrf, "routerMac",
5676 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
5677 json_object_array_add(json_vrfs, json_vrf);
5678 }
5679 }
5680
5681 /*
5682 * Display Neighbors for a VNI (VTY command handler).
5683 */
5684 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
5685 vni_t vni, bool use_json)
5686 {
5687 zebra_vni_t *zvni;
5688 uint32_t num_neigh;
5689 struct neigh_walk_ctx wctx;
5690 json_object *json = NULL;
5691
5692 if (!is_evpn_enabled())
5693 return;
5694 zvni = zvni_lookup(vni);
5695 if (!zvni) {
5696 if (use_json)
5697 vty_out(vty, "{}\n");
5698 else
5699 vty_out(vty, "%% VNI %u does not exist\n", vni);
5700 return;
5701 }
5702 num_neigh = hashcount(zvni->neigh_table);
5703 if (!num_neigh)
5704 return;
5705
5706 if (use_json)
5707 json = json_object_new_object();
5708
5709 /* Since we have IPv6 addresses to deal with which can vary widely in
5710 * size, we try to be a bit more elegant in display by first computing
5711 * the maximum width.
5712 */
5713 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
5714 wctx.zvni = zvni;
5715 wctx.vty = vty;
5716 wctx.addr_width = 15;
5717 wctx.json = json;
5718 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
5719
5720 if (!use_json) {
5721 vty_out(vty,
5722 "Number of ARPs (local and remote) known for this VNI: %u\n",
5723 num_neigh);
5724 vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
5725 -wctx.addr_width, "IP", "Type",
5726 "State", "MAC", "Remote VTEP");
5727 } else
5728 json_object_int_add(json, "numArpNd", num_neigh);
5729
5730 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
5731 if (use_json) {
5732 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5733 json, JSON_C_TO_STRING_PRETTY));
5734 json_object_free(json);
5735 }
5736 }
5737
5738 /*
5739 * Display neighbors across all VNIs (VTY command handler).
5740 */
5741 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
5742 bool print_dup, bool use_json)
5743 {
5744 json_object *json = NULL;
5745 void *args[3];
5746
5747 if (!is_evpn_enabled())
5748 return;
5749
5750 if (use_json)
5751 json = json_object_new_object();
5752
5753 args[0] = vty;
5754 args[1] = json;
5755 args[2] = (void *)(ptrdiff_t)print_dup;
5756
5757 hash_iterate(zvrf->vni_table,
5758 (void (*)(struct hash_backet *,
5759 void *))zvni_print_neigh_hash_all_vni,
5760 args);
5761 if (use_json) {
5762 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5763 json, JSON_C_TO_STRING_PRETTY));
5764 json_object_free(json);
5765 }
5766 }
5767
5768 /*
5769 * Display specific neighbor for a VNI, if present (VTY command handler).
5770 */
5771 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
5772 struct zebra_vrf *zvrf, vni_t vni,
5773 struct ipaddr *ip, bool use_json)
5774 {
5775 zebra_vni_t *zvni;
5776 zebra_neigh_t *n;
5777 json_object *json = NULL;
5778
5779 if (!is_evpn_enabled())
5780 return;
5781 zvni = zvni_lookup(vni);
5782 if (!zvni) {
5783 if (use_json)
5784 vty_out(vty, "{}\n");
5785 else
5786 vty_out(vty, "%% VNI %u does not exist\n", vni);
5787 return;
5788 }
5789 n = zvni_neigh_lookup(zvni, ip);
5790 if (!n) {
5791 if (!use_json)
5792 vty_out(vty,
5793 "%% Requested neighbor does not exist in VNI %u\n",
5794 vni);
5795 return;
5796 }
5797 if (use_json)
5798 json = json_object_new_object();
5799
5800 zvni_print_neigh(n, vty, json);
5801
5802 if (use_json) {
5803 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5804 json, JSON_C_TO_STRING_PRETTY));
5805 json_object_free(json);
5806 }
5807 }
5808
5809 /*
5810 * Display neighbors for a VNI from specific VTEP (VTY command handler).
5811 * By definition, these are remote neighbors.
5812 */
5813 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
5814 vni_t vni, struct in_addr vtep_ip,
5815 bool use_json)
5816 {
5817 zebra_vni_t *zvni;
5818 uint32_t num_neigh;
5819 struct neigh_walk_ctx wctx;
5820 json_object *json = NULL;
5821
5822 if (!is_evpn_enabled())
5823 return;
5824 zvni = zvni_lookup(vni);
5825 if (!zvni) {
5826 if (use_json)
5827 vty_out(vty, "{}\n");
5828 else
5829 vty_out(vty, "%% VNI %u does not exist\n", vni);
5830 return;
5831 }
5832 num_neigh = hashcount(zvni->neigh_table);
5833 if (!num_neigh)
5834 return;
5835
5836 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
5837 wctx.zvni = zvni;
5838 wctx.vty = vty;
5839 wctx.addr_width = 15;
5840 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
5841 wctx.r_vtep_ip = vtep_ip;
5842 wctx.json = json;
5843 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
5844 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
5845
5846 if (use_json) {
5847 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5848 json, JSON_C_TO_STRING_PRETTY));
5849 json_object_free(json);
5850 }
5851 }
5852
5853 /*
5854 * Display Duplicate detected Neighbors for a VNI
5855 * (VTY command handler).
5856 */
5857 void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
5858 struct zebra_vrf *zvrf,
5859 vni_t vni,
5860 bool use_json)
5861 {
5862 zebra_vni_t *zvni;
5863 uint32_t num_neigh;
5864 struct neigh_walk_ctx wctx;
5865 json_object *json = NULL;
5866
5867 if (!is_evpn_enabled())
5868 return;
5869
5870 zvni = zvni_lookup(vni);
5871 if (!zvni) {
5872 vty_out(vty, "%% VNI %u does not exist\n", vni);
5873 return;
5874 }
5875
5876 num_neigh = hashcount(zvni->neigh_table);
5877 if (!num_neigh)
5878 return;
5879
5880 num_neigh = num_dup_detected_neighs(zvni);
5881 if (!num_neigh)
5882 return;
5883
5884 if (use_json)
5885 json = json_object_new_object();
5886
5887 /* Since we have IPv6 addresses to deal with which can vary widely in
5888 * size, we try to be a bit more elegant in display by first computing
5889 * the maximum width.
5890 */
5891 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
5892 wctx.zvni = zvni;
5893 wctx.vty = vty;
5894 wctx.addr_width = 15;
5895 wctx.json = json;
5896 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
5897
5898 if (!use_json) {
5899 vty_out(vty,
5900 "Number of ARPs (local and remote) known for this VNI: %u\n",
5901 num_neigh);
5902 vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
5903 -wctx.addr_width, "IP", "Type",
5904 "State", "MAC", "Remote VTEP");
5905 } else
5906 json_object_int_add(json, "numArpNd", num_neigh);
5907
5908 hash_iterate(zvni->neigh_table, zvni_print_dad_neigh_hash, &wctx);
5909
5910 if (use_json) {
5911 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5912 json, JSON_C_TO_STRING_PRETTY));
5913 json_object_free(json);
5914 }
5915 }
5916
5917 /*
5918 * Display MACs for a VNI (VTY command handler).
5919 */
5920 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
5921 vni_t vni, bool use_json)
5922 {
5923 zebra_vni_t *zvni;
5924 uint32_t num_macs;
5925 struct mac_walk_ctx wctx;
5926 json_object *json = NULL;
5927 json_object *json_mac = NULL;
5928
5929 if (!is_evpn_enabled())
5930 return;
5931 zvni = zvni_lookup(vni);
5932 if (!zvni) {
5933 if (use_json)
5934 vty_out(vty, "{}\n");
5935 else
5936 vty_out(vty, "%% VNI %u does not exist\n", vni);
5937 return;
5938 }
5939 num_macs = num_valid_macs(zvni);
5940 if (!num_macs)
5941 return;
5942
5943 if (use_json) {
5944 json = json_object_new_object();
5945 json_mac = json_object_new_object();
5946 }
5947
5948 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
5949 wctx.zvni = zvni;
5950 wctx.vty = vty;
5951 wctx.json = json_mac;
5952
5953 if (!use_json) {
5954 vty_out(vty,
5955 "Number of MACs (local and remote) known for this VNI: %u\n",
5956 num_macs);
5957 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
5958 "Intf/Remote VTEP", "VLAN");
5959 } else
5960 json_object_int_add(json, "numMacs", num_macs);
5961
5962 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
5963
5964 if (use_json) {
5965 json_object_object_add(json, "macs", json_mac);
5966 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5967 json, JSON_C_TO_STRING_PRETTY));
5968 json_object_free(json);
5969 }
5970 }
5971
5972 /*
5973 * Display MACs for all VNIs (VTY command handler).
5974 */
5975 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
5976 bool print_dup, bool use_json)
5977 {
5978 struct mac_walk_ctx wctx;
5979 json_object *json = NULL;
5980
5981 if (!is_evpn_enabled()) {
5982 if (use_json)
5983 vty_out(vty, "{}\n");
5984 return;
5985 }
5986 if (use_json)
5987 json = json_object_new_object();
5988
5989 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
5990 wctx.vty = vty;
5991 wctx.json = json;
5992 wctx.print_dup = print_dup;
5993 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
5994
5995 if (use_json) {
5996 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5997 json, JSON_C_TO_STRING_PRETTY));
5998 json_object_free(json);
5999 }
6000 }
6001
6002 /*
6003 * Display MACs in detail for all VNIs (VTY command handler).
6004 */
6005 void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
6006 struct zebra_vrf *zvrf,
6007 bool print_dup, bool use_json)
6008 {
6009 struct mac_walk_ctx wctx;
6010 json_object *json = NULL;
6011
6012 if (!is_evpn_enabled()) {
6013 if (use_json)
6014 vty_out(vty, "{}\n");
6015 return;
6016 }
6017 if (use_json)
6018 json = json_object_new_object();
6019
6020 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6021 wctx.vty = vty;
6022 wctx.json = json;
6023 wctx.print_dup = print_dup;
6024 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni_detail,
6025 &wctx);
6026
6027 if (use_json) {
6028 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6029 json, JSON_C_TO_STRING_PRETTY));
6030 json_object_free(json);
6031 }
6032 }
6033
6034 /*
6035 * Display MACs for all VNIs (VTY command handler).
6036 */
6037 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
6038 struct zebra_vrf *zvrf,
6039 struct in_addr vtep_ip, bool use_json)
6040 {
6041 struct mac_walk_ctx wctx;
6042 json_object *json = NULL;
6043
6044 if (!is_evpn_enabled())
6045 return;
6046
6047 if (use_json)
6048 json = json_object_new_object();
6049
6050 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6051 wctx.vty = vty;
6052 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
6053 wctx.r_vtep_ip = vtep_ip;
6054 wctx.json = json;
6055 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
6056
6057 if (use_json) {
6058 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6059 json, JSON_C_TO_STRING_PRETTY));
6060 json_object_free(json);
6061 }
6062 }
6063
6064 /*
6065 * Display specific MAC for a VNI, if present (VTY command handler).
6066 */
6067 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
6068 vni_t vni, struct ethaddr *macaddr,
6069 bool use_json)
6070 {
6071 zebra_vni_t *zvni;
6072 zebra_mac_t *mac;
6073 json_object *json = NULL;
6074
6075 if (!is_evpn_enabled())
6076 return;
6077
6078 zvni = zvni_lookup(vni);
6079 if (!zvni) {
6080 if (use_json)
6081 vty_out(vty, "{}\n");
6082 else
6083 vty_out(vty, "%% VNI %u does not exist\n", vni);
6084 return;
6085 }
6086 mac = zvni_mac_lookup(zvni, macaddr);
6087 if (!mac) {
6088 if (use_json)
6089 vty_out(vty, "{}\n");
6090 else
6091 vty_out(vty,
6092 "%% Requested MAC does not exist in VNI %u\n",
6093 vni);
6094 return;
6095 }
6096
6097 if (use_json)
6098 json = json_object_new_object();
6099
6100 zvni_print_mac(mac, vty, json);
6101 if (use_json) {
6102 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6103 json, JSON_C_TO_STRING_PRETTY));
6104 json_object_free(json);
6105 }
6106 }
6107
6108 /* Print Duplicate MACs per VNI */
6109 void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
6110 struct zebra_vrf *zvrf,
6111 vni_t vni, bool use_json)
6112 {
6113 zebra_vni_t *zvni;
6114 struct mac_walk_ctx wctx;
6115 uint32_t num_macs;
6116 json_object *json = NULL;
6117 json_object *json_mac = NULL;
6118
6119 if (!is_evpn_enabled())
6120 return;
6121
6122 zvni = zvni_lookup(vni);
6123 if (!zvni) {
6124 vty_out(vty, "%% VNI %u does not exist\n", vni);
6125 return;
6126 }
6127
6128 num_macs = num_valid_macs(zvni);
6129 if (!num_macs)
6130 return;
6131
6132 num_macs = num_dup_detected_macs(zvni);
6133 if (!num_macs)
6134 return;
6135
6136 if (use_json) {
6137 json = json_object_new_object();
6138 json_mac = json_object_new_object();
6139 }
6140
6141 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6142 wctx.zvni = zvni;
6143 wctx.vty = vty;
6144 wctx.json = json_mac;
6145
6146 if (!use_json) {
6147 vty_out(vty,
6148 "Number of MACs (local and remote) known for this VNI: %u\n",
6149 num_macs);
6150 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
6151 "Intf/Remote VTEP", "VLAN");
6152 } else
6153 json_object_int_add(json, "numMacs", num_macs);
6154
6155 hash_iterate(zvni->mac_table, zvni_print_dad_mac_hash, &wctx);
6156
6157 if (use_json) {
6158 json_object_object_add(json, "macs", json_mac);
6159 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6160 json, JSON_C_TO_STRING_PRETTY));
6161 json_object_free(json);
6162 }
6163
6164 }
6165
6166 void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
6167 struct zebra_vrf *zvrf,
6168 vni_t vni, struct ethaddr *macaddr)
6169 {
6170 zebra_vni_t *zvni;
6171 zebra_mac_t *mac;
6172 struct listnode *node = NULL;
6173 zebra_neigh_t *nbr = NULL;
6174
6175 if (!is_evpn_enabled())
6176 return;
6177 zvni = zvni_lookup(vni);
6178 if (!zvni) {
6179 vty_out(vty, "%% VNI %u does not exist\n", vni);
6180 return;
6181 }
6182
6183 mac = zvni_mac_lookup(zvni, macaddr);
6184 if (!mac) {
6185 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
6186 vni);
6187 return;
6188 }
6189
6190 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
6191 vty_out(vty, "%% Requested MAC is not duplicate detected\n");
6192 return;
6193 }
6194
6195 /* Remove all IPs as duplicate associcated with this MAC */
6196 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
6197 /* For local neigh mark inactive so MACIP update is generated
6198 * to BGP. This is a scenario where MAC update received
6199 * and detected as duplicate which marked neigh as duplicate.
6200 * Later local neigh update did not get a chance to relay
6201 * to BGP. Similarly remote macip update, neigh needs to be
6202 * installed locally.
6203 */
6204 if (nbr->dad_count) {
6205 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
6206 ZEBRA_NEIGH_SET_INACTIVE(nbr);
6207 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
6208 zvni_neigh_install(zvni, nbr);
6209 }
6210
6211 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6212 nbr->dad_count = 0;
6213 nbr->detect_start_time.tv_sec = 0;
6214 nbr->dad_dup_detect_time = 0;
6215 }
6216
6217 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
6218 mac->dad_count = 0;
6219 mac->detect_start_time.tv_sec = 0;
6220 mac->detect_start_time.tv_usec = 0;
6221 mac->dad_dup_detect_time = 0;
6222 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
6223
6224 /* Local: Notify Peer VTEPs, Remote: Install the entry */
6225 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
6226 /* Inform to BGP */
6227 if (zvni_mac_send_add_to_client(zvni->vni,
6228 &mac->macaddr,
6229 mac->flags,
6230 mac->loc_seq))
6231 return;
6232
6233 /* Process all neighbors associated with this MAC. */
6234 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
6235
6236 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
6237 zvni_process_neigh_on_remote_mac_add(zvni, mac);
6238
6239 /* Install the entry. */
6240 zvni_mac_install(zvni, mac);
6241 }
6242
6243 }
6244
6245 void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
6246 struct zebra_vrf *zvrf,
6247 vni_t vni, struct ipaddr *ip)
6248 {
6249 zebra_vni_t *zvni;
6250 zebra_neigh_t *nbr;
6251 zebra_mac_t *mac;
6252 char buf[INET6_ADDRSTRLEN];
6253 char buf2[ETHER_ADDR_STRLEN];
6254
6255 if (!is_evpn_enabled())
6256 return;
6257
6258 zvni = zvni_lookup(vni);
6259 if (!zvni) {
6260 vty_out(vty, "%% VNI %u does not exist\n", vni);
6261 return;
6262 }
6263
6264 nbr = zvni_neigh_lookup(zvni, ip);
6265 if (!nbr) {
6266 vty_out(vty,
6267 "%% Requested host IP does not exist in VNI %u\n",
6268 vni);
6269 return;
6270 }
6271
6272 ipaddr2str(&nbr->ip, buf, sizeof(buf));
6273
6274 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
6275 vty_out(vty,
6276 "%% Requsted host IP %s is not duplicate detected\n",
6277 buf);
6278 return;
6279 }
6280
6281 mac = zvni_mac_lookup(zvni, &nbr->emac);
6282
6283 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
6284 vty_out(vty,
6285 "%% Requested IP's associated MAC %s is still in duplicate state\n",
6286 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
6287 return;
6288 }
6289
6290 if (IS_ZEBRA_DEBUG_VXLAN)
6291 zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
6292 __PRETTY_FUNCTION__, buf, nbr->flags,
6293 nbr->loc_seq);
6294
6295 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6296 nbr->dad_count = 0;
6297 nbr->detect_start_time.tv_sec = 0;
6298 nbr->detect_start_time.tv_usec = 0;
6299 nbr->dad_dup_detect_time = 0;
6300 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
6301
6302 if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
6303 zvni_neigh_send_add_to_client(zvni->vni, ip,
6304 &nbr->emac,
6305 nbr->flags, nbr->loc_seq);
6306 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
6307 zvni_neigh_install(zvni, nbr);
6308 }
6309
6310 }
6311
6312 static void zvni_clear_dup_mac_hash(struct hash_backet *backet, void *ctxt)
6313 {
6314 struct mac_walk_ctx *wctx = ctxt;
6315 zebra_mac_t *mac;
6316 zebra_vni_t *zvni;
6317 struct listnode *node = NULL;
6318 zebra_neigh_t *nbr = NULL;
6319
6320 mac = (zebra_mac_t *)backet->data;
6321 if (!mac)
6322 return;
6323
6324 zvni = wctx->zvni;
6325
6326 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
6327 return;
6328
6329 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
6330 mac->dad_count = 0;
6331 mac->detect_start_time.tv_sec = 0;
6332 mac->detect_start_time.tv_usec = 0;
6333 mac->dad_dup_detect_time = 0;
6334 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
6335
6336 /* Remove all IPs as duplicate associcated with this MAC */
6337 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
6338 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
6339 && nbr->dad_count)
6340 ZEBRA_NEIGH_SET_INACTIVE(nbr);
6341
6342 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6343 nbr->dad_count = 0;
6344 nbr->detect_start_time.tv_sec = 0;
6345 nbr->dad_dup_detect_time = 0;
6346 }
6347
6348 /* Local: Notify Peer VTEPs, Remote: Install the entry */
6349 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
6350 /* Inform to BGP */
6351 if (zvni_mac_send_add_to_client(zvni->vni,
6352 &mac->macaddr,
6353 mac->flags, mac->loc_seq))
6354 return;
6355
6356 /* Process all neighbors associated with this MAC. */
6357 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
6358
6359 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
6360 zvni_process_neigh_on_remote_mac_add(zvni, mac);
6361
6362 /* Install the entry. */
6363 zvni_mac_install(zvni, mac);
6364 }
6365 }
6366
6367 static void zvni_clear_dup_neigh_hash(struct hash_backet *backet, void *ctxt)
6368 {
6369 struct neigh_walk_ctx *wctx = ctxt;
6370 zebra_neigh_t *nbr;
6371 zebra_vni_t *zvni;
6372 char buf[INET6_ADDRSTRLEN];
6373
6374 nbr = (zebra_neigh_t *)backet->data;
6375 if (!nbr)
6376 return;
6377
6378 zvni = wctx->zvni;
6379
6380 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
6381 return;
6382
6383 if (IS_ZEBRA_DEBUG_VXLAN) {
6384 ipaddr2str(&nbr->ip, buf, sizeof(buf));
6385 zlog_debug(
6386 "%s: clear neigh %s dup state, flags 0x%x seq %u",
6387 __PRETTY_FUNCTION__, buf,
6388 nbr->flags, nbr->loc_seq);
6389 }
6390
6391 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6392 nbr->dad_count = 0;
6393 nbr->detect_start_time.tv_sec = 0;
6394 nbr->detect_start_time.tv_usec = 0;
6395 nbr->dad_dup_detect_time = 0;
6396 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
6397
6398 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
6399 zvni_neigh_send_add_to_client(zvni->vni, &nbr->ip,
6400 &nbr->emac,
6401 nbr->flags, nbr->loc_seq);
6402 } else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
6403 zvni_neigh_install(zvni, nbr);
6404 }
6405 }
6406
6407 static void zvni_clear_dup_detect_hash_vni_all(struct hash_backet *backet,
6408 void **args)
6409 {
6410 struct vty *vty;
6411 zebra_vni_t *zvni;
6412 struct zebra_vrf *zvrf;
6413 struct mac_walk_ctx m_wctx;
6414 struct neigh_walk_ctx n_wctx;
6415
6416 zvni = (zebra_vni_t *)backet->data;
6417 if (!zvni)
6418 return;
6419
6420 vty = (struct vty *)args[0];
6421 zvrf = (struct zebra_vrf *)args[1];
6422
6423 if (hashcount(zvni->neigh_table)) {
6424 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6425 n_wctx.vty = vty;
6426 n_wctx.zvni = zvni;
6427 n_wctx.zvrf = zvrf;
6428 hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash,
6429 &n_wctx);
6430 }
6431
6432 if (num_valid_macs(zvni)) {
6433 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6434 m_wctx.zvni = zvni;
6435 m_wctx.vty = vty;
6436 m_wctx.zvrf = zvrf;
6437 hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
6438 }
6439
6440 }
6441
6442 void zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
6443 struct zebra_vrf *zvrf)
6444 {
6445 void *args[2];
6446
6447 if (!is_evpn_enabled())
6448 return;
6449
6450 args[0] = vty;
6451 args[1] = zvrf;
6452
6453 hash_iterate(zvrf->vni_table,
6454 (void (*)(struct hash_backet *, void *))
6455 zvni_clear_dup_detect_hash_vni_all, args);
6456
6457 }
6458
6459 void zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
6460 struct zebra_vrf *zvrf,
6461 vni_t vni)
6462 {
6463 zebra_vni_t *zvni;
6464 struct mac_walk_ctx m_wctx;
6465 struct neigh_walk_ctx n_wctx;
6466
6467 if (!is_evpn_enabled())
6468 return;
6469
6470 zvni = zvni_lookup(vni);
6471 if (!zvni) {
6472 vty_out(vty, "%% VNI %u does not exist\n", vni);
6473 return;
6474 }
6475
6476 if (hashcount(zvni->neigh_table)) {
6477 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6478 n_wctx.vty = vty;
6479 n_wctx.zvni = zvni;
6480 n_wctx.zvrf = zvrf;
6481 hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash,
6482 &n_wctx);
6483 }
6484
6485 if (num_valid_macs(zvni)) {
6486 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6487 m_wctx.zvni = zvni;
6488 m_wctx.vty = vty;
6489 m_wctx.zvrf = zvrf;
6490 hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
6491 }
6492
6493 }
6494
6495 /*
6496 * Display MACs for a VNI from specific VTEP (VTY command handler).
6497 */
6498 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
6499 vni_t vni, struct in_addr vtep_ip,
6500 bool use_json)
6501 {
6502 zebra_vni_t *zvni;
6503 uint32_t num_macs;
6504 struct mac_walk_ctx wctx;
6505 json_object *json = NULL;
6506 json_object *json_mac = NULL;
6507
6508 if (!is_evpn_enabled())
6509 return;
6510 zvni = zvni_lookup(vni);
6511 if (!zvni) {
6512 if (use_json)
6513 vty_out(vty, "{}\n");
6514 else
6515 vty_out(vty, "%% VNI %u does not exist\n", vni);
6516 return;
6517 }
6518 num_macs = num_valid_macs(zvni);
6519 if (!num_macs)
6520 return;
6521
6522 if (use_json) {
6523 json = json_object_new_object();
6524 json_mac = json_object_new_object();
6525 }
6526
6527 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6528 wctx.zvni = zvni;
6529 wctx.vty = vty;
6530 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
6531 wctx.r_vtep_ip = vtep_ip;
6532 wctx.json = json_mac;
6533 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
6534
6535 if (use_json) {
6536 json_object_int_add(json, "numMacs", wctx.count);
6537 if (wctx.count)
6538 json_object_object_add(json, "macs", json_mac);
6539 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6540 json, JSON_C_TO_STRING_PRETTY));
6541 json_object_free(json);
6542 }
6543 }
6544
6545
6546 /*
6547 * Display VNI information (VTY command handler).
6548 */
6549 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
6550 bool use_json)
6551 {
6552 json_object *json = NULL;
6553 void *args[2];
6554 zebra_l3vni_t *zl3vni = NULL;
6555 zebra_vni_t *zvni = NULL;
6556
6557 if (!is_evpn_enabled())
6558 return;
6559
6560 if (use_json)
6561 json = json_object_new_object();
6562 args[0] = vty;
6563 args[1] = json;
6564
6565 zl3vni = zl3vni_lookup(vni);
6566 if (zl3vni) {
6567 zl3vni_print(zl3vni, (void *)args);
6568 } else {
6569 zvni = zvni_lookup(vni);
6570 if (!zvni) {
6571 if (use_json)
6572 vty_out(vty, "{}\n");
6573 else
6574 vty_out(vty, "%% VNI %u does not exist\n", vni);
6575 return;
6576 }
6577
6578 zvni_print(zvni, (void *)args);
6579 }
6580
6581 if (use_json) {
6582 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6583 json, JSON_C_TO_STRING_PRETTY));
6584 json_object_free(json);
6585 }
6586 }
6587
6588 /* Display all global details for EVPN */
6589 void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
6590 {
6591 int num_l2vnis = 0;
6592 int num_l3vnis = 0;
6593 int num_vnis = 0;
6594 json_object *json = NULL;
6595 struct zebra_vrf *zvrf = NULL;
6596
6597 if (!is_evpn_enabled())
6598 return;
6599
6600 zvrf = vrf_info_lookup(VRF_DEFAULT);
6601 if (!zvrf)
6602 return;
6603
6604 num_l3vnis = hashcount(zrouter.l3vni_table);
6605 num_l2vnis = hashcount(zvrf->vni_table);
6606 num_vnis = num_l2vnis + num_l3vnis;
6607
6608 if (uj) {
6609 json = json_object_new_object();
6610 json_object_string_add(json, "advertiseGatewayMacip",
6611 zvrf->advertise_gw_macip ? "Yes" : "No");
6612 json_object_int_add(json, "numVnis", num_vnis);
6613 json_object_int_add(json, "numL2Vnis", num_l2vnis);
6614 json_object_int_add(json, "numL3Vnis", num_l3vnis);
6615 if (zvrf->dup_addr_detect)
6616 json_object_boolean_true_add(json,
6617 "isDuplicateAddrDetection");
6618 else
6619 json_object_boolean_false_add(json,
6620 "isDuplicateAddrDetection");
6621 json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
6622 json_object_int_add(json, "detectionTime", zvrf->dad_time);
6623 json_object_int_add(json, "detectionFreezeTime",
6624 zvrf->dad_freeze_time);
6625
6626 } else {
6627 vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
6628 vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
6629 vty_out(vty, "Advertise gateway mac-ip: %s\n",
6630 zvrf->advertise_gw_macip ? "Yes" : "No");
6631 vty_out(vty, "Duplicate address detection: %s\n",
6632 zvrf->dup_addr_detect ? "Enable" : "Disable");
6633 vty_out(vty, " Detection max-moves %u, time %d\n",
6634 zvrf->dad_max_moves, zvrf->dad_time);
6635 if (zvrf->dad_freeze) {
6636 if (zvrf->dad_freeze_time)
6637 vty_out(vty, " Detection freeze %u\n",
6638 zvrf->dad_freeze_time);
6639 else
6640 vty_out(vty, " Detection freeze %s\n",
6641 "permanent");
6642 }
6643 }
6644
6645 if (uj) {
6646 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6647 json, JSON_C_TO_STRING_PRETTY));
6648 json_object_free(json);
6649 }
6650 }
6651
6652 /*
6653 * Display VNI hash table (VTY command handler).
6654 */
6655 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
6656 bool use_json)
6657 {
6658 json_object *json = NULL;
6659 void *args[2];
6660
6661 if (!is_evpn_enabled())
6662 return;
6663
6664 if (use_json)
6665 json = json_object_new_object();
6666 else
6667 vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
6668 "Type", "VxLAN IF", "# MACs", "# ARPs",
6669 "# Remote VTEPs", "Tenant VRF");
6670
6671 args[0] = vty;
6672 args[1] = json;
6673
6674 /* Display all L2-VNIs */
6675 hash_iterate(zvrf->vni_table,
6676 (void (*)(struct hash_backet *, void *))zvni_print_hash,
6677 args);
6678
6679 /* Display all L3-VNIs */
6680 hash_iterate(zrouter.l3vni_table,
6681 (void (*)(struct hash_backet *, void *))zl3vni_print_hash,
6682 args);
6683
6684 if (use_json) {
6685 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6686 json, JSON_C_TO_STRING_PRETTY));
6687 json_object_free(json);
6688 }
6689 }
6690
6691 void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
6692 {
6693 struct stream *s;
6694 int time = 0;
6695 uint32_t max_moves = 0;
6696 uint32_t freeze_time = 0;
6697 bool dup_addr_detect = false;
6698 bool freeze = false;
6699
6700 s = msg;
6701 STREAM_GETL(s, dup_addr_detect);
6702 STREAM_GETL(s, time);
6703 STREAM_GETL(s, max_moves);
6704 STREAM_GETL(s, freeze);
6705 STREAM_GETL(s, freeze_time);
6706
6707 /* DAD previous state was enabled, and new state is disable,
6708 * clear all duplicate detected addresses.
6709 */
6710 if (zvrf->dup_addr_detect && !dup_addr_detect)
6711 zebra_vxlan_clear_dup_detect_vni_all(NULL, zvrf);
6712
6713 zvrf->dup_addr_detect = dup_addr_detect;
6714 zvrf->dad_time = time;
6715 zvrf->dad_max_moves = max_moves;
6716 zvrf->dad_freeze = freeze;
6717 zvrf->dad_freeze_time = freeze_time;
6718
6719 if (IS_ZEBRA_DEBUG_VXLAN)
6720 zlog_debug(
6721 "%s: duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
6722 __PRETTY_FUNCTION__,
6723 zvrf->dup_addr_detect ? "enable" : "disable",
6724 zvrf->dad_max_moves,
6725 zvrf->dad_time,
6726 zvrf->dad_freeze ? "enable" : "disable",
6727 zvrf->dad_freeze_time);
6728
6729 stream_failure:
6730 return;
6731 }
6732
6733 /*
6734 * Handle neighbor delete notification from the kernel (on a VLAN device
6735 * / L3 interface). This may result in either the neighbor getting deleted
6736 * from our database or being re-added to the kernel (if it is a valid
6737 * remote neighbor).
6738 */
6739 int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
6740 struct interface *link_if,
6741 struct ipaddr *ip)
6742 {
6743 char buf[INET6_ADDRSTRLEN];
6744 char buf2[ETHER_ADDR_STRLEN];
6745 zebra_neigh_t *n = NULL;
6746 zebra_vni_t *zvni = NULL;
6747 zebra_mac_t *zmac = NULL;
6748 zebra_l3vni_t *zl3vni = NULL;
6749
6750 /* check if this is a remote neigh entry corresponding to remote
6751 * next-hop
6752 */
6753 zl3vni = zl3vni_from_svi(ifp, link_if);
6754 if (zl3vni)
6755 return zl3vni_local_nh_del(zl3vni, ip);
6756
6757 /* We are only interested in neighbors on an SVI that resides on top
6758 * of a VxLAN bridge.
6759 */
6760 zvni = zvni_from_svi(ifp, link_if);
6761 if (!zvni)
6762 return 0;
6763
6764 if (!zvni->vxlan_if) {
6765 zlog_debug(
6766 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
6767 zvni->vni, zvni);
6768 return -1;
6769 }
6770
6771 if (IS_ZEBRA_DEBUG_VXLAN)
6772 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
6773 ipaddr2str(ip, buf, sizeof(buf)), ifp->name,
6774 ifp->ifindex, zvni->vni);
6775
6776 /* If entry doesn't exist, nothing to do. */
6777 n = zvni_neigh_lookup(zvni, ip);
6778 if (!n)
6779 return 0;
6780
6781 zmac = zvni_mac_lookup(zvni, &n->emac);
6782 if (!zmac) {
6783 if (IS_ZEBRA_DEBUG_VXLAN)
6784 zlog_debug(
6785 "Trying to del a neigh %s without a mac %s on VNI %u",
6786 ipaddr2str(ip, buf, sizeof(buf)),
6787 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
6788 zvni->vni);
6789
6790 return 0;
6791 }
6792
6793 /* If it is a remote entry, the kernel has aged this out or someone has
6794 * deleted it, it needs to be re-installed as Quagga is the owner.
6795 */
6796 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
6797 zvni_neigh_install(zvni, n);
6798 return 0;
6799 }
6800
6801 /* Remove neighbor from BGP. */
6802 if (IS_ZEBRA_NEIGH_ACTIVE(n))
6803 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0);
6804
6805 /* Delete this neighbor entry. */
6806 zvni_neigh_del(zvni, n);
6807
6808 /* see if the AUTO mac needs to be deleted */
6809 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
6810 && !listcount(zmac->neigh_list))
6811 zvni_mac_del(zvni, zmac);
6812
6813 return 0;
6814 }
6815
6816 /*
6817 * Handle neighbor add or update notification from the kernel (on a VLAN
6818 * device / L3 interface). This is typically for a local neighbor but can
6819 * also be for a remote neighbor (e.g., ageout notification). It could
6820 * also be a "move" scenario.
6821 */
6822 int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
6823 struct interface *link_if,
6824 struct ipaddr *ip,
6825 struct ethaddr *macaddr,
6826 uint16_t state,
6827 bool is_ext,
6828 bool is_router)
6829 {
6830 char buf[ETHER_ADDR_STRLEN];
6831 char buf2[INET6_ADDRSTRLEN];
6832 zebra_vni_t *zvni = NULL;
6833 zebra_l3vni_t *zl3vni = NULL;
6834
6835 /* check if this is a remote neigh entry corresponding to remote
6836 * next-hop
6837 */
6838 zl3vni = zl3vni_from_svi(ifp, link_if);
6839 if (zl3vni)
6840 return zl3vni_local_nh_add_update(zl3vni, ip, state);
6841
6842 /* We are only interested in neighbors on an SVI that resides on top
6843 * of a VxLAN bridge.
6844 */
6845 zvni = zvni_from_svi(ifp, link_if);
6846 if (!zvni)
6847 return 0;
6848
6849 if (IS_ZEBRA_DEBUG_VXLAN)
6850 zlog_debug(
6851 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
6852 ipaddr2str(ip, buf2, sizeof(buf2)),
6853 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
6854 ifp->ifindex, state, is_ext ? "ext-learned " : "",
6855 is_router ? "router " : "",
6856 zvni->vni);
6857
6858 /* Is this about a local neighbor or a remote one? */
6859 if (!is_ext)
6860 return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
6861 is_router);
6862
6863 return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
6864 }
6865
6866
6867 /*
6868 * Handle message from client to delete a remote MACIP for a VNI.
6869 */
6870 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
6871 {
6872 struct stream *s;
6873 vni_t vni;
6874 struct ethaddr macaddr;
6875 struct ipaddr ip;
6876 struct in_addr vtep_ip;
6877 uint16_t l = 0, ipa_len;
6878 char buf[ETHER_ADDR_STRLEN];
6879 char buf1[INET6_ADDRSTRLEN];
6880
6881 memset(&macaddr, 0, sizeof(struct ethaddr));
6882 memset(&ip, 0, sizeof(struct ipaddr));
6883 memset(&vtep_ip, 0, sizeof(struct in_addr));
6884
6885 s = msg;
6886
6887 while (l < hdr->length) {
6888 /* Obtain each remote MACIP and process. */
6889 /* Message contains VNI, followed by MAC followed by IP (if any)
6890 * followed by remote VTEP IP.
6891 */
6892 memset(&ip, 0, sizeof(ip));
6893 STREAM_GETL(s, vni);
6894 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
6895 STREAM_GETL(s, ipa_len);
6896 if (ipa_len) {
6897 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
6898 : IPADDR_V6;
6899 STREAM_GET(&ip.ip.addr, s, ipa_len);
6900 }
6901 l += 4 + ETH_ALEN + 4 + ipa_len;
6902 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
6903 l += IPV4_MAX_BYTELEN;
6904
6905 if (IS_ZEBRA_DEBUG_VXLAN)
6906 zlog_debug(
6907 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
6908 vni,
6909 prefix_mac2str(&macaddr, buf, sizeof(buf)),
6910 ipa_len ? " IP " : "",
6911 ipa_len ?
6912 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
6913 inet_ntoa(vtep_ip),
6914 zebra_route_string(client->proto));
6915
6916 process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
6917 }
6918
6919 stream_failure:
6920 return;
6921 }
6922
6923 /*
6924 * Handle message from client to add a remote MACIP for a VNI. This
6925 * could be just the add of a MAC address or the add of a neighbor
6926 * (IP+MAC).
6927 */
6928 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
6929 {
6930 struct stream *s;
6931 vni_t vni;
6932 struct ethaddr macaddr;
6933 struct ipaddr ip;
6934 struct in_addr vtep_ip;
6935 uint16_t l = 0, ipa_len;
6936 uint8_t flags = 0;
6937 uint32_t seq;
6938 char buf[ETHER_ADDR_STRLEN];
6939 char buf1[INET6_ADDRSTRLEN];
6940
6941 memset(&macaddr, 0, sizeof(struct ethaddr));
6942 memset(&ip, 0, sizeof(struct ipaddr));
6943 memset(&vtep_ip, 0, sizeof(struct in_addr));
6944
6945 if (!EVPN_ENABLED(zvrf)) {
6946 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
6947 return;
6948 }
6949
6950 s = msg;
6951
6952 while (l < hdr->length) {
6953 /* Obtain each remote MACIP and process. */
6954 /* Message contains VNI, followed by MAC followed by IP (if any)
6955 * followed by remote VTEP IP.
6956 */
6957 memset(&ip, 0, sizeof(ip));
6958 STREAM_GETL(s, vni);
6959 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
6960 STREAM_GETL(s, ipa_len);
6961 if (ipa_len) {
6962 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
6963 : IPADDR_V6;
6964 STREAM_GET(&ip.ip.addr, s, ipa_len);
6965 }
6966 l += 4 + ETH_ALEN + 4 + ipa_len;
6967 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
6968 l += IPV4_MAX_BYTELEN;
6969
6970 /* Get flags - sticky mac and/or gateway mac */
6971 STREAM_GETC(s, flags);
6972 l++;
6973 STREAM_GETL(s, seq);
6974 l += 4;
6975
6976 if (IS_ZEBRA_DEBUG_VXLAN)
6977 zlog_debug(
6978 "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
6979 vni,
6980 prefix_mac2str(&macaddr, buf, sizeof(buf)),
6981 ipa_len ? " IP " : "",
6982 ipa_len ?
6983 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
6984 flags, seq, inet_ntoa(vtep_ip),
6985 zebra_route_string(client->proto));
6986
6987 process_remote_macip_add(vni, &macaddr, ipa_len, &ip,
6988 flags, seq, vtep_ip);
6989 }
6990
6991 stream_failure:
6992 return;
6993 }
6994
6995 /*
6996 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
6997 * us, this must involve a multihoming scenario. Treat this as implicit delete
6998 * of any prior local MAC.
6999 */
7000 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
7001 struct interface *br_if,
7002 struct ethaddr *macaddr, vlanid_t vid)
7003 {
7004 struct zebra_if *zif;
7005 struct zebra_l2info_vxlan *vxl;
7006 vni_t vni;
7007 zebra_vni_t *zvni;
7008 zebra_mac_t *mac;
7009 char buf[ETHER_ADDR_STRLEN];
7010
7011 zif = ifp->info;
7012 assert(zif);
7013 vxl = &zif->l2info.vxl;
7014 vni = vxl->vni;
7015
7016 /* Check if EVPN is enabled. */
7017 if (!is_evpn_enabled())
7018 return 0;
7019
7020 /* Locate hash entry; it is expected to exist. */
7021 zvni = zvni_lookup(vni);
7022 if (!zvni)
7023 return 0;
7024
7025 /* If entry doesn't exist, nothing to do. */
7026 mac = zvni_mac_lookup(zvni, macaddr);
7027 if (!mac)
7028 return 0;
7029
7030 /* Is it a local entry? */
7031 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
7032 return 0;
7033
7034 if (IS_ZEBRA_DEBUG_VXLAN)
7035 zlog_debug(
7036 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
7037 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7038 ifp->ifindex, vni);
7039
7040 /* Remove MAC from BGP. */
7041 zvni_mac_send_del_to_client(zvni->vni, macaddr);
7042
7043 /*
7044 * If there are no neigh associated with the mac delete the mac
7045 * else mark it as AUTO for forward reference
7046 */
7047 if (!listcount(mac->neigh_list)) {
7048 zvni_mac_del(zvni, mac);
7049 } else {
7050 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7051 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7052 }
7053
7054 return 0;
7055 }
7056
7057 /*
7058 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
7059 * This can happen because the remote MAC entries are also added as "dynamic",
7060 * so the kernel can ageout the entry.
7061 */
7062 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
7063 struct interface *br_if,
7064 struct ethaddr *macaddr, vlanid_t vid)
7065 {
7066 struct zebra_if *zif = NULL;
7067 struct zebra_l2info_vxlan *vxl = NULL;
7068 vni_t vni;
7069 zebra_vni_t *zvni = NULL;
7070 zebra_l3vni_t *zl3vni = NULL;
7071 zebra_mac_t *mac = NULL;
7072 char buf[ETHER_ADDR_STRLEN];
7073
7074 zif = ifp->info;
7075 assert(zif);
7076 vxl = &zif->l2info.vxl;
7077 vni = vxl->vni;
7078
7079 /* Check if EVPN is enabled. */
7080 if (!is_evpn_enabled())
7081 return 0;
7082
7083 /* check if this is a remote RMAC and readd simillar to remote macs */
7084 zl3vni = zl3vni_lookup(vni);
7085 if (zl3vni)
7086 return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
7087
7088 /* Locate hash entry; it is expected to exist. */
7089 zvni = zvni_lookup(vni);
7090 if (!zvni)
7091 return 0;
7092
7093 /* If entry doesn't exist, nothing to do. */
7094 mac = zvni_mac_lookup(zvni, macaddr);
7095 if (!mac)
7096 return 0;
7097
7098 /* Is it a remote entry? */
7099 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
7100 return 0;
7101
7102 if (IS_ZEBRA_DEBUG_VXLAN)
7103 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
7104 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7105 ifp->ifindex, vni);
7106
7107 zvni_mac_install(zvni, mac);
7108 return 0;
7109 }
7110
7111 /*
7112 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
7113 */
7114 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
7115 struct ethaddr *macaddr, vlanid_t vid)
7116 {
7117 zebra_vni_t *zvni;
7118 zebra_mac_t *mac;
7119 char buf[ETHER_ADDR_STRLEN];
7120
7121 /* We are interested in MACs only on ports or (port, VLAN) that
7122 * map to a VNI.
7123 */
7124 zvni = zvni_map_vlan(ifp, br_if, vid);
7125 if (!zvni)
7126 return 0;
7127 if (!zvni->vxlan_if) {
7128 zlog_debug(
7129 "VNI %u hash %p doesn't have intf upon local MAC DEL",
7130 zvni->vni, zvni);
7131 return -1;
7132 }
7133
7134 if (IS_ZEBRA_DEBUG_VXLAN)
7135 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u",
7136 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7137 ifp->ifindex, vid, zvni->vni);
7138
7139 /* If entry doesn't exist, nothing to do. */
7140 mac = zvni_mac_lookup(zvni, macaddr);
7141 if (!mac)
7142 return 0;
7143
7144 /* Is it a local entry? */
7145 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
7146 return 0;
7147
7148 /* Update all the neigh entries associated with this mac */
7149 zvni_process_neigh_on_local_mac_del(zvni, mac);
7150
7151 /* Remove MAC from BGP. */
7152 zvni_mac_send_del_to_client(zvni->vni, macaddr);
7153
7154 /*
7155 * If there are no neigh associated with the mac delete the mac
7156 * else mark it as AUTO for forward reference
7157 */
7158 if (!listcount(mac->neigh_list)) {
7159 zvni_mac_del(zvni, mac);
7160 } else {
7161 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7162 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7163 }
7164
7165 return 0;
7166 }
7167
7168 /*
7169 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
7170 */
7171 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
7172 struct interface *br_if,
7173 struct ethaddr *macaddr, vlanid_t vid,
7174 bool sticky)
7175 {
7176 zebra_vni_t *zvni;
7177 zebra_mac_t *mac;
7178 struct zebra_vrf *zvrf;
7179 char buf[ETHER_ADDR_STRLEN];
7180 bool mac_sticky = false;
7181 bool inform_client = false;
7182 bool upd_neigh = false;
7183 struct in_addr vtep_ip = {.s_addr = 0};
7184
7185 /* We are interested in MACs only on ports or (port, VLAN) that
7186 * map to a VNI.
7187 */
7188 zvni = zvni_map_vlan(ifp, br_if, vid);
7189 if (!zvni) {
7190 if (IS_ZEBRA_DEBUG_VXLAN)
7191 zlog_debug(
7192 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
7193 sticky ? "sticky " : "",
7194 prefix_mac2str(macaddr, buf, sizeof(buf)),
7195 ifp->name, ifp->ifindex, vid);
7196 return 0;
7197 }
7198
7199 if (!zvni->vxlan_if) {
7200 zlog_debug(
7201 "VNI %u hash %p doesn't have intf upon local MAC ADD",
7202 zvni->vni, zvni);
7203 return -1;
7204 }
7205
7206 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
7207 if (!zvrf)
7208 return -1;
7209
7210 /* Check if we need to create or update or it is a NO-OP. */
7211 mac = zvni_mac_lookup(zvni, macaddr);
7212 if (!mac) {
7213 if (IS_ZEBRA_DEBUG_VXLAN)
7214 zlog_debug(
7215 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
7216 sticky ? "sticky " : "",
7217 prefix_mac2str(macaddr, buf, sizeof(buf)),
7218 ifp->name, ifp->ifindex, vid, zvni->vni);
7219
7220 mac = zvni_mac_add(zvni, macaddr);
7221 if (!mac) {
7222 flog_err(
7223 EC_ZEBRA_MAC_ADD_FAILED,
7224 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
7225 prefix_mac2str(macaddr, buf, sizeof(buf)),
7226 ifp->name, ifp->ifindex, vid, zvni->vni);
7227 return -1;
7228 }
7229 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7230 mac->fwd_info.local.ifindex = ifp->ifindex;
7231 mac->fwd_info.local.vid = vid;
7232 if (sticky)
7233 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7234 inform_client = true;
7235
7236 } else {
7237 if (IS_ZEBRA_DEBUG_VXLAN)
7238 zlog_debug(
7239 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
7240 sticky ? "sticky " : "",
7241 prefix_mac2str(macaddr, buf, sizeof(buf)),
7242 ifp->name, ifp->ifindex, vid, zvni->vni,
7243 mac->flags);
7244
7245 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
7246 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
7247 mac_sticky = true;
7248
7249 /*
7250 * Update any changes and if changes are relevant to
7251 * BGP, note it.
7252 */
7253 if (mac_sticky == sticky
7254 && mac->fwd_info.local.ifindex == ifp->ifindex
7255 && mac->fwd_info.local.vid == vid) {
7256 if (IS_ZEBRA_DEBUG_VXLAN)
7257 zlog_debug(
7258 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
7259 "entry exists and has not changed ",
7260 sticky ? "sticky " : "",
7261 prefix_mac2str(macaddr, buf,
7262 sizeof(buf)),
7263 ifp->name, ifp->ifindex, vid,
7264 zvni->vni);
7265 return 0;
7266 }
7267 if (mac_sticky != sticky) {
7268 if (sticky)
7269 SET_FLAG(mac->flags,
7270 ZEBRA_MAC_STICKY);
7271 else
7272 UNSET_FLAG(mac->flags,
7273 ZEBRA_MAC_STICKY);
7274 inform_client = true;
7275 }
7276
7277 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
7278 mac->fwd_info.local.ifindex = ifp->ifindex;
7279 mac->fwd_info.local.vid = vid;
7280
7281 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
7282 CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
7283 bool do_dad = false;
7284
7285 /*
7286 * MAC has either moved or was "internally" created due
7287 * to a neighbor learn and is now actually learnt. If
7288 * it was learnt as a remote sticky MAC, this is an
7289 * operator error.
7290 */
7291 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
7292 flog_warn(
7293 EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
7294 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
7295 prefix_mac2str(macaddr, buf,
7296 sizeof(buf)),
7297 inet_ntoa(mac->fwd_info.r_vtep_ip),
7298 zvni->vni);
7299 return 0;
7300 }
7301
7302 /* If an actual move, compute MAC's seq number */
7303 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
7304 mac->loc_seq = MAX(mac->rem_seq + 1,
7305 mac->loc_seq);
7306 vtep_ip = mac->fwd_info.r_vtep_ip;
7307 /* Trigger DAD for remote MAC */
7308 do_dad = true;
7309 }
7310
7311 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
7312 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7313 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7314 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
7315 mac->fwd_info.local.ifindex = ifp->ifindex;
7316 mac->fwd_info.local.vid = vid;
7317 if (sticky)
7318 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7319 else
7320 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7321 /*
7322 * We have to inform BGP of this MAC as well as process
7323 * all neighbors.
7324 */
7325 inform_client = true;
7326 upd_neigh = true;
7327
7328 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac, vtep_ip,
7329 do_dad,
7330 &inform_client,
7331 true);
7332 }
7333 }
7334
7335 /* Inform BGP if required. */
7336 if (inform_client) {
7337 if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
7338 mac->flags, mac->loc_seq))
7339 return -1;
7340 }
7341
7342 /* Process all neighbors associated with this MAC, if required. */
7343 if (upd_neigh)
7344 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
7345
7346 return 0;
7347 }
7348
7349 /*
7350 * Handle message from client to delete a remote VTEP for a VNI.
7351 */
7352 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
7353 {
7354 struct stream *s;
7355 unsigned short l = 0;
7356 vni_t vni;
7357 struct in_addr vtep_ip;
7358 zebra_vni_t *zvni;
7359 zebra_vtep_t *zvtep;
7360 struct interface *ifp;
7361 struct zebra_if *zif;
7362
7363 if (!is_evpn_enabled()) {
7364 zlog_debug(
7365 "%s: EVPN is not enabled yet we have received a vtep del command",
7366 __PRETTY_FUNCTION__);
7367 return;
7368 }
7369
7370 if (zvrf_id(zvrf) != VRF_DEFAULT) {
7371 zlog_debug("Recv MACIP DEL for non-default VRF %u",
7372 zvrf_id(zvrf));
7373 return;
7374 }
7375
7376 s = msg;
7377
7378 while (l < hdr->length) {
7379 /* Obtain each remote VTEP and process. */
7380 STREAM_GETL(s, vni);
7381 l += 4;
7382 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
7383 l += IPV4_MAX_BYTELEN;
7384
7385 if (IS_ZEBRA_DEBUG_VXLAN)
7386 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
7387 inet_ntoa(vtep_ip), vni,
7388 zebra_route_string(client->proto));
7389
7390 /* Locate VNI hash entry - expected to exist. */
7391 zvni = zvni_lookup(vni);
7392 if (!zvni) {
7393 if (IS_ZEBRA_DEBUG_VXLAN)
7394 zlog_debug(
7395 "Failed to locate VNI hash upon remote VTEP DEL, "
7396 "VNI %u",
7397 vni);
7398 continue;
7399 }
7400
7401 ifp = zvni->vxlan_if;
7402 if (!ifp) {
7403 zlog_debug(
7404 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
7405 zvni->vni, zvni);
7406 continue;
7407 }
7408 zif = ifp->info;
7409
7410 /* If down or not mapped to a bridge, we're done. */
7411 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
7412 continue;
7413
7414 /* If the remote VTEP does not exist, there's nothing more to
7415 * do.
7416 * Otherwise, uninstall any remote MACs pointing to this VTEP
7417 * and
7418 * then, the VTEP entry itself and remove it.
7419 */
7420 zvtep = zvni_vtep_find(zvni, &vtep_ip);
7421 if (!zvtep)
7422 continue;
7423
7424 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
7425 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
7426 zvni_vtep_uninstall(zvni, &vtep_ip);
7427 zvni_vtep_del(zvni, zvtep);
7428 }
7429
7430 stream_failure:
7431 return;
7432 }
7433
7434 /*
7435 * Handle message from client to add a remote VTEP for a VNI.
7436 */
7437 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
7438 {
7439 struct stream *s;
7440 unsigned short l = 0;
7441 vni_t vni;
7442 struct in_addr vtep_ip;
7443 zebra_vni_t *zvni;
7444 struct interface *ifp;
7445 struct zebra_if *zif;
7446
7447 if (!is_evpn_enabled()) {
7448 zlog_debug(
7449 "%s: EVPN not enabled yet we received a vtep_add zapi call",
7450 __PRETTY_FUNCTION__);
7451 return;
7452 }
7453
7454 if (zvrf_id(zvrf) != VRF_DEFAULT) {
7455 zlog_debug("Recv MACIP ADD for non-default VRF %u",
7456 zvrf_id(zvrf));
7457 return;
7458 }
7459
7460 s = msg;
7461
7462 while (l < hdr->length) {
7463 /* Obtain each remote VTEP and process. */
7464 STREAM_GETL(s, vni);
7465 l += 4;
7466 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
7467 l += IPV4_MAX_BYTELEN;
7468
7469 if (IS_ZEBRA_DEBUG_VXLAN)
7470 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
7471 inet_ntoa(vtep_ip), vni,
7472 zebra_route_string(client->proto));
7473
7474 /* Locate VNI hash entry - expected to exist. */
7475 zvni = zvni_lookup(vni);
7476 if (!zvni) {
7477 flog_err(
7478 EC_ZEBRA_VTEP_ADD_FAILED,
7479 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
7480 vni);
7481 continue;
7482 }
7483
7484 ifp = zvni->vxlan_if;
7485 if (!ifp) {
7486 flog_err(
7487 EC_ZEBRA_VTEP_ADD_FAILED,
7488 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
7489 zvni->vni, zvni);
7490 continue;
7491 }
7492
7493 zif = ifp->info;
7494
7495 /* If down or not mapped to a bridge, we're done. */
7496 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
7497 continue;
7498
7499 /* If the remote VTEP already exists,
7500 there's nothing more to do. */
7501 if (zvni_vtep_find(zvni, &vtep_ip))
7502 continue;
7503
7504 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
7505 flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
7506 "Failed to add remote VTEP, VNI %u zvni %p",
7507 vni, zvni);
7508 continue;
7509 }
7510
7511 zvni_vtep_install(zvni, &vtep_ip);
7512 }
7513
7514 stream_failure:
7515 return;
7516 }
7517
7518 /*
7519 * Add/Del gateway macip to evpn
7520 * g/w can be:
7521 * 1. SVI interface on a vlan aware bridge
7522 * 2. SVI interface on a vlan unaware bridge
7523 * 3. vrr interface (MACVLAN) associated to a SVI
7524 * We advertise macip routes for an interface if it is associated to VxLan vlan
7525 */
7526 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
7527 int add)
7528 {
7529 struct ipaddr ip;
7530 struct ethaddr macaddr;
7531 zebra_vni_t *zvni = NULL;
7532
7533 memset(&ip, 0, sizeof(struct ipaddr));
7534 memset(&macaddr, 0, sizeof(struct ethaddr));
7535
7536 /* Check if EVPN is enabled. */
7537 if (!is_evpn_enabled())
7538 return 0;
7539
7540 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
7541 struct interface *svi_if =
7542 NULL; /* SVI corresponding to the MACVLAN */
7543 struct zebra_if *ifp_zif =
7544 NULL; /* Zebra daemon specific info for MACVLAN */
7545 struct zebra_if *svi_if_zif =
7546 NULL; /* Zebra daemon specific info for SVI*/
7547
7548 ifp_zif = ifp->info;
7549 if (!ifp_zif)
7550 return -1;
7551
7552 /*
7553 * for a MACVLAN interface the link represents the svi_if
7554 */
7555 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
7556 ifp_zif->link_ifindex);
7557 if (!svi_if) {
7558 zlog_debug("MACVLAN %s(%u) without link information",
7559 ifp->name, ifp->ifindex);
7560 return -1;
7561 }
7562
7563 if (IS_ZEBRA_IF_VLAN(svi_if)) {
7564 /*
7565 * If it is a vlan aware bridge then the link gives the
7566 * bridge information
7567 */
7568 struct interface *svi_if_link = NULL;
7569
7570 svi_if_zif = svi_if->info;
7571 if (svi_if_zif) {
7572 svi_if_link = if_lookup_by_index_per_ns(
7573 zebra_ns_lookup(NS_DEFAULT),
7574 svi_if_zif->link_ifindex);
7575 zvni = zvni_from_svi(svi_if, svi_if_link);
7576 }
7577 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
7578 /*
7579 * If it is a vlan unaware bridge then svi is the bridge
7580 * itself
7581 */
7582 zvni = zvni_from_svi(svi_if, svi_if);
7583 }
7584 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
7585 struct zebra_if *svi_if_zif =
7586 NULL; /* Zebra daemon specific info for SVI */
7587 struct interface *svi_if_link =
7588 NULL; /* link info for the SVI = bridge info */
7589
7590 svi_if_zif = ifp->info;
7591 if (svi_if_zif) {
7592 svi_if_link = if_lookup_by_index_per_ns(
7593 zebra_ns_lookup(NS_DEFAULT),
7594 svi_if_zif->link_ifindex);
7595 if (svi_if_link)
7596 zvni = zvni_from_svi(ifp, svi_if_link);
7597 }
7598 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
7599 zvni = zvni_from_svi(ifp, ifp);
7600 }
7601
7602 if (!zvni)
7603 return 0;
7604
7605 if (!zvni->vxlan_if) {
7606 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
7607 zvni->vni, zvni);
7608 return -1;
7609 }
7610
7611
7612 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
7613
7614 if (p->family == AF_INET) {
7615 ip.ipa_type = IPADDR_V4;
7616 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
7617 sizeof(struct in_addr));
7618 } else if (p->family == AF_INET6) {
7619 ip.ipa_type = IPADDR_V6;
7620 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
7621 sizeof(struct in6_addr));
7622 }
7623
7624
7625 if (add)
7626 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
7627 else
7628 zvni_gw_macip_del(ifp, zvni, &ip);
7629
7630 return 0;
7631 }
7632
7633 /*
7634 * Handle SVI interface going down.
7635 * SVI can be associated to either L3-VNI or L2-VNI.
7636 * For L2-VNI: At this point, this is a NOP since
7637 * the kernel deletes the neighbor entries on this SVI (if any).
7638 * We only need to update the vrf corresponding to zvni.
7639 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
7640 * from bgp
7641 */
7642 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
7643 {
7644 zebra_l3vni_t *zl3vni = NULL;
7645
7646 zl3vni = zl3vni_from_svi(ifp, link_if);
7647 if (zl3vni) {
7648
7649 /* process l3-vni down */
7650 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7651
7652 /* remove association with svi-if */
7653 zl3vni->svi_if = NULL;
7654 } else {
7655 zebra_vni_t *zvni = NULL;
7656
7657 /* since we dont have svi corresponding to zvni, we associate it
7658 * to default vrf. Note: the corresponding neigh entries on the
7659 * SVI would have already been deleted */
7660 zvni = zvni_from_svi(ifp, link_if);
7661 if (zvni) {
7662 zvni->vrf_id = VRF_DEFAULT;
7663
7664 /* update the tenant vrf in BGP */
7665 zvni_send_add_to_client(zvni);
7666 }
7667 }
7668 return 0;
7669 }
7670
7671 /*
7672 * Handle SVI interface coming up.
7673 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
7674 * vxlan intf).
7675 * For L2-VNI: we need to install any remote neighbors entried (used for
7676 * apr-suppression)
7677 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
7678 */
7679 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
7680 {
7681 zebra_vni_t *zvni = NULL;
7682 zebra_l3vni_t *zl3vni = NULL;
7683
7684 zl3vni = zl3vni_from_svi(ifp, link_if);
7685 if (zl3vni) {
7686
7687 /* associate with svi */
7688 zl3vni->svi_if = ifp;
7689
7690 /* process oper-up */
7691 if (is_l3vni_oper_up(zl3vni))
7692 zebra_vxlan_process_l3vni_oper_up(zl3vni);
7693 } else {
7694
7695 /* process SVI up for l2-vni */
7696 struct neigh_walk_ctx n_wctx;
7697
7698 zvni = zvni_from_svi(ifp, link_if);
7699 if (!zvni)
7700 return 0;
7701
7702 if (!zvni->vxlan_if) {
7703 zlog_debug(
7704 "VNI %u hash %p doesn't have intf upon SVI up",
7705 zvni->vni, zvni);
7706 return -1;
7707 }
7708
7709 if (IS_ZEBRA_DEBUG_VXLAN)
7710 zlog_debug(
7711 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
7712 ifp->name, ifp->ifindex, zvni->vni,
7713 vrf_id_to_name(ifp->vrf_id));
7714
7715 /* update the vrf information for l2-vni and inform bgp */
7716 zvni->vrf_id = ifp->vrf_id;
7717 zvni_send_add_to_client(zvni);
7718
7719 /* Install any remote neighbors for this VNI. */
7720 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
7721 n_wctx.zvni = zvni;
7722 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
7723 &n_wctx);
7724 }
7725
7726 return 0;
7727 }
7728
7729 /*
7730 * Handle VxLAN interface down
7731 */
7732 int zebra_vxlan_if_down(struct interface *ifp)
7733 {
7734 vni_t vni;
7735 struct zebra_if *zif = NULL;
7736 struct zebra_l2info_vxlan *vxl = NULL;
7737 zebra_l3vni_t *zl3vni = NULL;
7738 zebra_vni_t *zvni;
7739
7740 /* Check if EVPN is enabled. */
7741 if (!is_evpn_enabled())
7742 return 0;
7743
7744 zif = ifp->info;
7745 assert(zif);
7746 vxl = &zif->l2info.vxl;
7747 vni = vxl->vni;
7748
7749 zl3vni = zl3vni_lookup(vni);
7750 if (zl3vni) {
7751 /* process-if-down for l3-vni */
7752 if (IS_ZEBRA_DEBUG_VXLAN)
7753 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
7754 ifp->ifindex, vni);
7755
7756 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7757 } else {
7758 /* process if-down for l2-vni */
7759 if (IS_ZEBRA_DEBUG_VXLAN)
7760 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
7761 ifp->ifindex, vni);
7762
7763 /* Locate hash entry; it is expected to exist. */
7764 zvni = zvni_lookup(vni);
7765 if (!zvni) {
7766 zlog_debug(
7767 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
7768 ifp->name, ifp->ifindex, vni);
7769 return -1;
7770 }
7771
7772 assert(zvni->vxlan_if == ifp);
7773
7774 /* Delete this VNI from BGP. */
7775 zvni_send_del_to_client(zvni->vni);
7776
7777 /* Free up all neighbors and MACs, if any. */
7778 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
7779 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
7780
7781 /* Free up all remote VTEPs, if any. */
7782 zvni_vtep_del_all(zvni, 1);
7783 }
7784 return 0;
7785 }
7786
7787 /*
7788 * Handle VxLAN interface up - update BGP if required.
7789 */
7790 int zebra_vxlan_if_up(struct interface *ifp)
7791 {
7792 vni_t vni;
7793 struct zebra_if *zif = NULL;
7794 struct zebra_l2info_vxlan *vxl = NULL;
7795 zebra_vni_t *zvni = NULL;
7796 zebra_l3vni_t *zl3vni = NULL;
7797
7798 /* Check if EVPN is enabled. */
7799 if (!is_evpn_enabled())
7800 return 0;
7801
7802 zif = ifp->info;
7803 assert(zif);
7804 vxl = &zif->l2info.vxl;
7805 vni = vxl->vni;
7806
7807 zl3vni = zl3vni_lookup(vni);
7808 if (zl3vni) {
7809
7810 if (IS_ZEBRA_DEBUG_VXLAN)
7811 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp->name,
7812 ifp->ifindex, vni);
7813
7814 /* we need to associate with SVI, if any, we can associate with
7815 * svi-if only after association with vxlan-intf is complete
7816 */
7817 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
7818
7819 if (is_l3vni_oper_up(zl3vni))
7820 zebra_vxlan_process_l3vni_oper_up(zl3vni);
7821 } else {
7822 /* Handle L2-VNI add */
7823 struct interface *vlan_if = NULL;
7824
7825 if (IS_ZEBRA_DEBUG_VXLAN)
7826 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
7827 ifp->ifindex, vni);
7828
7829 /* Locate hash entry; it is expected to exist. */
7830 zvni = zvni_lookup(vni);
7831 if (!zvni) {
7832 zlog_debug(
7833 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
7834 ifp->name, ifp->ifindex, vni);
7835 return -1;
7836 }
7837
7838 assert(zvni->vxlan_if == ifp);
7839 vlan_if = zvni_map_to_svi(vxl->access_vlan,
7840 zif->brslave_info.br_if);
7841 if (vlan_if) {
7842 zvni->vrf_id = vlan_if->vrf_id;
7843 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
7844 if (zl3vni)
7845 listnode_add_sort(zl3vni->l2vnis, zvni);
7846 }
7847
7848 /* If part of a bridge, inform BGP about this VNI. */
7849 /* Also, read and populate local MACs and neighbors. */
7850 if (zif->brslave_info.br_if) {
7851 zvni_send_add_to_client(zvni);
7852 zvni_read_mac_neigh(zvni, ifp);
7853 }
7854 }
7855
7856 return 0;
7857 }
7858
7859 /*
7860 * Handle VxLAN interface delete. Locate and remove entry in hash table
7861 * and update BGP, if required.
7862 */
7863 int zebra_vxlan_if_del(struct interface *ifp)
7864 {
7865 vni_t vni;
7866 struct zebra_if *zif = NULL;
7867 struct zebra_l2info_vxlan *vxl = NULL;
7868 zebra_vni_t *zvni = NULL;
7869 zebra_l3vni_t *zl3vni = NULL;
7870
7871 /* Check if EVPN is enabled. */
7872 if (!is_evpn_enabled())
7873 return 0;
7874
7875 zif = ifp->info;
7876 assert(zif);
7877 vxl = &zif->l2info.vxl;
7878 vni = vxl->vni;
7879
7880 zl3vni = zl3vni_lookup(vni);
7881 if (zl3vni) {
7882
7883 if (IS_ZEBRA_DEBUG_VXLAN)
7884 zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
7885 ifp->ifindex);
7886
7887 /* process oper-down for l3-vni */
7888 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7889
7890 /* remove the association with vxlan_if */
7891 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
7892 zl3vni->vxlan_if = NULL;
7893 } else {
7894
7895 /* process if-del for l2-vni*/
7896 if (IS_ZEBRA_DEBUG_VXLAN)
7897 zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name,
7898 ifp->ifindex);
7899
7900 /* Locate hash entry; it is expected to exist. */
7901 zvni = zvni_lookup(vni);
7902 if (!zvni) {
7903 zlog_debug(
7904 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
7905 ifp->name, ifp->ifindex, vni);
7906 return 0;
7907 }
7908
7909 /* remove from l3-vni list */
7910 zl3vni = zl3vni_from_vrf(zvni->vrf_id);
7911 if (zl3vni)
7912 listnode_delete(zl3vni->l2vnis, zvni);
7913
7914 /* Delete VNI from BGP. */
7915 zvni_send_del_to_client(zvni->vni);
7916
7917 /* Free up all neighbors and MAC, if any. */
7918 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
7919 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
7920
7921 /* Free up all remote VTEPs, if any. */
7922 zvni_vtep_del_all(zvni, 0);
7923
7924 /* Delete the hash entry. */
7925 if (zvni_del(zvni)) {
7926 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
7927 "Failed to del VNI hash %p, IF %s(%u) VNI %u",
7928 zvni, ifp->name, ifp->ifindex, zvni->vni);
7929 return -1;
7930 }
7931 }
7932 return 0;
7933 }
7934
7935 /*
7936 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
7937 */
7938 int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
7939 {
7940 vni_t vni;
7941 struct zebra_if *zif = NULL;
7942 struct zebra_l2info_vxlan *vxl = NULL;
7943 zebra_vni_t *zvni = NULL;
7944 zebra_l3vni_t *zl3vni = NULL;
7945
7946 /* Check if EVPN is enabled. */
7947 if (!is_evpn_enabled())
7948 return 0;
7949
7950 zif = ifp->info;
7951 assert(zif);
7952 vxl = &zif->l2info.vxl;
7953 vni = vxl->vni;
7954
7955 zl3vni = zl3vni_lookup(vni);
7956 if (zl3vni) {
7957
7958 if (IS_ZEBRA_DEBUG_VXLAN)
7959 zlog_debug(
7960 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
7961 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
7962 inet_ntoa(vxl->vtep_ip),
7963 zif->brslave_info.bridge_ifindex, chgflags);
7964
7965 /* Removed from bridge? Cleanup and return */
7966 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
7967 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
7968 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7969 return 0;
7970 }
7971
7972 /* access-vlan change - process oper down, associate with new
7973 * svi_if and then process oper up again
7974 */
7975 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
7976 if (if_is_operative(ifp)) {
7977 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7978 zl3vni->svi_if = NULL;
7979 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
7980 zl3vni->local_vtep_ip = vxl->vtep_ip;
7981 if (is_l3vni_oper_up(zl3vni))
7982 zebra_vxlan_process_l3vni_oper_up(
7983 zl3vni);
7984 }
7985 }
7986
7987 /*
7988 * local-ip change - process oper down, associate with new
7989 * local-ip and then process oper up again
7990 */
7991 if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) {
7992 if (if_is_operative(ifp)) {
7993 zebra_vxlan_process_l3vni_oper_down(zl3vni);
7994 zl3vni->local_vtep_ip = vxl->vtep_ip;
7995 if (is_l3vni_oper_up(zl3vni))
7996 zebra_vxlan_process_l3vni_oper_up(
7997 zl3vni);
7998 }
7999 }
8000
8001 /* Update local tunnel IP. */
8002 zl3vni->local_vtep_ip = vxl->vtep_ip;
8003
8004 /* if we have a valid new master, process l3-vni oper up */
8005 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
8006 if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni))
8007 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8008 }
8009 } else {
8010
8011 /* Update VNI hash. */
8012 zvni = zvni_lookup(vni);
8013 if (!zvni) {
8014 zlog_debug(
8015 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
8016 ifp->name, ifp->ifindex, vni);
8017 return -1;
8018 }
8019
8020 if (IS_ZEBRA_DEBUG_VXLAN)
8021 zlog_debug(
8022 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
8023 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
8024 inet_ntoa(vxl->vtep_ip),
8025 zif->brslave_info.bridge_ifindex, chgflags);
8026
8027 /* Removed from bridge? Cleanup and return */
8028 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
8029 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
8030 /* Delete from client, remove all remote VTEPs */
8031 /* Also, free up all MACs and neighbors. */
8032 zvni_send_del_to_client(zvni->vni);
8033 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
8034 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
8035 zvni_vtep_del_all(zvni, 1);
8036 return 0;
8037 }
8038
8039 /* Handle other changes. */
8040 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
8041 /* Remove all existing local neigh and MACs for this VNI
8042 * (including from BGP)
8043 */
8044 zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
8045 zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
8046 }
8047
8048 zvni->local_vtep_ip = vxl->vtep_ip;
8049 zvni->vxlan_if = ifp;
8050
8051 /* Take further actions needed.
8052 * Note that if we are here, there is a change of interest.
8053 */
8054 /* If down or not mapped to a bridge, we're done. */
8055 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8056 return 0;
8057
8058 /* Inform BGP, if there is a change of interest. */
8059 if (chgflags
8060 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
8061 zvni_send_add_to_client(zvni);
8062
8063 /* If there is a valid new master or a VLAN mapping change,
8064 * read and populate local MACs and neighbors.
8065 * Also, reinstall any remote MACs and neighbors
8066 * for this VNI (based on new VLAN).
8067 */
8068 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
8069 zvni_read_mac_neigh(zvni, ifp);
8070 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
8071 struct mac_walk_ctx m_wctx;
8072 struct neigh_walk_ctx n_wctx;
8073
8074 zvni_read_mac_neigh(zvni, ifp);
8075
8076 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
8077 m_wctx.zvni = zvni;
8078 hash_iterate(zvni->mac_table, zvni_install_mac_hash,
8079 &m_wctx);
8080
8081 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
8082 n_wctx.zvni = zvni;
8083 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
8084 &n_wctx);
8085 }
8086 }
8087
8088 return 0;
8089 }
8090
8091 /*
8092 * Handle VxLAN interface add.
8093 */
8094 int zebra_vxlan_if_add(struct interface *ifp)
8095 {
8096 vni_t vni;
8097 struct zebra_if *zif = NULL;
8098 struct zebra_l2info_vxlan *vxl = NULL;
8099 zebra_vni_t *zvni = NULL;
8100 zebra_l3vni_t *zl3vni = NULL;
8101
8102 /* Check if EVPN is enabled. */
8103 if (!is_evpn_enabled())
8104 return 0;
8105
8106 zif = ifp->info;
8107 assert(zif);
8108 vxl = &zif->l2info.vxl;
8109 vni = vxl->vni;
8110
8111 zl3vni = zl3vni_lookup(vni);
8112 if (zl3vni) {
8113
8114 /* process if-add for l3-vni*/
8115 if (IS_ZEBRA_DEBUG_VXLAN)
8116 zlog_debug(
8117 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
8118 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
8119 inet_ntoa(vxl->vtep_ip),
8120 zif->brslave_info.bridge_ifindex);
8121
8122 /* associate with vxlan_if */
8123 zl3vni->local_vtep_ip = vxl->vtep_ip;
8124 zl3vni->vxlan_if = ifp;
8125
8126 /* Associate with SVI, if any. We can associate with svi-if only
8127 * after association with vxlan_if is complete */
8128 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8129
8130 if (is_l3vni_oper_up(zl3vni))
8131 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8132 } else {
8133
8134 /* process if-add for l2-vni */
8135 struct interface *vlan_if = NULL;
8136
8137 /* Create or update VNI hash. */
8138 zvni = zvni_lookup(vni);
8139 if (!zvni) {
8140 zvni = zvni_add(vni);
8141 if (!zvni) {
8142 flog_err(
8143 EC_ZEBRA_VNI_ADD_FAILED,
8144 "Failed to add VNI hash, IF %s(%u) VNI %u",
8145 ifp->name, ifp->ifindex, vni);
8146 return -1;
8147 }
8148 }
8149
8150 zvni->local_vtep_ip = vxl->vtep_ip;
8151 zvni->vxlan_if = ifp;
8152 vlan_if = zvni_map_to_svi(vxl->access_vlan,
8153 zif->brslave_info.br_if);
8154 if (vlan_if) {
8155 zvni->vrf_id = vlan_if->vrf_id;
8156 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
8157 if (zl3vni)
8158 listnode_add_sort(zl3vni->l2vnis, zvni);
8159 }
8160
8161 if (IS_ZEBRA_DEBUG_VXLAN)
8162 zlog_debug(
8163 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
8164 vni,
8165 vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
8166 : "Default",
8167 ifp->name, ifp->ifindex, vxl->access_vlan,
8168 inet_ntoa(vxl->vtep_ip),
8169 zif->brslave_info.bridge_ifindex);
8170
8171 /* If down or not mapped to a bridge, we're done. */
8172 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8173 return 0;
8174
8175 /* Inform BGP */
8176 zvni_send_add_to_client(zvni);
8177
8178 /* Read and populate local MACs and neighbors */
8179 zvni_read_mac_neigh(zvni, ifp);
8180 }
8181
8182 return 0;
8183 }
8184
8185 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
8186 char *err, int err_str_sz, int filter,
8187 int add)
8188 {
8189 zebra_l3vni_t *zl3vni = NULL;
8190 struct zebra_vrf *zvrf_default = NULL;
8191
8192 zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT);
8193 if (!zvrf_default)
8194 return -1;
8195
8196 if (IS_ZEBRA_DEBUG_VXLAN)
8197 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
8198 add ? "ADD" : "DEL");
8199
8200 if (add) {
8201
8202 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
8203
8204 /* check if the vni is already present under zvrf */
8205 if (zvrf->l3vni) {
8206 snprintf(err, err_str_sz,
8207 "VNI is already configured under the vrf");
8208 return -1;
8209 }
8210
8211 /* check if this VNI is already present in the system */
8212 zl3vni = zl3vni_lookup(vni);
8213 if (zl3vni) {
8214 snprintf(err, err_str_sz,
8215 "VNI is already configured as L3-VNI");
8216 return -1;
8217 }
8218
8219 /* add the L3-VNI to the global table */
8220 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
8221 if (!zl3vni) {
8222 snprintf(err, err_str_sz, "Could not add L3-VNI");
8223 return -1;
8224 }
8225
8226 /* associate the vrf with vni */
8227 zvrf->l3vni = vni;
8228
8229 /* set the filter in l3vni to denote if we are using l3vni only
8230 * for prefix routes
8231 */
8232 if (filter)
8233 SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
8234
8235 /* associate with vxlan-intf;
8236 * we need to associate with the vxlan-intf first
8237 */
8238 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
8239
8240 /* associate with corresponding SVI interface, we can associate
8241 * with svi-if only after vxlan interface association is
8242 * complete
8243 */
8244 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8245
8246 /* formulate l2vni list */
8247 hash_iterate(zvrf_default->vni_table, zvni_add_to_l3vni_list,
8248 zl3vni);
8249
8250 if (is_l3vni_oper_up(zl3vni))
8251 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8252
8253 } else {
8254 zl3vni = zl3vni_lookup(vni);
8255 if (!zl3vni) {
8256 snprintf(err, err_str_sz, "VNI doesn't exist");
8257 return -1;
8258 }
8259
8260 if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
8261 snprintf(err, ERR_STR_SZ,
8262 "prefix-routes-only is not set for the vni");
8263 return -1;
8264 }
8265
8266 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8267
8268 /* delete and uninstall all rmacs */
8269 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
8270 zl3vni);
8271
8272 /* delete and uninstall all next-hops */
8273 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
8274 zl3vni);
8275
8276 zvrf->l3vni = 0;
8277 zl3vni_del(zl3vni);
8278
8279 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
8280 }
8281 return 0;
8282 }
8283
8284 int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
8285 {
8286 zebra_l3vni_t *zl3vni = NULL;
8287
8288 if (zvrf->l3vni)
8289 zl3vni = zl3vni_lookup(zvrf->l3vni);
8290 if (!zl3vni)
8291 return 0;
8292
8293 zl3vni->vrf_id = zvrf_id(zvrf);
8294 if (is_l3vni_oper_up(zl3vni))
8295 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8296 return 0;
8297 }
8298
8299 int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
8300 {
8301 zebra_l3vni_t *zl3vni = NULL;
8302
8303 if (zvrf->l3vni)
8304 zl3vni = zl3vni_lookup(zvrf->l3vni);
8305 if (!zl3vni)
8306 return 0;
8307
8308 zl3vni->vrf_id = VRF_UNKNOWN;
8309 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8310 return 0;
8311 }
8312
8313 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
8314 {
8315 zebra_l3vni_t *zl3vni = NULL;
8316 vni_t vni;
8317
8318 if (zvrf->l3vni)
8319 zl3vni = zl3vni_lookup(zvrf->l3vni);
8320 if (!zl3vni)
8321 return 0;
8322
8323 vni = zl3vni->vni;
8324 zl3vni_del(zl3vni);
8325 zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
8326
8327 return 0;
8328 }
8329
8330 /*
8331 * Handle message from client to specify the flooding mechanism for
8332 * BUM packets. The default is to do head-end (ingress) replication
8333 * and the other supported option is to disable it. This applies to
8334 * all BUM traffic and disabling it applies to both the transmit and
8335 * receive direction.
8336 */
8337 void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
8338 {
8339 struct stream *s;
8340 enum vxlan_flood_control flood_ctrl;
8341
8342 if (zvrf_id(zvrf) != VRF_DEFAULT) {
8343 zlog_err("EVPN flood control for non-default VRF %u",
8344 zvrf_id(zvrf));
8345 return;
8346 }
8347
8348 s = msg;
8349 STREAM_GETC(s, flood_ctrl);
8350
8351 if (IS_ZEBRA_DEBUG_VXLAN)
8352 zlog_debug("EVPN flood control %u, currently %u",
8353 flood_ctrl, zvrf->vxlan_flood_ctrl);
8354
8355 if (zvrf->vxlan_flood_ctrl == flood_ctrl)
8356 return;
8357
8358 zvrf->vxlan_flood_ctrl = flood_ctrl;
8359
8360 /* Install or uninstall flood entries corresponding to
8361 * remote VTEPs.
8362 */
8363 hash_iterate(zvrf->vni_table, zvni_handle_flooding_remote_vteps,
8364 zvrf);
8365
8366 stream_failure:
8367 return;
8368 }
8369
8370 /*
8371 * Handle message from client to enable/disable advertisement of g/w macip
8372 * routes
8373 */
8374 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
8375 {
8376 struct stream *s;
8377 int advertise;
8378 vni_t vni = 0;
8379 zebra_vni_t *zvni = NULL;
8380 struct interface *ifp = NULL;
8381 struct zebra_if *zif = NULL;
8382 struct zebra_l2info_vxlan zl2_info;
8383 struct interface *vlan_if = NULL;
8384
8385 if (zvrf_id(zvrf) != VRF_DEFAULT) {
8386 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
8387 zvrf_id(zvrf));
8388 return;
8389 }
8390
8391 s = msg;
8392 STREAM_GETC(s, advertise);
8393 vni = stream_get3(s);
8394
8395 zvni = zvni_lookup(vni);
8396 if (!zvni)
8397 return;
8398
8399 if (zvni->advertise_subnet == advertise)
8400 return;
8401
8402 if (IS_ZEBRA_DEBUG_VXLAN)
8403 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
8404 advertise ? "enabled" : "disabled", vni,
8405 zvni->advertise_subnet ? "enabled" : "disabled");
8406
8407
8408 zvni->advertise_subnet = advertise;
8409
8410 ifp = zvni->vxlan_if;
8411 if (!ifp)
8412 return;
8413
8414 zif = ifp->info;
8415
8416 /* If down or not mapped to a bridge, we're done. */
8417 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8418 return;
8419
8420 zl2_info = zif->l2info.vxl;
8421
8422 vlan_if =
8423 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
8424 if (!vlan_if)
8425 return;
8426
8427 if (zvni->advertise_subnet)
8428 zvni_advertise_subnet(zvni, vlan_if, 1);
8429 else
8430 zvni_advertise_subnet(zvni, vlan_if, 0);
8431
8432 stream_failure:
8433 return;
8434 }
8435
8436 /*
8437 * Handle message from client to enable/disable advertisement of g/w macip
8438 * routes
8439 */
8440 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
8441 {
8442 struct stream *s;
8443 int advertise;
8444 vni_t vni = 0;
8445 zebra_vni_t *zvni = NULL;
8446 struct interface *ifp = NULL;
8447
8448 if (zvrf_id(zvrf) != VRF_DEFAULT) {
8449 zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
8450 zvrf_id(zvrf));
8451 return;
8452 }
8453
8454 s = msg;
8455 STREAM_GETC(s, advertise);
8456 STREAM_GETL(s, vni);
8457
8458 if (!vni) {
8459 if (IS_ZEBRA_DEBUG_VXLAN)
8460 zlog_debug("EVPN gateway macip Adv %s, currently %s",
8461 advertise ? "enabled" : "disabled",
8462 advertise_gw_macip_enabled(NULL)
8463 ? "enabled"
8464 : "disabled");
8465
8466 if (zvrf->advertise_gw_macip == advertise)
8467 return;
8468
8469 zvrf->advertise_gw_macip = advertise;
8470
8471 if (advertise_gw_macip_enabled(zvni))
8472 hash_iterate(zvrf->vni_table,
8473 zvni_gw_macip_add_for_vni_hash, NULL);
8474 else
8475 hash_iterate(zvrf->vni_table,
8476 zvni_gw_macip_del_for_vni_hash, NULL);
8477
8478 } else {
8479 struct zebra_if *zif = NULL;
8480 struct zebra_l2info_vxlan zl2_info;
8481 struct interface *vlan_if = NULL;
8482 struct interface *vrr_if = NULL;
8483
8484 zvni = zvni_lookup(vni);
8485 if (!zvni)
8486 return;
8487
8488 if (IS_ZEBRA_DEBUG_VXLAN)
8489 zlog_debug(
8490 "EVPN gateway macip Adv %s on VNI %d , currently %s",
8491 advertise ? "enabled" : "disabled", vni,
8492 advertise_gw_macip_enabled(zvni) ? "enabled"
8493 : "disabled");
8494
8495 if (zvni->advertise_gw_macip == advertise)
8496 return;
8497
8498 zvni->advertise_gw_macip = advertise;
8499
8500 ifp = zvni->vxlan_if;
8501 if (!ifp)
8502 return;
8503
8504 zif = ifp->info;
8505
8506 /* If down or not mapped to a bridge, we're done. */
8507 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8508 return;
8509
8510 zl2_info = zif->l2info.vxl;
8511
8512 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
8513 zif->brslave_info.br_if);
8514 if (!vlan_if)
8515 return;
8516
8517 if (advertise_gw_macip_enabled(zvni)) {
8518 /* Add primary SVI MAC-IP */
8519 zvni_add_macip_for_intf(vlan_if, zvni);
8520
8521 /* Add VRR MAC-IP - if any*/
8522 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
8523 if (vrr_if)
8524 zvni_add_macip_for_intf(vrr_if, zvni);
8525 } else {
8526 /* Del primary MAC-IP */
8527 zvni_del_macip_for_intf(vlan_if, zvni);
8528
8529 /* Del VRR MAC-IP - if any*/
8530 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
8531 if (vrr_if)
8532 zvni_del_macip_for_intf(vrr_if, zvni);
8533 }
8534 }
8535
8536 stream_failure:
8537 return;
8538 }
8539
8540
8541 /*
8542 * Handle message from client to learn (or stop learning) about VNIs and MACs.
8543 * When enabled, the VNI hash table will be built and MAC FDB table read;
8544 * when disabled, the entries should be deleted and remote VTEPs and MACs
8545 * uninstalled from the kernel.
8546 * This also informs the setting for BUM handling at the time this change
8547 * occurs; it is relevant only when specifying "learn".
8548 */
8549 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
8550 {
8551 struct stream *s = NULL;
8552 int advertise = 0;
8553 enum vxlan_flood_control flood_ctrl;
8554
8555 if (zvrf_id(zvrf) != VRF_DEFAULT) {
8556 zlog_debug("EVPN VNI Adv for non-default VRF %u",
8557 zvrf_id(zvrf));
8558 return;
8559 }
8560
8561 s = msg;
8562 STREAM_GETC(s, advertise);
8563 STREAM_GETC(s, flood_ctrl);
8564
8565 if (IS_ZEBRA_DEBUG_VXLAN)
8566 zlog_debug("EVPN VNI Adv %s, currently %s, flood control %u",
8567 advertise ? "enabled" : "disabled",
8568 is_evpn_enabled() ? "enabled" : "disabled",
8569 flood_ctrl);
8570
8571 if (zvrf->advertise_all_vni == advertise)
8572 return;
8573
8574 zvrf->advertise_all_vni = advertise;
8575 if (is_evpn_enabled()) {
8576 /* Note BUM handling */
8577 zvrf->vxlan_flood_ctrl = flood_ctrl;
8578
8579 /* Build VNI hash table and inform BGP. */
8580 zvni_build_hash_table();
8581
8582 /* Add all SVI (L3 GW) MACs to BGP*/
8583 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
8584 NULL);
8585
8586 /* Read the MAC FDB */
8587 macfdb_read(zvrf->zns);
8588
8589 /* Read neighbors */
8590 neigh_read(zvrf->zns);
8591 } else {
8592 /* Cleanup VTEPs for all VNIs - uninstall from
8593 * kernel and free entries.
8594 */
8595 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
8596
8597 /* cleanup all l3vnis */
8598 hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
8599 }
8600
8601 stream_failure:
8602 return;
8603 }
8604
8605 /*
8606 * Allocate VNI hash table for this VRF and do other initialization.
8607 * NOTE: Currently supported only for default VRF.
8608 */
8609 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
8610 {
8611 if (!zvrf)
8612 return;
8613 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
8614 "Zebra VRF VNI Table");
8615 }
8616
8617 /* Cleanup VNI info, but don't free the table. */
8618 void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
8619 {
8620 if (!zvrf)
8621 return;
8622 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
8623 }
8624
8625 /* Close all VNI handling */
8626 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
8627 {
8628 if (!zvrf)
8629 return;
8630 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
8631 hash_free(zvrf->vni_table);
8632 }
8633
8634 /* init the l3vni table */
8635 void zebra_vxlan_ns_init(struct zebra_ns *zns)
8636 {
8637 zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
8638 "Zebra VRF L3 VNI table");
8639 }
8640
8641 /* free l3vni table */
8642 void zebra_vxlan_ns_disable(struct zebra_ns *zns)
8643 {
8644 hash_free(zrouter.l3vni_table);
8645 }
8646
8647 /* get the l3vni svi ifindex */
8648 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
8649 {
8650 zebra_l3vni_t *zl3vni = NULL;
8651
8652 zl3vni = zl3vni_from_vrf(vrf_id);
8653 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
8654 return 0;
8655
8656 return zl3vni->svi_if->ifindex;
8657 }
8658
8659 static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
8660 {
8661 struct zebra_vrf *zvrf = NULL;
8662 zebra_neigh_t *nbr = NULL;
8663 zebra_vni_t *zvni = NULL;
8664 char buf1[INET6_ADDRSTRLEN];
8665 char buf2[ETHER_ADDR_STRLEN];
8666
8667 nbr = THREAD_ARG(t);
8668
8669 /* since this is asynchronous we need sanity checks*/
8670 zvrf = vrf_info_lookup(nbr->zvni->vrf_id);
8671 if (!zvrf)
8672 return 0;
8673
8674 zvni = zvni_lookup(nbr->zvni->vni);
8675 if (!zvni)
8676 return 0;
8677
8678 nbr = zvni_neigh_lookup(zvni, &nbr->ip);
8679 if (!nbr)
8680 return 0;
8681
8682 if (IS_ZEBRA_DEBUG_VXLAN)
8683 zlog_debug("%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
8684 __PRETTY_FUNCTION__,
8685 prefix_mac2str(&nbr->emac, buf1, sizeof(buf1)),
8686 ipaddr2str(&nbr->ip, buf2, sizeof(buf2)),
8687 nbr->flags,
8688 nbr->dad_count, zvni->vni);
8689
8690 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8691 nbr->dad_count = 0;
8692 nbr->detect_start_time.tv_sec = 0;
8693 nbr->detect_start_time.tv_usec = 0;
8694 nbr->dad_dup_detect_time = 0;
8695 nbr->dad_ip_auto_recovery_timer = NULL;
8696
8697 /* Send to BGP */
8698 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
8699 zvni_neigh_send_add_to_client(zvni->vni, &nbr->ip, &nbr->emac,
8700 nbr->flags, nbr->loc_seq);
8701 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
8702 zvni_neigh_install(zvni, nbr);
8703 }
8704
8705 return 0;
8706 }
8707
8708 static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
8709 {
8710 struct zebra_vrf *zvrf = NULL;
8711 zebra_mac_t *mac = NULL;
8712 zebra_vni_t *zvni = NULL;
8713 struct listnode *node = NULL;
8714 zebra_neigh_t *nbr = NULL;
8715 char buf[ETHER_ADDR_STRLEN];
8716
8717 mac = THREAD_ARG(t);
8718
8719 /* since this is asynchronous we need sanity checks*/
8720 zvrf = vrf_info_lookup(mac->zvni->vrf_id);
8721 if (!zvrf)
8722 return 0;
8723
8724 zvni = zvni_lookup(mac->zvni->vni);
8725 if (!zvni)
8726 return 0;
8727
8728 mac = zvni_mac_lookup(zvni, &mac->macaddr);
8729 if (!mac)
8730 return 0;
8731
8732 if (IS_ZEBRA_DEBUG_VXLAN)
8733 zlog_debug("%s: duplicate addr mac %s flags 0x%x learn count %u host count %u auto recovery expired",
8734 __PRETTY_FUNCTION__,
8735 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
8736 mac->flags,
8737 mac->dad_count,
8738 listcount(mac->neigh_list));
8739
8740 /* Remove all IPs as duplicate associcated with this MAC */
8741 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
8742 if (nbr->dad_count) {
8743 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
8744 ZEBRA_NEIGH_SET_INACTIVE(nbr);
8745 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
8746 zvni_neigh_install(zvni, nbr);
8747 }
8748
8749 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8750 nbr->dad_count = 0;
8751 nbr->detect_start_time.tv_sec = 0;
8752 nbr->dad_dup_detect_time = 0;
8753 }
8754
8755 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
8756 mac->dad_count = 0;
8757 mac->detect_start_time.tv_sec = 0;
8758 mac->detect_start_time.tv_usec = 0;
8759 mac->dad_dup_detect_time = 0;
8760 mac->dad_mac_auto_recovery_timer = NULL;
8761
8762 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
8763 /* Inform to BGP */
8764 if (zvni_mac_send_add_to_client(zvni->vni, &mac->macaddr,
8765 mac->flags, mac->loc_seq))
8766 return -1;
8767
8768 /* Process all neighbors associated with this MAC. */
8769 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
8770
8771 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
8772 zvni_process_neigh_on_remote_mac_add(zvni, mac);
8773
8774 /* Install the entry. */
8775 zvni_mac_install(zvni, mac);
8776 }
8777
8778 return 0;
8779 }