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