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