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