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