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