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