]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
Merge pull request #4635 from AnuradhaKaruppiah/evpn-pim-replay
[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 #ifdef GNU_LINUX
2519 uint8_t flags;
2520 #endif
2521 int ret = 0;
2522
2523 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2524 return 0;
2525
2526 zif = zvni->vxlan_if->info;
2527 if (!zif)
2528 return -1;
2529 vxl = &zif->l2info.vxl;
2530
2531 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2532 if (!vlan_if)
2533 return -1;
2534 #ifdef GNU_LINUX
2535 flags = NTF_EXT_LEARNED;
2536 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
2537 flags |= NTF_ROUTER;
2538 ZEBRA_NEIGH_SET_ACTIVE(n);
2539 ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
2540 #endif
2541 return ret;
2542 }
2543
2544 /*
2545 * Uninstall remote neighbor from the kernel.
2546 */
2547 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
2548 {
2549 struct zebra_if *zif;
2550 struct zebra_l2info_vxlan *vxl;
2551 struct interface *vlan_if;
2552
2553 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2554 return 0;
2555
2556 if (!zvni->vxlan_if) {
2557 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2558 zvni->vni, zvni);
2559 return -1;
2560 }
2561
2562 zif = zvni->vxlan_if->info;
2563 if (!zif)
2564 return -1;
2565 vxl = &zif->l2info.vxl;
2566 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2567 if (!vlan_if)
2568 return -1;
2569
2570 ZEBRA_NEIGH_SET_INACTIVE(n);
2571 n->loc_seq = 0;
2572 return kernel_del_neigh(vlan_if, &n->ip);
2573 }
2574
2575 /*
2576 * Probe neighbor from the kernel.
2577 */
2578 static int zvni_neigh_probe(zebra_vni_t *zvni, zebra_neigh_t *n)
2579 {
2580 struct zebra_if *zif;
2581 struct zebra_l2info_vxlan *vxl;
2582 struct interface *vlan_if;
2583
2584 zif = zvni->vxlan_if->info;
2585 if (!zif)
2586 return -1;
2587 vxl = &zif->l2info.vxl;
2588
2589 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2590 if (!vlan_if)
2591 return -1;
2592
2593 #ifdef GNU_LINUX
2594 return kernel_upd_neigh(vlan_if, &n->ip, &n->emac,
2595 0, NUD_PROBE);
2596 #else
2597 return 0;
2598 #endif
2599 }
2600
2601 /*
2602 * Install neighbor hash entry - called upon access VLAN change.
2603 */
2604 static void zvni_install_neigh_hash(struct hash_bucket *bucket, void *ctxt)
2605 {
2606 zebra_neigh_t *n;
2607 struct neigh_walk_ctx *wctx = ctxt;
2608
2609 n = (zebra_neigh_t *)bucket->data;
2610
2611 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2612 zvni_neigh_install(wctx->zvni, n);
2613 }
2614
2615 /* Get the VRR interface for SVI if any */
2616 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
2617 {
2618 struct zebra_vrf *zvrf = NULL;
2619 struct interface *tmp_if = NULL;
2620 struct zebra_if *zif = NULL;
2621
2622 zvrf = vrf_info_lookup(ifp->vrf_id);
2623 assert(zvrf);
2624
2625 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
2626 zif = tmp_if->info;
2627 if (!zif)
2628 continue;
2629
2630 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
2631 continue;
2632
2633 if (zif->link == ifp)
2634 return tmp_if;
2635 }
2636
2637 return NULL;
2638 }
2639
2640 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
2641 {
2642 struct listnode *cnode = NULL, *cnnode = NULL;
2643 struct connected *c = NULL;
2644 struct ethaddr macaddr;
2645
2646 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2647
2648 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2649 struct ipaddr ip;
2650
2651 memset(&ip, 0, sizeof(struct ipaddr));
2652 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2653 continue;
2654
2655 if (c->address->family == AF_INET) {
2656 ip.ipa_type = IPADDR_V4;
2657 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2658 sizeof(struct in_addr));
2659 } else if (c->address->family == AF_INET6) {
2660 ip.ipa_type = IPADDR_V6;
2661 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2662 sizeof(struct in6_addr));
2663 } else {
2664 continue;
2665 }
2666
2667 zvni_gw_macip_del(ifp, zvni, &ip);
2668 }
2669
2670 return 0;
2671 }
2672
2673 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
2674 {
2675 struct listnode *cnode = NULL, *cnnode = NULL;
2676 struct connected *c = NULL;
2677 struct ethaddr macaddr;
2678
2679 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2680
2681 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2682 struct ipaddr ip;
2683
2684 memset(&ip, 0, sizeof(struct ipaddr));
2685 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2686 continue;
2687
2688 if (c->address->family == AF_INET) {
2689 ip.ipa_type = IPADDR_V4;
2690 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2691 sizeof(struct in_addr));
2692 } else if (c->address->family == AF_INET6) {
2693 ip.ipa_type = IPADDR_V6;
2694 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2695 sizeof(struct in6_addr));
2696 } else {
2697 continue;
2698 }
2699
2700 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
2701 }
2702 return 0;
2703 }
2704
2705
2706 static int zvni_advertise_subnet(zebra_vni_t *zvni, struct interface *ifp,
2707 int advertise)
2708 {
2709 struct listnode *cnode = NULL, *cnnode = NULL;
2710 struct connected *c = NULL;
2711 struct ethaddr macaddr;
2712
2713 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2714
2715 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2716 struct prefix p;
2717
2718 memcpy(&p, c->address, sizeof(struct prefix));
2719
2720 /* skip link local address */
2721 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
2722 continue;
2723
2724 apply_mask(&p);
2725 if (advertise)
2726 ip_prefix_send_to_client(ifp->vrf_id, &p,
2727 ZEBRA_IP_PREFIX_ROUTE_ADD);
2728 else
2729 ip_prefix_send_to_client(ifp->vrf_id, &p,
2730 ZEBRA_IP_PREFIX_ROUTE_DEL);
2731 }
2732 return 0;
2733 }
2734
2735 /*
2736 * zvni_gw_macip_add_to_client
2737 */
2738 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
2739 struct ethaddr *macaddr, struct ipaddr *ip)
2740 {
2741 char buf[ETHER_ADDR_STRLEN];
2742 char buf2[INET6_ADDRSTRLEN];
2743 zebra_neigh_t *n = NULL;
2744 zebra_mac_t *mac = NULL;
2745 struct zebra_if *zif = NULL;
2746 struct zebra_l2info_vxlan *vxl = NULL;
2747
2748 zif = zvni->vxlan_if->info;
2749 if (!zif)
2750 return -1;
2751
2752 vxl = &zif->l2info.vxl;
2753
2754 mac = zvni_mac_lookup(zvni, macaddr);
2755 if (!mac) {
2756 mac = zvni_mac_add(zvni, macaddr);
2757 if (!mac) {
2758 flog_err(EC_ZEBRA_MAC_ADD_FAILED,
2759 "Failed to add MAC %s intf %s(%u) VID %u",
2760 prefix_mac2str(macaddr, buf, sizeof(buf)),
2761 ifp->name, ifp->ifindex, vxl->access_vlan);
2762 return -1;
2763 }
2764 }
2765
2766 /* Set "local" forwarding info. */
2767 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2768 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2769 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
2770 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2771 mac->fwd_info.local.ifindex = ifp->ifindex;
2772 mac->fwd_info.local.vid = vxl->access_vlan;
2773
2774 n = zvni_neigh_lookup(zvni, ip);
2775 if (!n) {
2776 n = zvni_neigh_add(zvni, ip, macaddr);
2777 if (!n) {
2778 flog_err(
2779 EC_ZEBRA_MAC_ADD_FAILED,
2780 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2781 ipaddr2str(ip, buf2, sizeof(buf2)),
2782 prefix_mac2str(macaddr, buf, sizeof(buf)),
2783 ifp->name, ifp->ifindex, zvni->vni);
2784 return -1;
2785 }
2786 }
2787
2788 /* Set "local" forwarding info. */
2789 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2790 SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
2791 ZEBRA_NEIGH_SET_ACTIVE(n);
2792 /* Set Router flag (R-bit) */
2793 if (ip->ipa_type == IPADDR_V6)
2794 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2795 memcpy(&n->emac, macaddr, ETH_ALEN);
2796 n->ifindex = ifp->ifindex;
2797
2798 /* Only advertise in BGP if the knob is enabled */
2799 if (!advertise_gw_macip_enabled(zvni))
2800 return 0;
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
2812 return 0;
2813 }
2814
2815 /*
2816 * zvni_gw_macip_del_from_client
2817 */
2818 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
2819 struct ipaddr *ip)
2820 {
2821 char buf1[ETHER_ADDR_STRLEN];
2822 char buf2[INET6_ADDRSTRLEN];
2823 zebra_neigh_t *n = NULL;
2824 zebra_mac_t *mac = NULL;
2825
2826 /* If the neigh entry is not present nothing to do*/
2827 n = zvni_neigh_lookup(zvni, ip);
2828 if (!n)
2829 return 0;
2830
2831 /* mac entry should be present */
2832 mac = zvni_mac_lookup(zvni, &n->emac);
2833 if (!mac) {
2834 zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u",
2835 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
2836 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
2837 return -1;
2838 }
2839
2840 /* If the entry is not local nothing to do*/
2841 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
2842 return -1;
2843
2844 /* only need to delete the entry from bgp if we sent it before */
2845 if (IS_ZEBRA_DEBUG_VXLAN)
2846 zlog_debug(
2847 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
2848 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
2849 prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
2850 ipaddr2str(ip, buf2, sizeof(buf2)));
2851
2852 /* Remove neighbor from BGP. */
2853 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
2854 ZEBRA_MACIP_TYPE_GW, ZEBRA_NEIGH_ACTIVE);
2855
2856 /* Delete this neighbor entry. */
2857 zvni_neigh_del(zvni, n);
2858
2859 /* see if the mac needs to be deleted as well*/
2860 if (mac)
2861 zvni_deref_ip2mac(zvni, mac);
2862
2863 return 0;
2864 }
2865
2866 static void zvni_gw_macip_del_for_vni_hash(struct hash_bucket *bucket,
2867 void *ctxt)
2868 {
2869 zebra_vni_t *zvni = NULL;
2870 struct zebra_if *zif = NULL;
2871 struct zebra_l2info_vxlan zl2_info;
2872 struct interface *vlan_if = NULL;
2873 struct interface *vrr_if = NULL;
2874 struct interface *ifp;
2875
2876 /* Add primary SVI MAC*/
2877 zvni = (zebra_vni_t *)bucket->data;
2878
2879 /* Global (Zvrf) advertise-default-gw is disabled,
2880 * but zvni advertise-default-gw is enabled
2881 */
2882 if (zvni->advertise_gw_macip) {
2883 if (IS_ZEBRA_DEBUG_VXLAN)
2884 zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
2885 zvni->vni);
2886 return;
2887 }
2888
2889 ifp = zvni->vxlan_if;
2890 if (!ifp)
2891 return;
2892 zif = ifp->info;
2893
2894 /* If down or not mapped to a bridge, we're done. */
2895 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
2896 return;
2897
2898 zl2_info = zif->l2info.vxl;
2899
2900 vlan_if =
2901 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
2902 if (!vlan_if)
2903 return;
2904
2905 /* Del primary MAC-IP */
2906 zvni_del_macip_for_intf(vlan_if, zvni);
2907
2908 /* Del VRR MAC-IP - if any*/
2909 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2910 if (vrr_if)
2911 zvni_del_macip_for_intf(vrr_if, zvni);
2912
2913 return;
2914 }
2915
2916 static void zvni_gw_macip_add_for_vni_hash(struct hash_bucket *bucket,
2917 void *ctxt)
2918 {
2919 zebra_vni_t *zvni = NULL;
2920 struct zebra_if *zif = NULL;
2921 struct zebra_l2info_vxlan zl2_info;
2922 struct interface *vlan_if = NULL;
2923 struct interface *vrr_if = NULL;
2924 struct interface *ifp = NULL;
2925
2926 zvni = (zebra_vni_t *)bucket->data;
2927
2928 ifp = zvni->vxlan_if;
2929 if (!ifp)
2930 return;
2931 zif = ifp->info;
2932
2933 /* If down or not mapped to a bridge, we're done. */
2934 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
2935 return;
2936 zl2_info = zif->l2info.vxl;
2937
2938 vlan_if =
2939 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
2940 if (!vlan_if)
2941 return;
2942
2943 /* Add primary SVI MAC-IP */
2944 zvni_add_macip_for_intf(vlan_if, zvni);
2945
2946 if (advertise_gw_macip_enabled(zvni)) {
2947 /* Add VRR MAC-IP - if any*/
2948 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2949 if (vrr_if)
2950 zvni_add_macip_for_intf(vrr_if, zvni);
2951 }
2952
2953 return;
2954 }
2955
2956 static void zvni_svi_macip_del_for_vni_hash(struct hash_bucket *bucket,
2957 void *ctxt)
2958 {
2959 zebra_vni_t *zvni = NULL;
2960 struct zebra_if *zif = NULL;
2961 struct zebra_l2info_vxlan zl2_info;
2962 struct interface *vlan_if = NULL;
2963 struct interface *ifp;
2964
2965 /* Add primary SVI MAC*/
2966 zvni = (zebra_vni_t *)bucket->data;
2967 if (!zvni)
2968 return;
2969
2970 /* Global(vrf) advertise-svi-ip disabled, but zvni advertise-svi-ip
2971 * enabled
2972 */
2973 if (zvni->advertise_svi_macip) {
2974 if (IS_ZEBRA_DEBUG_VXLAN)
2975 zlog_debug("VNI: %u SVI-MACIP enabled, retain svi-macip",
2976 zvni->vni);
2977 return;
2978 }
2979
2980 ifp = zvni->vxlan_if;
2981 if (!ifp)
2982 return;
2983 zif = ifp->info;
2984
2985 /* If down or not mapped to a bridge, we're done. */
2986 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
2987 return;
2988
2989 zl2_info = zif->l2info.vxl;
2990
2991 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
2992 zif->brslave_info.br_if);
2993 if (!vlan_if)
2994 return;
2995
2996 /* Del primary MAC-IP */
2997 zvni_del_macip_for_intf(vlan_if, zvni);
2998
2999 return;
3000 }
3001
3002 static int zvni_local_neigh_update(zebra_vni_t *zvni,
3003 struct interface *ifp,
3004 struct ipaddr *ip,
3005 struct ethaddr *macaddr,
3006 bool is_router)
3007 {
3008 char buf[ETHER_ADDR_STRLEN];
3009 char buf2[INET6_ADDRSTRLEN];
3010 struct zebra_vrf *zvrf;
3011 zebra_neigh_t *n = NULL;
3012 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
3013 uint32_t old_mac_seq = 0, mac_new_seq = 0;
3014 bool upd_mac_seq = false;
3015 bool neigh_mac_change = false;
3016 bool neigh_on_hold = false;
3017 bool neigh_was_remote = false;
3018 bool do_dad = false;
3019 struct in_addr vtep_ip = {.s_addr = 0};
3020
3021 /* Check if the MAC exists. */
3022 zmac = zvni_mac_lookup(zvni, macaddr);
3023 if (!zmac) {
3024 /* create a dummy MAC if the MAC is not already present */
3025 if (IS_ZEBRA_DEBUG_VXLAN)
3026 zlog_debug(
3027 "AUTO MAC %s created for neigh %s on VNI %u",
3028 prefix_mac2str(macaddr, buf, sizeof(buf)),
3029 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
3030
3031 zmac = zvni_mac_add(zvni, macaddr);
3032 if (!zmac) {
3033 zlog_debug("Failed to add MAC %s VNI %u",
3034 prefix_mac2str(macaddr, buf, sizeof(buf)),
3035 zvni->vni);
3036 return -1;
3037 }
3038
3039 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
3040 memset(&zmac->flags, 0, sizeof(uint32_t));
3041 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
3042 } else {
3043 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
3044 /*
3045 * We don't change the MAC to local upon a neighbor
3046 * learn event, we wait for the explicit local MAC
3047 * learn. However, we have to compute its sequence
3048 * number in preparation for when it actually turns
3049 * local.
3050 */
3051 upd_mac_seq = true;
3052 }
3053 }
3054
3055 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
3056 if (!zvrf) {
3057 if (IS_ZEBRA_DEBUG_VXLAN)
3058 zlog_debug("\tUnable to find vrf for: %d",
3059 zvni->vxlan_if->vrf_id);
3060 return -1;
3061 }
3062
3063 /* Check if the neighbor exists. */
3064 n = zvni_neigh_lookup(zvni, ip);
3065 if (!n) {
3066 /* New neighbor - create */
3067 n = zvni_neigh_add(zvni, ip, macaddr);
3068 if (!n) {
3069 flog_err(
3070 EC_ZEBRA_MAC_ADD_FAILED,
3071 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
3072 ipaddr2str(ip, buf2, sizeof(buf2)),
3073 prefix_mac2str(macaddr, buf, sizeof(buf)),
3074 ifp->name, ifp->ifindex, zvni->vni);
3075 return -1;
3076 }
3077 /* Set "local" forwarding info. */
3078 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3079 n->ifindex = ifp->ifindex;
3080 } else {
3081 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
3082 bool mac_different;
3083 bool cur_is_router;
3084
3085 /* Note any changes and see if of interest to BGP. */
3086 mac_different = (memcmp(n->emac.octet,
3087 macaddr->octet, ETH_ALEN) != 0) ? 1 : 0;
3088 cur_is_router = !!CHECK_FLAG(n->flags,
3089 ZEBRA_NEIGH_ROUTER_FLAG);
3090 if (!mac_different && is_router == cur_is_router) {
3091 if (IS_ZEBRA_DEBUG_VXLAN)
3092 zlog_debug(
3093 "\tIgnoring entry mac is the same and is_router == cur_is_router");
3094 n->ifindex = ifp->ifindex;
3095 return 0;
3096 }
3097
3098 if (!mac_different) {
3099 bool is_neigh_freezed = false;
3100
3101 /* Only the router flag has changed. */
3102 if (is_router)
3103 SET_FLAG(n->flags,
3104 ZEBRA_NEIGH_ROUTER_FLAG);
3105 else
3106 UNSET_FLAG(n->flags,
3107 ZEBRA_NEIGH_ROUTER_FLAG);
3108
3109 /* Neigh is in freeze state and freeze action
3110 * is enabled, do not send update to client.
3111 */
3112 is_neigh_freezed = (zvrf->dup_addr_detect &&
3113 zvrf->dad_freeze &&
3114 CHECK_FLAG(n->flags,
3115 ZEBRA_NEIGH_DUPLICATE));
3116
3117 if (IS_ZEBRA_NEIGH_ACTIVE(n) &&
3118 !is_neigh_freezed)
3119 return zvni_neigh_send_add_to_client(
3120 zvni->vni, ip, macaddr,
3121 n->flags, n->loc_seq);
3122 else {
3123 if (IS_ZEBRA_DEBUG_VXLAN)
3124 zlog_debug(
3125 "\tNeighbor active and frozen");
3126 }
3127 return 0;
3128 }
3129
3130 /* The MAC has changed, need to issue a delete
3131 * first as this means a different MACIP route.
3132 * Also, need to do some unlinking/relinking.
3133 * We also need to update the MAC's sequence number
3134 * in different situations.
3135 */
3136 if (IS_ZEBRA_NEIGH_ACTIVE(n))
3137 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
3138 &n->emac, 0, n->state);
3139 old_zmac = zvni_mac_lookup(zvni, &n->emac);
3140 if (old_zmac) {
3141 old_mac_seq = CHECK_FLAG(old_zmac->flags,
3142 ZEBRA_MAC_REMOTE) ?
3143 old_zmac->rem_seq : old_zmac->loc_seq;
3144 neigh_mac_change = upd_mac_seq = true;
3145 listnode_delete(old_zmac->neigh_list, n);
3146 zvni_deref_ip2mac(zvni, old_zmac);
3147 }
3148
3149 /* Update the forwarding info. */
3150 n->ifindex = ifp->ifindex;
3151 memcpy(&n->emac, macaddr, ETH_ALEN);
3152
3153 /* Link to new MAC */
3154 listnode_add_sort(zmac->neigh_list, n);
3155 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
3156 /*
3157 * Neighbor has moved from remote to local. Its
3158 * MAC could have also changed as part of the move.
3159 */
3160 if (memcmp(n->emac.octet, macaddr->octet,
3161 ETH_ALEN) != 0) {
3162 old_zmac = zvni_mac_lookup(zvni, &n->emac);
3163 if (old_zmac) {
3164 old_mac_seq = CHECK_FLAG(
3165 old_zmac->flags,
3166 ZEBRA_MAC_REMOTE) ?
3167 old_zmac->rem_seq :
3168 old_zmac->loc_seq;
3169 neigh_mac_change = upd_mac_seq = true;
3170 listnode_delete(old_zmac->neigh_list,
3171 n);
3172 zvni_deref_ip2mac(zvni, old_zmac);
3173 }
3174
3175 /* Link to new MAC */
3176 memcpy(&n->emac, macaddr, ETH_ALEN);
3177 listnode_add_sort(zmac->neigh_list, n);
3178 }
3179 /* Based on Mobility event Scenario-B from the
3180 * draft, neigh's previous state was remote treat this
3181 * event for DAD.
3182 */
3183 neigh_was_remote = true;
3184 vtep_ip = n->r_vtep_ip;
3185 /* Mark appropriately */
3186 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3187 n->r_vtep_ip.s_addr = 0;
3188 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3189 n->ifindex = ifp->ifindex;
3190 }
3191 }
3192
3193 /* If MAC was previously remote, or the neighbor had a different
3194 * MAC earlier, recompute the sequence number.
3195 */
3196 if (upd_mac_seq) {
3197 uint32_t seq1, seq2;
3198
3199 seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ?
3200 zmac->rem_seq + 1 : zmac->loc_seq;
3201 seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
3202 mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ?
3203 MAX(seq1, seq2) : zmac->loc_seq;
3204 }
3205
3206 /* Mark Router flag (R-bit) */
3207 if (is_router)
3208 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
3209 else
3210 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
3211
3212 /* Check old and/or new MAC detected as duplicate mark
3213 * the neigh as duplicate
3214 */
3215 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
3216 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
3217 "VNI %u: MAC %s IP %s detected as duplicate during local update, inherit duplicate from MAC",
3218 zvni->vni,
3219 prefix_mac2str(macaddr, buf, sizeof(buf)),
3220 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
3221 }
3222
3223 /* For IP Duplicate Address Detection (DAD) is trigger,
3224 * when the event is extended mobility based on scenario-B
3225 * from the draft, IP/Neigh's MAC binding changed and
3226 * neigh's previous state was remote.
3227 */
3228 if (neigh_mac_change && neigh_was_remote)
3229 do_dad = true;
3230
3231 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
3232 &neigh_on_hold, true);
3233
3234 /* Before we program this in BGP, we need to check if MAC is locally
3235 * learnt. If not, force neighbor to be inactive and reset its seq.
3236 */
3237 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
3238 ZEBRA_NEIGH_SET_INACTIVE(n);
3239 n->loc_seq = 0;
3240 zmac->loc_seq = mac_new_seq;
3241 return 0;
3242 }
3243
3244 /* If the MAC's sequence number has changed, inform the MAC and all
3245 * neighbors associated with the MAC to BGP, else just inform this
3246 * neighbor.
3247 */
3248 if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
3249 if (IS_ZEBRA_DEBUG_VXLAN)
3250 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
3251 prefix_mac2str(macaddr, buf, sizeof(buf)),
3252 zvni->vni, zmac->loc_seq, mac_new_seq);
3253 zmac->loc_seq = mac_new_seq;
3254 if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
3255 zmac->flags, zmac->loc_seq))
3256 return -1;
3257 zvni_process_neigh_on_local_mac_change(zvni, zmac, 1);
3258 return 0;
3259 }
3260
3261 n->loc_seq = zmac->loc_seq;
3262
3263 if (!neigh_on_hold) {
3264 ZEBRA_NEIGH_SET_ACTIVE(n);
3265
3266 return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
3267 n->flags, n->loc_seq);
3268 } else {
3269 if (IS_ZEBRA_DEBUG_VXLAN)
3270 zlog_debug("\tNeighbor on hold not sending");
3271 }
3272 return 0;
3273 }
3274
3275 static int zvni_remote_neigh_update(zebra_vni_t *zvni,
3276 struct interface *ifp,
3277 struct ipaddr *ip,
3278 struct ethaddr *macaddr,
3279 uint16_t state)
3280 {
3281 char buf[ETHER_ADDR_STRLEN];
3282 char buf2[INET6_ADDRSTRLEN];
3283 zebra_neigh_t *n = NULL;
3284 zebra_mac_t *zmac = NULL;
3285
3286 /* If the neighbor is unknown, there is no further action. */
3287 n = zvni_neigh_lookup(zvni, ip);
3288 if (!n)
3289 return 0;
3290
3291 /* If a remote entry, see if it needs to be refreshed */
3292 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
3293 #ifdef GNU_LINUX
3294 if (state & NUD_STALE)
3295 zvni_neigh_install(zvni, n);
3296 #endif
3297 } else {
3298 /* We got a "remote" neighbor notification for an entry
3299 * we think is local. This can happen in a multihoming
3300 * scenario - but only if the MAC is already "remote".
3301 * Just mark our entry as "remote".
3302 */
3303 zmac = zvni_mac_lookup(zvni, macaddr);
3304 if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
3305 zlog_debug(
3306 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
3307 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
3308 prefix_mac2str(macaddr, buf, sizeof(buf)),
3309 zvni->vni);
3310 return -1;
3311 }
3312
3313 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3314 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3315 ZEBRA_NEIGH_SET_ACTIVE(n);
3316 n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
3317 }
3318
3319 return 0;
3320 }
3321
3322 /*
3323 * Make hash key for MAC.
3324 */
3325 static unsigned int mac_hash_keymake(const void *p)
3326 {
3327 const zebra_mac_t *pmac = p;
3328 const void *pnt = (void *)pmac->macaddr.octet;
3329
3330 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
3331 }
3332
3333 /*
3334 * Compare two MAC addresses.
3335 */
3336 static bool mac_cmp(const void *p1, const void *p2)
3337 {
3338 const zebra_mac_t *pmac1 = p1;
3339 const zebra_mac_t *pmac2 = p2;
3340
3341 if (pmac1 == NULL && pmac2 == NULL)
3342 return true;
3343
3344 if (pmac1 == NULL || pmac2 == NULL)
3345 return false;
3346
3347 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN)
3348 == 0);
3349 }
3350
3351 /*
3352 * Callback to allocate MAC hash entry.
3353 */
3354 static void *zvni_mac_alloc(void *p)
3355 {
3356 const zebra_mac_t *tmp_mac = p;
3357 zebra_mac_t *mac;
3358
3359 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
3360 *mac = *tmp_mac;
3361
3362 return ((void *)mac);
3363 }
3364
3365 /*
3366 * Add MAC entry.
3367 */
3368 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
3369 {
3370 zebra_mac_t tmp_mac;
3371 zebra_mac_t *mac = NULL;
3372
3373 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
3374 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
3375 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
3376 assert(mac);
3377
3378 mac->zvni = zvni;
3379 mac->dad_mac_auto_recovery_timer = NULL;
3380
3381 mac->neigh_list = list_new();
3382 mac->neigh_list->cmp = neigh_list_cmp;
3383
3384 return mac;
3385 }
3386
3387 /*
3388 * Delete MAC entry.
3389 */
3390 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
3391 {
3392 zebra_mac_t *tmp_mac;
3393
3394 /* Cancel auto recovery */
3395 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3396
3397 list_delete(&mac->neigh_list);
3398
3399 /* Free the VNI hash entry and allocated memory. */
3400 tmp_mac = hash_release(zvni->mac_table, mac);
3401 XFREE(MTYPE_MAC, tmp_mac);
3402
3403 return 0;
3404 }
3405
3406 /*
3407 * Free MAC hash entry (callback)
3408 */
3409 static void zvni_mac_del_hash_entry(struct hash_bucket *bucket, void *arg)
3410 {
3411 struct mac_walk_ctx *wctx = arg;
3412 zebra_mac_t *mac = bucket->data;
3413
3414 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
3415 || ((wctx->flags & DEL_REMOTE_MAC)
3416 && (mac->flags & ZEBRA_MAC_REMOTE))
3417 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
3418 && (mac->flags & ZEBRA_MAC_REMOTE)
3419 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
3420 &wctx->r_vtep_ip))) {
3421 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
3422 zvni_mac_send_del_to_client(wctx->zvni->vni,
3423 &mac->macaddr);
3424 }
3425
3426 if (wctx->uninstall)
3427 zvni_mac_uninstall(wctx->zvni, mac);
3428
3429 zvni_mac_del(wctx->zvni, mac);
3430 }
3431
3432 return;
3433 }
3434
3435 /*
3436 * Delete all MAC entries from specific VTEP for a particular VNI.
3437 */
3438 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
3439 struct in_addr *r_vtep_ip)
3440 {
3441 struct mac_walk_ctx wctx;
3442
3443 if (!zvni->mac_table)
3444 return;
3445
3446 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
3447 wctx.zvni = zvni;
3448 wctx.uninstall = uninstall;
3449 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
3450 wctx.r_vtep_ip = *r_vtep_ip;
3451
3452 hash_iterate(zvni->mac_table, zvni_mac_del_hash_entry, &wctx);
3453 }
3454
3455 /*
3456 * Delete all MAC entries for this VNI.
3457 */
3458 static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
3459 uint32_t flags)
3460 {
3461 struct mac_walk_ctx wctx;
3462
3463 if (!zvni->mac_table)
3464 return;
3465
3466 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
3467 wctx.zvni = zvni;
3468 wctx.uninstall = uninstall;
3469 wctx.upd_client = upd_client;
3470 wctx.flags = flags;
3471
3472 hash_iterate(zvni->mac_table, zvni_mac_del_hash_entry, &wctx);
3473 }
3474
3475 /*
3476 * Look up MAC hash entry.
3477 */
3478 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
3479 {
3480 zebra_mac_t tmp;
3481 zebra_mac_t *pmac;
3482
3483 memset(&tmp, 0, sizeof(tmp));
3484 memcpy(&tmp.macaddr, mac, ETH_ALEN);
3485 pmac = hash_lookup(zvni->mac_table, &tmp);
3486
3487 return pmac;
3488 }
3489
3490 /*
3491 * Inform BGP about local MAC addition.
3492 */
3493 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
3494 uint8_t mac_flags, uint32_t seq)
3495 {
3496 uint8_t flags = 0;
3497
3498 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
3499 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
3500 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
3501 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
3502
3503 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
3504 seq, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_ADD);
3505 }
3506
3507 /*
3508 * Inform BGP about local MAC deletion.
3509 */
3510 static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
3511 {
3512 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
3513 0 /* seq */, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_DEL);
3514 }
3515
3516 /*
3517 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
3518 * notifications, to see if they are of interest.
3519 */
3520 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
3521 struct interface *br_if, vlanid_t vid)
3522 {
3523 struct zebra_ns *zns;
3524 struct route_node *rn;
3525 struct interface *tmp_if = NULL;
3526 struct zebra_if *zif;
3527 struct zebra_l2info_bridge *br;
3528 struct zebra_l2info_vxlan *vxl = NULL;
3529 uint8_t bridge_vlan_aware;
3530 zebra_vni_t *zvni;
3531 int found = 0;
3532
3533 /* Determine if bridge is VLAN-aware or not */
3534 zif = br_if->info;
3535 assert(zif);
3536 br = &zif->l2info.br;
3537 bridge_vlan_aware = br->vlan_aware;
3538
3539 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3540 /* TODO: Optimize with a hash. */
3541 zns = zebra_ns_lookup(NS_DEFAULT);
3542 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3543 tmp_if = (struct interface *)rn->info;
3544 if (!tmp_if)
3545 continue;
3546 zif = tmp_if->info;
3547 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3548 continue;
3549 if (!if_is_operative(tmp_if))
3550 continue;
3551 vxl = &zif->l2info.vxl;
3552
3553 if (zif->brslave_info.br_if != br_if)
3554 continue;
3555
3556 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3557 found = 1;
3558 break;
3559 }
3560 }
3561
3562 if (!found)
3563 return NULL;
3564
3565 zvni = zvni_lookup(vxl->vni);
3566 return zvni;
3567 }
3568
3569 /*
3570 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3571 * neighbor notifications, to see if they are of interest.
3572 */
3573 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
3574 struct interface *br_if)
3575 {
3576 struct zebra_ns *zns;
3577 struct route_node *rn;
3578 struct interface *tmp_if = NULL;
3579 struct zebra_if *zif;
3580 struct zebra_l2info_bridge *br;
3581 struct zebra_l2info_vxlan *vxl = NULL;
3582 uint8_t bridge_vlan_aware;
3583 vlanid_t vid = 0;
3584 zebra_vni_t *zvni;
3585 int found = 0;
3586
3587 if (!br_if)
3588 return NULL;
3589
3590 /* Make sure the linked interface is a bridge. */
3591 if (!IS_ZEBRA_IF_BRIDGE(br_if))
3592 return NULL;
3593
3594 /* Determine if bridge is VLAN-aware or not */
3595 zif = br_if->info;
3596 assert(zif);
3597 br = &zif->l2info.br;
3598 bridge_vlan_aware = br->vlan_aware;
3599 if (bridge_vlan_aware) {
3600 struct zebra_l2info_vlan *vl;
3601
3602 if (!IS_ZEBRA_IF_VLAN(ifp))
3603 return NULL;
3604
3605 zif = ifp->info;
3606 assert(zif);
3607 vl = &zif->l2info.vl;
3608 vid = vl->vid;
3609 }
3610
3611 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3612 /* TODO: Optimize with a hash. */
3613 zns = zebra_ns_lookup(NS_DEFAULT);
3614 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3615 tmp_if = (struct interface *)rn->info;
3616 if (!tmp_if)
3617 continue;
3618 zif = tmp_if->info;
3619 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3620 continue;
3621 if (!if_is_operative(tmp_if))
3622 continue;
3623 vxl = &zif->l2info.vxl;
3624
3625 if (zif->brslave_info.br_if != br_if)
3626 continue;
3627
3628 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3629 found = 1;
3630 break;
3631 }
3632 }
3633
3634 if (!found)
3635 return NULL;
3636
3637 zvni = zvni_lookup(vxl->vni);
3638 return zvni;
3639 }
3640
3641 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
3642 * of two cases:
3643 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
3644 * linked to the bridge
3645 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
3646 * itself
3647 */
3648 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
3649 {
3650 struct zebra_ns *zns;
3651 struct route_node *rn;
3652 struct interface *tmp_if = NULL;
3653 struct zebra_if *zif;
3654 struct zebra_l2info_bridge *br;
3655 struct zebra_l2info_vlan *vl;
3656 uint8_t bridge_vlan_aware;
3657 int found = 0;
3658
3659 /* Defensive check, caller expected to invoke only with valid bridge. */
3660 if (!br_if)
3661 return NULL;
3662
3663 /* Determine if bridge is VLAN-aware or not */
3664 zif = br_if->info;
3665 assert(zif);
3666 br = &zif->l2info.br;
3667 bridge_vlan_aware = br->vlan_aware;
3668
3669 /* Check oper status of the SVI. */
3670 if (!bridge_vlan_aware)
3671 return if_is_operative(br_if) ? br_if : NULL;
3672
3673 /* Identify corresponding VLAN interface. */
3674 /* TODO: Optimize with a hash. */
3675 zns = zebra_ns_lookup(NS_DEFAULT);
3676 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3677 tmp_if = (struct interface *)rn->info;
3678 /* Check oper status of the SVI. */
3679 if (!tmp_if || !if_is_operative(tmp_if))
3680 continue;
3681 zif = tmp_if->info;
3682 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
3683 || zif->link != br_if)
3684 continue;
3685 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
3686
3687 if (vl->vid == vid) {
3688 found = 1;
3689 break;
3690 }
3691 }
3692
3693 return found ? tmp_if : NULL;
3694 }
3695
3696 /*
3697 * Install remote MAC into the kernel.
3698 */
3699 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
3700 {
3701 struct zebra_if *zif;
3702 struct zebra_l2info_vxlan *vxl;
3703 bool sticky;
3704
3705 if (!(mac->flags & ZEBRA_MAC_REMOTE))
3706 return 0;
3707
3708 zif = zvni->vxlan_if->info;
3709 if (!zif)
3710 return -1;
3711 vxl = &zif->l2info.vxl;
3712
3713 sticky = !!CHECK_FLAG(mac->flags,
3714 (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
3715
3716 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
3717 mac->fwd_info.r_vtep_ip, sticky);
3718 }
3719
3720 /*
3721 * Uninstall remote MAC from the kernel.
3722 */
3723 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac)
3724 {
3725 struct zebra_if *zif;
3726 struct zebra_l2info_vxlan *vxl;
3727 struct in_addr vtep_ip;
3728 struct interface *ifp;
3729
3730 if (!(mac->flags & ZEBRA_MAC_REMOTE))
3731 return 0;
3732
3733 if (!zvni->vxlan_if) {
3734 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
3735 zvni->vni, zvni);
3736 return -1;
3737 }
3738
3739 zif = zvni->vxlan_if->info;
3740 if (!zif)
3741 return -1;
3742 vxl = &zif->l2info.vxl;
3743
3744 ifp = zvni->vxlan_if;
3745 vtep_ip = mac->fwd_info.r_vtep_ip;
3746
3747 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip);
3748 }
3749
3750 /*
3751 * Install MAC hash entry - called upon access VLAN change.
3752 */
3753 static void zvni_install_mac_hash(struct hash_bucket *bucket, void *ctxt)
3754 {
3755 zebra_mac_t *mac;
3756 struct mac_walk_ctx *wctx = ctxt;
3757
3758 mac = (zebra_mac_t *)bucket->data;
3759
3760 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
3761 zvni_mac_install(wctx->zvni, mac);
3762 }
3763
3764 /*
3765 * Count of remote neighbors referencing this MAC.
3766 */
3767 static int remote_neigh_count(zebra_mac_t *zmac)
3768 {
3769 zebra_neigh_t *n = NULL;
3770 struct listnode *node = NULL;
3771 int count = 0;
3772
3773 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
3774 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
3775 count++;
3776 }
3777
3778 return count;
3779 }
3780
3781 /*
3782 * Decrement neighbor refcount of MAC; uninstall and free it if
3783 * appropriate.
3784 */
3785 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac)
3786 {
3787 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
3788 return;
3789
3790 /* If all remote neighbors referencing a remote MAC go away,
3791 * we need to uninstall the MAC.
3792 */
3793 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
3794 remote_neigh_count(mac) == 0) {
3795 zvni_mac_uninstall(zvni, mac);
3796 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3797 }
3798
3799 /* If no neighbors, delete the MAC. */
3800 if (list_isempty(mac->neigh_list))
3801 zvni_mac_del(zvni, mac);
3802 }
3803
3804 /*
3805 * Read and populate local MACs and neighbors corresponding to this VNI.
3806 */
3807 static void zvni_read_mac_neigh(zebra_vni_t *zvni, struct interface *ifp)
3808 {
3809 struct zebra_ns *zns;
3810 struct zebra_if *zif;
3811 struct interface *vlan_if;
3812 struct zebra_l2info_vxlan *vxl;
3813 struct interface *vrr_if;
3814
3815 zif = ifp->info;
3816 vxl = &zif->l2info.vxl;
3817 zns = zebra_ns_lookup(NS_DEFAULT);
3818
3819 if (IS_ZEBRA_DEBUG_VXLAN)
3820 zlog_debug(
3821 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
3822 ifp->name, ifp->ifindex, zvni->vni,
3823 zif->brslave_info.bridge_ifindex);
3824
3825 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
3826 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
3827 if (vlan_if) {
3828
3829 /* Add SVI MAC-IP */
3830 zvni_add_macip_for_intf(vlan_if, zvni);
3831
3832 /* Add VRR MAC-IP - if any*/
3833 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
3834 if (vrr_if)
3835 zvni_add_macip_for_intf(vrr_if, zvni);
3836
3837 neigh_read_for_vlan(zns, vlan_if);
3838 }
3839 }
3840
3841 /*
3842 * Hash function for VNI.
3843 */
3844 static unsigned int vni_hash_keymake(const void *p)
3845 {
3846 const zebra_vni_t *zvni = p;
3847
3848 return (jhash_1word(zvni->vni, 0));
3849 }
3850
3851 /*
3852 * Compare 2 VNI hash entries.
3853 */
3854 static bool vni_hash_cmp(const void *p1, const void *p2)
3855 {
3856 const zebra_vni_t *zvni1 = p1;
3857 const zebra_vni_t *zvni2 = p2;
3858
3859 return (zvni1->vni == zvni2->vni);
3860 }
3861
3862 static int vni_list_cmp(void *p1, void *p2)
3863 {
3864 const zebra_vni_t *zvni1 = p1;
3865 const zebra_vni_t *zvni2 = p2;
3866
3867 if (zvni1->vni == zvni2->vni)
3868 return 0;
3869 return (zvni1->vni < zvni2->vni) ? -1 : 1;
3870 }
3871
3872 /*
3873 * Callback to allocate VNI hash entry.
3874 */
3875 static void *zvni_alloc(void *p)
3876 {
3877 const zebra_vni_t *tmp_vni = p;
3878 zebra_vni_t *zvni;
3879
3880 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
3881 zvni->vni = tmp_vni->vni;
3882 return ((void *)zvni);
3883 }
3884
3885 /*
3886 * Look up VNI hash entry.
3887 */
3888 static zebra_vni_t *zvni_lookup(vni_t vni)
3889 {
3890 struct zebra_vrf *zvrf;
3891 zebra_vni_t tmp_vni;
3892 zebra_vni_t *zvni = NULL;
3893
3894 zvrf = zebra_vrf_get_evpn();
3895 assert(zvrf);
3896 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
3897 tmp_vni.vni = vni;
3898 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
3899
3900 return zvni;
3901 }
3902
3903 /*
3904 * Add VNI hash entry.
3905 */
3906 static zebra_vni_t *zvni_add(vni_t vni)
3907 {
3908 struct zebra_vrf *zvrf;
3909 zebra_vni_t tmp_zvni;
3910 zebra_vni_t *zvni = NULL;
3911
3912 zvrf = zebra_vrf_get_evpn();
3913 assert(zvrf);
3914 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
3915 tmp_zvni.vni = vni;
3916 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
3917 assert(zvni);
3918
3919 /* Create hash table for MAC */
3920 zvni->mac_table =
3921 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
3922
3923 /* Create hash table for neighbors */
3924 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
3925 "Zebra VNI Neighbor Table");
3926
3927 return zvni;
3928 }
3929
3930 /*
3931 * Delete VNI hash entry.
3932 */
3933 static int zvni_del(zebra_vni_t *zvni)
3934 {
3935 struct zebra_vrf *zvrf;
3936 zebra_vni_t *tmp_zvni;
3937
3938 zvrf = zebra_vrf_get_evpn();
3939 assert(zvrf);
3940
3941 zvni->vxlan_if = NULL;
3942
3943 /* Remove references to the BUM mcast grp */
3944 zebra_vxlan_sg_deref(zvni->local_vtep_ip, zvni->mcast_grp);
3945
3946 /* Free the neighbor hash table. */
3947 hash_free(zvni->neigh_table);
3948 zvni->neigh_table = NULL;
3949
3950 /* Free the MAC hash table. */
3951 hash_free(zvni->mac_table);
3952 zvni->mac_table = NULL;
3953
3954 /* Free the VNI hash entry and allocated memory. */
3955 tmp_zvni = hash_release(zvrf->vni_table, zvni);
3956 XFREE(MTYPE_ZVNI, tmp_zvni);
3957
3958 return 0;
3959 }
3960
3961 /*
3962 * Inform BGP about local VNI addition.
3963 */
3964 static int zvni_send_add_to_client(zebra_vni_t *zvni)
3965 {
3966 struct zserv *client;
3967 struct stream *s;
3968
3969 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
3970 /* BGP may not be running. */
3971 if (!client)
3972 return 0;
3973
3974 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
3975
3976 zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
3977 stream_putl(s, zvni->vni);
3978 stream_put_in_addr(s, &zvni->local_vtep_ip);
3979 stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
3980 stream_put_in_addr(s, &zvni->mcast_grp);
3981
3982 /* Write packet size. */
3983 stream_putw_at(s, 0, stream_get_endp(s));
3984
3985 if (IS_ZEBRA_DEBUG_VXLAN)
3986 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s", zvni->vni,
3987 inet_ntoa(zvni->local_vtep_ip),
3988 vrf_id_to_name(zvni->vrf_id),
3989 zebra_route_string(client->proto));
3990
3991 client->vniadd_cnt++;
3992 return zserv_send_message(client, s);
3993 }
3994
3995 /*
3996 * Inform BGP about local VNI deletion.
3997 */
3998 static int zvni_send_del_to_client(vni_t vni)
3999 {
4000 struct zserv *client;
4001 struct stream *s;
4002
4003 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4004 /* BGP may not be running. */
4005 if (!client)
4006 return 0;
4007
4008 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4009 stream_reset(s);
4010
4011 zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
4012 stream_putl(s, vni);
4013
4014 /* Write packet size. */
4015 stream_putw_at(s, 0, stream_get_endp(s));
4016
4017 if (IS_ZEBRA_DEBUG_VXLAN)
4018 zlog_debug("Send VNI_DEL %u to %s", vni,
4019 zebra_route_string(client->proto));
4020
4021 client->vnidel_cnt++;
4022 return zserv_send_message(client, s);
4023 }
4024
4025 /*
4026 * Build the VNI hash table by going over the VxLAN interfaces. This
4027 * is called when EVPN (advertise-all-vni) is enabled.
4028 */
4029 static void zvni_build_hash_table(void)
4030 {
4031 struct zebra_ns *zns;
4032 struct route_node *rn;
4033 struct interface *ifp;
4034
4035 /* Walk VxLAN interfaces and create VNI hash. */
4036 zns = zebra_ns_lookup(NS_DEFAULT);
4037 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4038 vni_t vni;
4039 zebra_vni_t *zvni = NULL;
4040 zebra_l3vni_t *zl3vni = NULL;
4041 struct zebra_if *zif;
4042 struct zebra_l2info_vxlan *vxl;
4043
4044 ifp = (struct interface *)rn->info;
4045 if (!ifp)
4046 continue;
4047 zif = ifp->info;
4048 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4049 continue;
4050
4051 vxl = &zif->l2info.vxl;
4052 vni = vxl->vni;
4053
4054 /* L3-VNI and L2-VNI are handled seperately */
4055 zl3vni = zl3vni_lookup(vni);
4056 if (zl3vni) {
4057
4058 if (IS_ZEBRA_DEBUG_VXLAN)
4059 zlog_debug(
4060 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
4061 ifp->name, ifp->ifindex, vni);
4062
4063 /* associate with vxlan_if */
4064 zl3vni->local_vtep_ip = vxl->vtep_ip;
4065 zl3vni->vxlan_if = ifp;
4066
4067 /*
4068 * we need to associate with SVI.
4069 * we can associate with svi-if only after association
4070 * with vxlan-intf is complete
4071 */
4072 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
4073
4074 if (is_l3vni_oper_up(zl3vni))
4075 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4076
4077 } else {
4078 struct interface *vlan_if = NULL;
4079
4080 if (IS_ZEBRA_DEBUG_VXLAN)
4081 zlog_debug(
4082 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
4083 ifp->name, ifp->ifindex, vni,
4084 inet_ntoa(vxl->vtep_ip));
4085
4086 /* VNI hash entry is expected to exist, if the BGP process is killed */
4087 zvni = zvni_lookup(vni);
4088 if (zvni) {
4089 zlog_debug(
4090 "VNI hash already present for IF %s(%u) L2-VNI %u",
4091 ifp->name, ifp->ifindex, vni);
4092
4093 /*
4094 * Inform BGP if intf is up and mapped to
4095 * bridge.
4096 */
4097 if (if_is_operative(ifp) &&
4098 zif->brslave_info.br_if)
4099 zvni_send_add_to_client(zvni);
4100
4101 /* Send Local MAC-entries to client */
4102 zvni_send_mac_to_client(zvni);
4103
4104 /* Send Loval Neighbor entries to client */
4105 zvni_send_neigh_to_client(zvni);
4106 } else {
4107 zvni = zvni_add(vni);
4108 if (!zvni) {
4109 zlog_debug(
4110 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
4111 ifp->name, ifp->ifindex, vni);
4112 return;
4113 }
4114
4115 if (zvni->local_vtep_ip.s_addr !=
4116 vxl->vtep_ip.s_addr ||
4117 zvni->mcast_grp.s_addr !=
4118 vxl->mcast_grp.s_addr) {
4119 zebra_vxlan_sg_deref(
4120 zvni->local_vtep_ip,
4121 zvni->mcast_grp);
4122 zebra_vxlan_sg_ref(vxl->vtep_ip,
4123 vxl->mcast_grp);
4124 zvni->local_vtep_ip = vxl->vtep_ip;
4125 zvni->mcast_grp = vxl->mcast_grp;
4126 }
4127 zvni->vxlan_if = ifp;
4128 vlan_if = zvni_map_to_svi(vxl->access_vlan,
4129 zif->brslave_info.br_if);
4130 if (vlan_if) {
4131 zvni->vrf_id = vlan_if->vrf_id;
4132 zl3vni = zl3vni_from_vrf(
4133 vlan_if->vrf_id);
4134 if (zl3vni)
4135 listnode_add_sort(
4136 zl3vni->l2vnis, zvni);
4137 }
4138
4139 /*
4140 * Inform BGP if intf is up and mapped to
4141 * bridge.
4142 */
4143 if (if_is_operative(ifp) &&
4144 zif->brslave_info.br_if)
4145 zvni_send_add_to_client(zvni);
4146 }
4147 }
4148 }
4149 }
4150
4151 /*
4152 * See if remote VTEP matches with prefix.
4153 */
4154 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
4155 {
4156 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
4157 }
4158
4159 /*
4160 * Locate remote VTEP in VNI hash table.
4161 */
4162 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
4163 {
4164 zebra_vtep_t *zvtep;
4165
4166 if (!zvni)
4167 return NULL;
4168
4169 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
4170 if (zvni_vtep_match(vtep_ip, zvtep))
4171 break;
4172 }
4173
4174 return zvtep;
4175 }
4176
4177 /*
4178 * Add remote VTEP to VNI hash table.
4179 */
4180 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip,
4181 int flood_control)
4182
4183 {
4184 zebra_vtep_t *zvtep;
4185
4186 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
4187
4188 zvtep->vtep_ip = *vtep_ip;
4189 zvtep->flood_control = flood_control;
4190
4191 if (zvni->vteps)
4192 zvni->vteps->prev = zvtep;
4193 zvtep->next = zvni->vteps;
4194 zvni->vteps = zvtep;
4195
4196 return zvtep;
4197 }
4198
4199 /*
4200 * Remove remote VTEP from VNI hash table.
4201 */
4202 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
4203 {
4204 if (zvtep->next)
4205 zvtep->next->prev = zvtep->prev;
4206 if (zvtep->prev)
4207 zvtep->prev->next = zvtep->next;
4208 else
4209 zvni->vteps = zvtep->next;
4210
4211 zvtep->prev = zvtep->next = NULL;
4212 XFREE(MTYPE_ZVNI_VTEP, zvtep);
4213
4214 return 0;
4215 }
4216
4217 /*
4218 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
4219 * uninstall from kernel if asked to.
4220 */
4221 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
4222 {
4223 zebra_vtep_t *zvtep, *zvtep_next;
4224
4225 if (!zvni)
4226 return -1;
4227
4228 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
4229 zvtep_next = zvtep->next;
4230 if (uninstall)
4231 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
4232 zvni_vtep_del(zvni, zvtep);
4233 }
4234
4235 return 0;
4236 }
4237
4238 /*
4239 * Install remote VTEP into the kernel if the remote VTEP has asked
4240 * for head-end-replication.
4241 */
4242 static int zvni_vtep_install(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
4243 {
4244 if (is_vxlan_flooding_head_end() &&
4245 (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL))
4246 return kernel_add_vtep(zvni->vni, zvni->vxlan_if,
4247 &zvtep->vtep_ip);
4248 return 0;
4249 }
4250
4251 /*
4252 * Uninstall remote VTEP from the kernel.
4253 */
4254 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
4255 {
4256 if (!zvni->vxlan_if) {
4257 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
4258 zvni->vni, zvni);
4259 return -1;
4260 }
4261
4262 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
4263 }
4264
4265 /*
4266 * Install or uninstall flood entries in the kernel corresponding to
4267 * remote VTEPs. This is invoked upon change to BUM handling.
4268 */
4269 static void zvni_handle_flooding_remote_vteps(struct hash_bucket *bucket,
4270 void *zvrf)
4271 {
4272 zebra_vni_t *zvni;
4273 zebra_vtep_t *zvtep;
4274
4275 zvni = (zebra_vni_t *)bucket->data;
4276 if (!zvni)
4277 return;
4278
4279 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
4280 if (is_vxlan_flooding_head_end())
4281 zvni_vtep_install(zvni, zvtep);
4282 else
4283 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
4284 }
4285 }
4286
4287 /*
4288 * Cleanup VNI/VTEP and update kernel
4289 */
4290 static void zvni_cleanup_all(struct hash_bucket *bucket, void *arg)
4291 {
4292 zebra_vni_t *zvni = NULL;
4293 zebra_l3vni_t *zl3vni = NULL;
4294 struct zebra_vrf *zvrf = (struct zebra_vrf *)arg;
4295
4296 zvni = (zebra_vni_t *)bucket->data;
4297
4298 /* remove from l3-vni list */
4299 if (zvrf->l3vni)
4300 zl3vni = zl3vni_lookup(zvrf->l3vni);
4301 if (zl3vni)
4302 listnode_delete(zl3vni->l2vnis, zvni);
4303
4304 /* Free up all neighbors and MACs, if any. */
4305 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
4306 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
4307
4308 /* Free up all remote VTEPs, if any. */
4309 zvni_vtep_del_all(zvni, 1);
4310
4311 /* Delete the hash entry. */
4312 zvni_del(zvni);
4313 }
4314
4315 /* cleanup L3VNI */
4316 static void zl3vni_cleanup_all(struct hash_bucket *bucket, void *args)
4317 {
4318 zebra_l3vni_t *zl3vni = NULL;
4319
4320 zl3vni = (zebra_l3vni_t *)bucket->data;
4321
4322 zebra_vxlan_process_l3vni_oper_down(zl3vni);
4323 }
4324
4325 static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
4326 struct prefix *host)
4327 {
4328 struct host_rb_entry lookup;
4329 struct host_rb_entry *hle;
4330
4331 memset(&lookup, 0, sizeof(lookup));
4332 memcpy(&lookup.p, host, sizeof(*host));
4333
4334 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
4335 if (hle)
4336 return;
4337
4338 hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
4339 memcpy(hle, &lookup, sizeof(lookup));
4340
4341 RB_INSERT(host_rb_tree_entry, hrbe, hle);
4342 }
4343
4344 static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
4345 {
4346 struct host_rb_entry lookup;
4347 struct host_rb_entry *hle;
4348
4349 memset(&lookup, 0, sizeof(lookup));
4350 memcpy(&lookup.p, host, sizeof(*host));
4351
4352 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
4353 if (hle) {
4354 RB_REMOVE(host_rb_tree_entry, hrbe, hle);
4355 XFREE(MTYPE_HOST_PREFIX, hle);
4356 }
4357
4358 return;
4359 }
4360
4361 /*
4362 * Look up MAC hash entry.
4363 */
4364 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
4365 struct ethaddr *rmac)
4366 {
4367 zebra_mac_t tmp;
4368 zebra_mac_t *pmac;
4369
4370 memset(&tmp, 0, sizeof(tmp));
4371 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
4372 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
4373
4374 return pmac;
4375 }
4376
4377 /*
4378 * Callback to allocate RMAC hash entry.
4379 */
4380 static void *zl3vni_rmac_alloc(void *p)
4381 {
4382 const zebra_mac_t *tmp_rmac = p;
4383 zebra_mac_t *zrmac;
4384
4385 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
4386 *zrmac = *tmp_rmac;
4387
4388 return ((void *)zrmac);
4389 }
4390
4391 /*
4392 * Add RMAC entry to l3-vni
4393 */
4394 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac)
4395 {
4396 zebra_mac_t tmp_rmac;
4397 zebra_mac_t *zrmac = NULL;
4398
4399 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
4400 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
4401 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
4402 assert(zrmac);
4403
4404 RB_INIT(host_rb_tree_entry, &zrmac->host_rb);
4405
4406 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
4407 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
4408
4409 return zrmac;
4410 }
4411
4412 /*
4413 * Delete MAC entry.
4414 */
4415 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4416 {
4417 zebra_mac_t *tmp_rmac;
4418 struct host_rb_entry *hle;
4419
4420 while (!RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
4421 hle = RB_ROOT(host_rb_tree_entry, &zrmac->host_rb);
4422
4423 RB_REMOVE(host_rb_tree_entry, &zrmac->host_rb, hle);
4424 XFREE(MTYPE_HOST_PREFIX, hle);
4425 }
4426
4427 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
4428 XFREE(MTYPE_MAC, tmp_rmac);
4429
4430 return 0;
4431 }
4432
4433 /*
4434 * Install remote RMAC into the kernel.
4435 */
4436 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4437 {
4438 struct zebra_if *zif = NULL;
4439 struct zebra_l2info_vxlan *vxl = NULL;
4440
4441 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
4442 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
4443 return 0;
4444
4445 zif = zl3vni->vxlan_if->info;
4446 if (!zif)
4447 return -1;
4448
4449 vxl = &zif->l2info.vxl;
4450
4451 return kernel_add_mac(zl3vni->vxlan_if, vxl->access_vlan,
4452 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
4453 }
4454
4455 /*
4456 * Uninstall remote RMAC from the kernel.
4457 */
4458 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4459 {
4460 char buf[ETHER_ADDR_STRLEN];
4461 struct zebra_if *zif = NULL;
4462 struct zebra_l2info_vxlan *vxl = NULL;
4463
4464 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
4465 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
4466 return 0;
4467
4468 if (!zl3vni->vxlan_if) {
4469 zlog_debug(
4470 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
4471 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
4472 zl3vni->vni, zl3vni);
4473 return -1;
4474 }
4475
4476 zif = zl3vni->vxlan_if->info;
4477 if (!zif)
4478 return -1;
4479
4480 vxl = &zif->l2info.vxl;
4481
4482 return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
4483 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
4484 }
4485
4486 /* handle rmac add */
4487 static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
4488 struct ipaddr *vtep_ip,
4489 struct prefix *host_prefix)
4490 {
4491 char buf[ETHER_ADDR_STRLEN];
4492 char buf1[INET6_ADDRSTRLEN];
4493 zebra_mac_t *zrmac = NULL;
4494
4495 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
4496 if (!zrmac) {
4497
4498 zrmac = zl3vni_rmac_add(zl3vni, rmac);
4499 if (!zrmac) {
4500 zlog_debug(
4501 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
4502 prefix_mac2str(rmac, buf, sizeof(buf)),
4503 zl3vni->vni,
4504 ipaddr2str(vtep_ip, buf1, sizeof(buf1)));
4505 return -1;
4506 }
4507 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
4508 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
4509
4510 /* Send RMAC for FPM processing */
4511 hook_call(zebra_rmac_update, zrmac, zl3vni, false,
4512 "new RMAC added");
4513
4514 /* install rmac in kernel */
4515 zl3vni_rmac_install(zl3vni, zrmac);
4516 }
4517
4518 rb_find_or_add_host(&zrmac->host_rb, host_prefix);
4519
4520 return 0;
4521 }
4522
4523
4524 /* handle rmac delete */
4525 static void zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac,
4526 struct prefix *host_prefix)
4527 {
4528 rb_delete_host(&zrmac->host_rb, host_prefix);
4529
4530 if (RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
4531 /* uninstall from kernel */
4532 zl3vni_rmac_uninstall(zl3vni, zrmac);
4533
4534 /* Send RMAC for FPM processing */
4535 hook_call(zebra_rmac_update, zrmac, zl3vni, true,
4536 "RMAC deleted");
4537
4538 /* del the rmac entry */
4539 zl3vni_rmac_del(zl3vni, zrmac);
4540 }
4541 }
4542
4543 /*
4544 * Look up nh hash entry on a l3-vni.
4545 */
4546 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
4547 {
4548 zebra_neigh_t tmp;
4549 zebra_neigh_t *n;
4550
4551 memset(&tmp, 0, sizeof(tmp));
4552 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
4553 n = hash_lookup(zl3vni->nh_table, &tmp);
4554
4555 return n;
4556 }
4557
4558
4559 /*
4560 * Callback to allocate NH hash entry on L3-VNI.
4561 */
4562 static void *zl3vni_nh_alloc(void *p)
4563 {
4564 const zebra_neigh_t *tmp_n = p;
4565 zebra_neigh_t *n;
4566
4567 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
4568 *n = *tmp_n;
4569
4570 return ((void *)n);
4571 }
4572
4573 /*
4574 * Add neighbor entry.
4575 */
4576 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *ip,
4577 struct ethaddr *mac)
4578 {
4579 zebra_neigh_t tmp_n;
4580 zebra_neigh_t *n = NULL;
4581
4582 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
4583 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
4584 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
4585 assert(n);
4586
4587 RB_INIT(host_rb_tree_entry, &n->host_rb);
4588
4589 memcpy(&n->emac, mac, ETH_ALEN);
4590 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
4591 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
4592
4593 return n;
4594 }
4595
4596 /*
4597 * Delete neighbor entry.
4598 */
4599 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4600 {
4601 zebra_neigh_t *tmp_n;
4602 struct host_rb_entry *hle;
4603
4604 while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
4605 hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
4606
4607 RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
4608 XFREE(MTYPE_HOST_PREFIX, hle);
4609 }
4610
4611 tmp_n = hash_release(zl3vni->nh_table, n);
4612 XFREE(MTYPE_NEIGH, tmp_n);
4613
4614 return 0;
4615 }
4616
4617 /*
4618 * Install remote nh as neigh into the kernel.
4619 */
4620 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4621 {
4622 #ifdef GNU_LINUX
4623 uint8_t flags;
4624 #endif
4625 int ret = 0;
4626
4627 if (!is_l3vni_oper_up(zl3vni))
4628 return -1;
4629
4630 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
4631 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
4632 return 0;
4633 #ifdef GNU_LINUX
4634 flags = NTF_EXT_LEARNED;
4635 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
4636 flags |= NTF_ROUTER;
4637 ret = kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac, flags);
4638 #endif
4639 return ret;
4640 }
4641
4642 /*
4643 * Uninstall remote nh from the kernel.
4644 */
4645 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
4646 {
4647 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
4648 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
4649 return 0;
4650
4651 if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
4652 return 0;
4653
4654 return kernel_del_neigh(zl3vni->svi_if, &n->ip);
4655 }
4656
4657 /* add remote vtep as a neigh entry */
4658 static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
4659 struct ethaddr *rmac,
4660 struct prefix *host_prefix)
4661 {
4662 char buf[ETHER_ADDR_STRLEN];
4663 char buf1[INET6_ADDRSTRLEN];
4664 zebra_neigh_t *nh = NULL;
4665
4666 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
4667 if (!nh) {
4668 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
4669 if (!nh) {
4670
4671 zlog_debug(
4672 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
4673 ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
4674 prefix_mac2str(rmac, buf, sizeof(buf)),
4675 zl3vni->vni);
4676 return -1;
4677 }
4678
4679 /* install the nh neigh in kernel */
4680 zl3vni_nh_install(zl3vni, nh);
4681 }
4682
4683 rb_find_or_add_host(&nh->host_rb, host_prefix);
4684
4685 return 0;
4686 }
4687
4688 /* handle nh neigh delete */
4689 static void zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *nh,
4690 struct prefix *host_prefix)
4691 {
4692 rb_delete_host(&nh->host_rb, host_prefix);
4693
4694 if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
4695 /* uninstall from kernel */
4696 zl3vni_nh_uninstall(zl3vni, nh);
4697
4698 /* delete the nh entry */
4699 zl3vni_nh_del(zl3vni, nh);
4700 }
4701 }
4702
4703 /* handle neigh update from kernel - the only thing of interest is to
4704 * readd stale entries.
4705 */
4706 static int zl3vni_local_nh_add_update(zebra_l3vni_t *zl3vni, struct ipaddr *ip,
4707 uint16_t state)
4708 {
4709 #ifdef GNU_LINUX
4710 zebra_neigh_t *n = NULL;
4711
4712 n = zl3vni_nh_lookup(zl3vni, ip);
4713 if (!n)
4714 return 0;
4715
4716 /* all next hop neigh are remote and installed by frr.
4717 * If the kernel has aged this entry, re-install.
4718 */
4719 if (state & NUD_STALE)
4720 zl3vni_nh_install(zl3vni, n);
4721 #endif
4722 return 0;
4723 }
4724
4725 /* handle neigh delete from kernel */
4726 static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
4727 {
4728 zebra_neigh_t *n = NULL;
4729
4730 n = zl3vni_nh_lookup(zl3vni, ip);
4731 if (!n)
4732 return 0;
4733
4734 /* all next hop neigh are remote and installed by frr.
4735 * If we get an age out notification for these neigh entries, we have to
4736 * install it back
4737 */
4738 zl3vni_nh_install(zl3vni, n);
4739
4740 return 0;
4741 }
4742
4743 /*
4744 * Hash function for L3 VNI.
4745 */
4746 static unsigned int l3vni_hash_keymake(const void *p)
4747 {
4748 const zebra_l3vni_t *zl3vni = p;
4749
4750 return jhash_1word(zl3vni->vni, 0);
4751 }
4752
4753 /*
4754 * Compare 2 L3 VNI hash entries.
4755 */
4756 static bool l3vni_hash_cmp(const void *p1, const void *p2)
4757 {
4758 const zebra_l3vni_t *zl3vni1 = p1;
4759 const zebra_l3vni_t *zl3vni2 = p2;
4760
4761 return (zl3vni1->vni == zl3vni2->vni);
4762 }
4763
4764 /*
4765 * Callback to allocate L3 VNI hash entry.
4766 */
4767 static void *zl3vni_alloc(void *p)
4768 {
4769 zebra_l3vni_t *zl3vni = NULL;
4770 const zebra_l3vni_t *tmp_l3vni = p;
4771
4772 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(zebra_l3vni_t));
4773 zl3vni->vni = tmp_l3vni->vni;
4774 return ((void *)zl3vni);
4775 }
4776
4777 /*
4778 * Look up L3 VNI hash entry.
4779 */
4780 static zebra_l3vni_t *zl3vni_lookup(vni_t vni)
4781 {
4782 zebra_l3vni_t tmp_l3vni;
4783 zebra_l3vni_t *zl3vni = NULL;
4784
4785 memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t));
4786 tmp_l3vni.vni = vni;
4787 zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
4788
4789 return zl3vni;
4790 }
4791
4792 /*
4793 * Add L3 VNI hash entry.
4794 */
4795 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
4796 {
4797 zebra_l3vni_t tmp_zl3vni;
4798 zebra_l3vni_t *zl3vni = NULL;
4799
4800 memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t));
4801 tmp_zl3vni.vni = vni;
4802
4803 zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
4804 assert(zl3vni);
4805
4806 zl3vni->vrf_id = vrf_id;
4807 zl3vni->svi_if = NULL;
4808 zl3vni->vxlan_if = NULL;
4809 zl3vni->l2vnis = list_new();
4810 zl3vni->l2vnis->cmp = vni_list_cmp;
4811
4812 /* Create hash table for remote RMAC */
4813 zl3vni->rmac_table = hash_create(mac_hash_keymake, mac_cmp,
4814 "Zebra L3-VNI RMAC-Table");
4815
4816 /* Create hash table for neighbors */
4817 zl3vni->nh_table = hash_create(neigh_hash_keymake, neigh_cmp,
4818 "Zebra L3-VNI next-hop table");
4819
4820 return zl3vni;
4821 }
4822
4823 /*
4824 * Delete L3 VNI hash entry.
4825 */
4826 static int zl3vni_del(zebra_l3vni_t *zl3vni)
4827 {
4828 zebra_l3vni_t *tmp_zl3vni;
4829
4830 /* free the list of l2vnis */
4831 list_delete(&zl3vni->l2vnis);
4832 zl3vni->l2vnis = NULL;
4833
4834 /* Free the rmac table */
4835 hash_free(zl3vni->rmac_table);
4836 zl3vni->rmac_table = NULL;
4837
4838 /* Free the nh table */
4839 hash_free(zl3vni->nh_table);
4840 zl3vni->nh_table = NULL;
4841
4842 /* Free the VNI hash entry and allocated memory. */
4843 tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
4844 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
4845
4846 return 0;
4847 }
4848
4849 struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
4850 {
4851 struct zebra_ns *zns = NULL;
4852 struct route_node *rn = NULL;
4853 struct interface *ifp = NULL;
4854
4855 /* loop through all vxlan-interface */
4856 zns = zebra_ns_lookup(NS_DEFAULT);
4857 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4858
4859 struct zebra_if *zif = NULL;
4860 struct zebra_l2info_vxlan *vxl = NULL;
4861
4862 ifp = (struct interface *)rn->info;
4863 if (!ifp)
4864 continue;
4865
4866 zif = ifp->info;
4867 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4868 continue;
4869
4870 vxl = &zif->l2info.vxl;
4871 if (vxl->vni == zl3vni->vni) {
4872 zl3vni->local_vtep_ip = vxl->vtep_ip;
4873 return ifp;
4874 }
4875 }
4876
4877 return NULL;
4878 }
4879
4880 struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
4881 {
4882 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
4883 struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
4884
4885 if (!zl3vni)
4886 return NULL;
4887
4888 if (!zl3vni->vxlan_if)
4889 return NULL;
4890
4891 zif = zl3vni->vxlan_if->info;
4892 if (!zif)
4893 return NULL;
4894
4895 vxl = &zif->l2info.vxl;
4896
4897 return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
4898 }
4899
4900 zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id)
4901 {
4902 struct zebra_vrf *zvrf = NULL;
4903
4904 zvrf = zebra_vrf_lookup_by_id(vrf_id);
4905 if (!zvrf)
4906 return NULL;
4907
4908 return zl3vni_lookup(zvrf->l3vni);
4909 }
4910
4911 /*
4912 * Map SVI and associated bridge to a VNI. This is invoked upon getting
4913 * neighbor notifications, to see if they are of interest.
4914 */
4915 static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp,
4916 struct interface *br_if)
4917 {
4918 int found = 0;
4919 vlanid_t vid = 0;
4920 uint8_t bridge_vlan_aware = 0;
4921 zebra_l3vni_t *zl3vni = NULL;
4922 struct zebra_ns *zns = NULL;
4923 struct route_node *rn = NULL;
4924 struct zebra_if *zif = NULL;
4925 struct interface *tmp_if = NULL;
4926 struct zebra_l2info_bridge *br = NULL;
4927 struct zebra_l2info_vxlan *vxl = NULL;
4928
4929 if (!br_if)
4930 return NULL;
4931
4932 /* Make sure the linked interface is a bridge. */
4933 if (!IS_ZEBRA_IF_BRIDGE(br_if))
4934 return NULL;
4935
4936 /* Determine if bridge is VLAN-aware or not */
4937 zif = br_if->info;
4938 assert(zif);
4939 br = &zif->l2info.br;
4940 bridge_vlan_aware = br->vlan_aware;
4941 if (bridge_vlan_aware) {
4942 struct zebra_l2info_vlan *vl;
4943
4944 if (!IS_ZEBRA_IF_VLAN(ifp))
4945 return NULL;
4946
4947 zif = ifp->info;
4948 assert(zif);
4949 vl = &zif->l2info.vl;
4950 vid = vl->vid;
4951 }
4952
4953 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
4954 /* TODO: Optimize with a hash. */
4955 zns = zebra_ns_lookup(NS_DEFAULT);
4956 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4957 tmp_if = (struct interface *)rn->info;
4958 if (!tmp_if)
4959 continue;
4960 zif = tmp_if->info;
4961 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4962 continue;
4963 if (!if_is_operative(tmp_if))
4964 continue;
4965 vxl = &zif->l2info.vxl;
4966
4967 if (zif->brslave_info.br_if != br_if)
4968 continue;
4969
4970 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
4971 found = 1;
4972 break;
4973 }
4974 }
4975
4976 if (!found)
4977 return NULL;
4978
4979 zl3vni = zl3vni_lookup(vxl->vni);
4980 return zl3vni;
4981 }
4982
4983 /*
4984 * Inform BGP about l3-vni.
4985 */
4986 static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
4987 {
4988 struct stream *s = NULL;
4989 struct zserv *client = NULL;
4990 struct ethaddr rmac;
4991 char buf[ETHER_ADDR_STRLEN];
4992
4993 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4994 /* BGP may not be running. */
4995 if (!client)
4996 return 0;
4997
4998 /* get the rmac */
4999 memset(&rmac, 0, sizeof(struct ethaddr));
5000 zl3vni_get_rmac(zl3vni, &rmac);
5001
5002 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5003
5004 zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
5005 stream_putl(s, zl3vni->vni);
5006 stream_put(s, &rmac, sizeof(struct ethaddr));
5007 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
5008 stream_put(s, &zl3vni->filter, sizeof(int));
5009 stream_putl(s, zl3vni->svi_if->ifindex);
5010
5011 /* Write packet size. */
5012 stream_putw_at(s, 0, stream_get_endp(s));
5013
5014 if (IS_ZEBRA_DEBUG_VXLAN)
5015 zlog_debug(
5016 "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s",
5017 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
5018 prefix_mac2str(&rmac, buf, sizeof(buf)),
5019 inet_ntoa(zl3vni->local_vtep_ip),
5020 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
5021 ? "prefix-routes-only"
5022 : "none",
5023 zebra_route_string(client->proto));
5024
5025 client->l3vniadd_cnt++;
5026 return zserv_send_message(client, s);
5027 }
5028
5029 /*
5030 * Inform BGP about local l3-VNI deletion.
5031 */
5032 static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
5033 {
5034 struct stream *s = NULL;
5035 struct zserv *client = NULL;
5036
5037 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
5038 /* BGP may not be running. */
5039 if (!client)
5040 return 0;
5041
5042 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5043
5044 zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
5045 stream_putl(s, zl3vni->vni);
5046
5047 /* Write packet size. */
5048 stream_putw_at(s, 0, stream_get_endp(s));
5049
5050 if (IS_ZEBRA_DEBUG_VXLAN)
5051 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
5052 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
5053 zebra_route_string(client->proto));
5054
5055 client->l3vnidel_cnt++;
5056 return zserv_send_message(client, s);
5057 }
5058
5059 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
5060 {
5061 if (!zl3vni)
5062 return;
5063
5064 /* send l3vni add to BGP */
5065 zl3vni_send_add_to_client(zl3vni);
5066 }
5067
5068 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
5069 {
5070 if (!zl3vni)
5071 return;
5072
5073 /* send l3-vni del to BGP*/
5074 zl3vni_send_del_to_client(zl3vni);
5075 }
5076
5077 static void zvni_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
5078 {
5079 zebra_vni_t *zvni = (zebra_vni_t *)bucket->data;
5080 zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)ctxt;
5081
5082 if (zvni->vrf_id == zl3vni_vrf_id(zl3vni))
5083 listnode_add_sort(zl3vni->l2vnis, zvni);
5084 }
5085
5086 /*
5087 * handle transition of vni from l2 to l3 and vice versa
5088 */
5089 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
5090 int add)
5091 {
5092 zebra_vni_t *zvni = NULL;
5093
5094 /* There is a possibility that VNI notification was already received
5095 * from kernel and we programmed it as L2-VNI
5096 * In such a case we need to delete this L2-VNI first, so
5097 * that it can be reprogrammed as L3-VNI in the system. It is also
5098 * possible that the vrf-vni mapping is removed from FRR while the vxlan
5099 * interface is still present in kernel. In this case to keep it
5100 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
5101 */
5102 if (add) {
5103 /* Locate hash entry */
5104 zvni = zvni_lookup(vni);
5105 if (!zvni)
5106 return 0;
5107
5108 if (IS_ZEBRA_DEBUG_VXLAN)
5109 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
5110
5111 /* Delete VNI from BGP. */
5112 zvni_send_del_to_client(zvni->vni);
5113
5114 /* Free up all neighbors and MAC, if any. */
5115 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
5116 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
5117
5118 /* Free up all remote VTEPs, if any. */
5119 zvni_vtep_del_all(zvni, 0);
5120
5121 /* Delete the hash entry. */
5122 if (zvni_del(zvni)) {
5123 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
5124 "Failed to del VNI hash %p, VNI %u", zvni,
5125 zvni->vni);
5126 return -1;
5127 }
5128 } else {
5129 /* TODO_MITESH: This needs to be thought through. We don't have
5130 * enough information at this point to reprogram the vni as
5131 * l2-vni. One way is to store the required info in l3-vni and
5132 * used it solely for this purpose
5133 */
5134 }
5135
5136 return 0;
5137 }
5138
5139 /* delete and uninstall rmac hash entry */
5140 static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx)
5141 {
5142 zebra_mac_t *zrmac = NULL;
5143 zebra_l3vni_t *zl3vni = NULL;
5144
5145 zrmac = (zebra_mac_t *)bucket->data;
5146 zl3vni = (zebra_l3vni_t *)ctx;
5147 zl3vni_rmac_uninstall(zl3vni, zrmac);
5148
5149 /* Send RMAC for FPM processing */
5150 hook_call(zebra_rmac_update, zrmac, zl3vni, true, "RMAC deleted");
5151
5152 zl3vni_rmac_del(zl3vni, zrmac);
5153 }
5154
5155 /* delete and uninstall nh hash entry */
5156 static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx)
5157 {
5158 zebra_neigh_t *n = NULL;
5159 zebra_l3vni_t *zl3vni = NULL;
5160
5161 n = (zebra_neigh_t *)bucket->data;
5162 zl3vni = (zebra_l3vni_t *)ctx;
5163 zl3vni_nh_uninstall(zl3vni, n);
5164 zl3vni_nh_del(zl3vni, n);
5165 }
5166
5167 static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
5168 uint16_t cmd)
5169 {
5170 struct zserv *client = NULL;
5171 struct stream *s = NULL;
5172 char buf[PREFIX_STRLEN];
5173
5174 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
5175 /* BGP may not be running. */
5176 if (!client)
5177 return 0;
5178
5179 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5180
5181 zclient_create_header(s, cmd, vrf_id);
5182 stream_put(s, p, sizeof(struct prefix));
5183
5184 /* Write packet size. */
5185 stream_putw_at(s, 0, stream_get_endp(s));
5186
5187 if (IS_ZEBRA_DEBUG_VXLAN)
5188 zlog_debug("Send ip prefix %s %s on vrf %s",
5189 prefix2str(p, buf, sizeof(buf)),
5190 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
5191 vrf_id_to_name(vrf_id));
5192
5193 if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
5194 client->prefixadd_cnt++;
5195 else
5196 client->prefixdel_cnt++;
5197
5198 return zserv_send_message(client, s);
5199 }
5200
5201 /* re-add remote rmac if needed */
5202 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
5203 struct ethaddr *rmac)
5204 {
5205 char buf[ETHER_ADDR_STRLEN];
5206 zebra_mac_t *zrmac = NULL;
5207
5208 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
5209 if (!zrmac)
5210 return 0;
5211
5212 if (IS_ZEBRA_DEBUG_VXLAN)
5213 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
5214 prefix_mac2str(rmac, buf, sizeof(buf)), zl3vni->vni);
5215
5216 zl3vni_rmac_install(zl3vni, zrmac);
5217 return 0;
5218 }
5219
5220 /* Process a remote MACIP add from BGP. */
5221 static void process_remote_macip_add(vni_t vni,
5222 struct ethaddr *macaddr,
5223 uint16_t ipa_len,
5224 struct ipaddr *ipaddr,
5225 uint8_t flags,
5226 uint32_t seq,
5227 struct in_addr vtep_ip)
5228 {
5229 zebra_vni_t *zvni;
5230 zebra_vtep_t *zvtep;
5231 zebra_mac_t *mac = NULL, *old_mac = NULL;
5232 zebra_neigh_t *n = NULL;
5233 int update_mac = 0, update_neigh = 0;
5234 char buf[ETHER_ADDR_STRLEN];
5235 char buf1[INET6_ADDRSTRLEN];
5236 struct interface *ifp = NULL;
5237 struct zebra_if *zif = NULL;
5238 struct zebra_vrf *zvrf;
5239 uint32_t tmp_seq;
5240 bool sticky;
5241 bool remote_gw;
5242 bool is_router;
5243 bool do_dad = false;
5244 bool is_dup_detect = false;
5245
5246 /* Locate VNI hash entry - expected to exist. */
5247 zvni = zvni_lookup(vni);
5248 if (!zvni) {
5249 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni);
5250 return;
5251 }
5252
5253 ifp = zvni->vxlan_if;
5254 if (ifp)
5255 zif = ifp->info;
5256 if (!ifp ||
5257 !if_is_operative(ifp) ||
5258 !zif ||
5259 !zif->brslave_info.br_if) {
5260 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
5261 vni);
5262 return;
5263 }
5264
5265 /* The remote VTEP specified should normally exist, but it is
5266 * possible that when peering comes up, peer may advertise MACIP
5267 * routes before advertising type-3 routes.
5268 */
5269 zvtep = zvni_vtep_find(zvni, &vtep_ip);
5270 if (!zvtep) {
5271 zvtep = zvni_vtep_add(zvni, &vtep_ip, VXLAN_FLOOD_DISABLED);
5272 if (!zvtep) {
5273 flog_err(
5274 EC_ZEBRA_VTEP_ADD_FAILED,
5275 "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
5276 vni, zvni);
5277 return;
5278 }
5279
5280 zvni_vtep_install(zvni, zvtep);
5281 }
5282
5283 sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
5284 remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
5285 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
5286
5287 mac = zvni_mac_lookup(zvni, macaddr);
5288
5289 /* Ignore if the mac is already present as a gateway mac */
5290 if (mac &&
5291 CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
5292 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
5293 if (IS_ZEBRA_DEBUG_VXLAN)
5294 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
5295 vni,
5296 prefix_mac2str(macaddr, buf, sizeof(buf)),
5297 ipa_len ? " IP " : "",
5298 ipa_len ?
5299 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
5300 return;
5301 }
5302
5303 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
5304 if (!zvrf)
5305 return;
5306
5307 /* check if the remote MAC is unknown or has a change.
5308 * If so, that needs to be updated first. Note that client could
5309 * install MAC and MACIP separately or just install the latter.
5310 */
5311 if (!mac
5312 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
5313 || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
5314 || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
5315 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
5316 || seq != mac->rem_seq)
5317 update_mac = 1;
5318
5319 if (update_mac) {
5320 if (!mac) {
5321 mac = zvni_mac_add(zvni, macaddr);
5322 if (!mac) {
5323 zlog_warn(
5324 "Failed to add MAC %s VNI %u Remote VTEP %s",
5325 prefix_mac2str(macaddr, buf,
5326 sizeof(buf)),
5327 vni, inet_ntoa(vtep_ip));
5328 return;
5329 }
5330
5331 /* Is this MAC created for a MACIP? */
5332 if (ipa_len)
5333 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5334 } else {
5335 const char *mac_type;
5336
5337 /* When host moves but changes its (MAC,IP)
5338 * binding, BGP may install a MACIP entry that
5339 * corresponds to "older" location of the host
5340 * in transient situations (because {IP1,M1}
5341 * is a different route from {IP1,M2}). Check
5342 * the sequence number and ignore this update
5343 * if appropriate.
5344 */
5345 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
5346 tmp_seq = mac->loc_seq;
5347 mac_type = "local";
5348 } else {
5349 tmp_seq = mac->rem_seq;
5350 mac_type = "remote";
5351 }
5352 if (seq < tmp_seq) {
5353 if (IS_ZEBRA_DEBUG_VXLAN)
5354 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
5355 vni,
5356 prefix_mac2str(macaddr,
5357 buf, sizeof(buf)),
5358 ipa_len ? " IP " : "",
5359 ipa_len ?
5360 ipaddr2str(ipaddr,
5361 buf1, sizeof(buf1)) : "",
5362 mac_type,
5363 tmp_seq);
5364 return;
5365 }
5366 }
5367
5368 /* Check MAC's curent state is local (this is the case
5369 * where MAC has moved from L->R) and check previous
5370 * detection started via local learning.
5371 * RFC-7432: A PE/VTEP that detects a MAC mobility
5372 * event via local learning starts an M-second timer.
5373 *
5374 * VTEP-IP or seq. change alone is not considered
5375 * for dup. detection.
5376 *
5377 * MAC is already marked duplicate set dad, then
5378 * is_dup_detect will be set to not install the entry.
5379 */
5380 if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
5381 mac->dad_count) ||
5382 CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
5383 do_dad = true;
5384
5385 /* Remove local MAC from BGP. */
5386 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5387 zvni_mac_send_del_to_client(zvni->vni, macaddr);
5388
5389 /* Set "auto" and "remote" forwarding info. */
5390 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5391 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5392 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5393 mac->fwd_info.r_vtep_ip = vtep_ip;
5394
5395 if (sticky)
5396 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5397 else
5398 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5399
5400 if (remote_gw)
5401 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
5402 else
5403 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
5404
5405 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac,
5406 mac->fwd_info.r_vtep_ip,
5407 do_dad, &is_dup_detect,
5408 false);
5409
5410 if (!is_dup_detect) {
5411 zvni_process_neigh_on_remote_mac_add(zvni, mac);
5412 /* Install the entry. */
5413 zvni_mac_install(zvni, mac);
5414 }
5415 }
5416
5417 /* Update seq number. */
5418 mac->rem_seq = seq;
5419
5420 /* If there is no IP, return after clearing AUTO flag of MAC. */
5421 if (!ipa_len) {
5422 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5423 return;
5424 }
5425
5426 /* Reset flag */
5427 do_dad = false;
5428
5429 /* Check if the remote neighbor itself is unknown or has a
5430 * change. If so, create or update and then install the entry.
5431 */
5432 n = zvni_neigh_lookup(zvni, ipaddr);
5433 if (!n
5434 || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5435 || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
5436 || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0)
5437 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)
5438 || seq != n->rem_seq)
5439 update_neigh = 1;
5440
5441 if (update_neigh) {
5442 if (!n) {
5443 n = zvni_neigh_add(zvni, ipaddr, macaddr);
5444 if (!n) {
5445 zlog_warn(
5446 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5447 ipaddr2str(ipaddr, buf1,
5448 sizeof(buf1)),
5449 prefix_mac2str(macaddr, buf,
5450 sizeof(buf)),
5451 vni, inet_ntoa(vtep_ip));
5452 return;
5453 }
5454
5455 } else {
5456 const char *n_type;
5457
5458 /* When host moves but changes its (MAC,IP)
5459 * binding, BGP may install a MACIP entry that
5460 * corresponds to "older" location of the host
5461 * in transient situations (because {IP1,M1}
5462 * is a different route from {IP1,M2}). Check
5463 * the sequence number and ignore this update
5464 * if appropriate.
5465 */
5466 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
5467 tmp_seq = n->loc_seq;
5468 n_type = "local";
5469 } else {
5470 tmp_seq = n->rem_seq;
5471 n_type = "remote";
5472 }
5473 if (seq < tmp_seq) {
5474 if (IS_ZEBRA_DEBUG_VXLAN)
5475 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
5476 vni,
5477 prefix_mac2str(macaddr,
5478 buf, sizeof(buf)),
5479 " IP ",
5480 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
5481 n_type,
5482 tmp_seq);
5483 return;
5484 }
5485 if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) {
5486 /* MAC change, send a delete for old
5487 * neigh if learnt locally.
5488 */
5489 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) &&
5490 IS_ZEBRA_NEIGH_ACTIVE(n))
5491 zvni_neigh_send_del_to_client(
5492 zvni->vni, &n->ip,
5493 &n->emac, 0, n->state);
5494
5495 /* update neigh list for macs */
5496 old_mac = zvni_mac_lookup(zvni, &n->emac);
5497 if (old_mac) {
5498 listnode_delete(old_mac->neigh_list, n);
5499 zvni_deref_ip2mac(zvni, old_mac);
5500 }
5501 listnode_add_sort(mac->neigh_list, n);
5502 memcpy(&n->emac, macaddr, ETH_ALEN);
5503
5504 /* Check Neigh's curent state is local
5505 * (this is the case where neigh/host has moved
5506 * from L->R) and check previous detction
5507 * started via local learning.
5508 *
5509 * RFC-7432: A PE/VTEP that detects a MAC
5510 * mobilit event via local learning starts
5511 * an M-second timer.
5512 * VTEP-IP or seq. change along is not
5513 * considered for dup. detection.
5514 *
5515 * Mobilty event scenario-B IP-MAC binding
5516 * changed.
5517 */
5518 if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
5519 && n->dad_count)
5520 do_dad = true;
5521
5522 }
5523 }
5524
5525 /* Set "remote" forwarding info. */
5526 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
5527 n->r_vtep_ip = vtep_ip;
5528 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
5529
5530 /* Set router flag (R-bit) to this Neighbor entry */
5531 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
5532 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
5533 else
5534 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
5535
5536 /* Check old or new MAC detected as duplicate,
5537 * inherit duplicate flag to this neigh.
5538 */
5539 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_mac,
5540 mac, n)) {
5541 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
5542 "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
5543 zvni->vni,
5544 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
5545 ipaddr2str(&n->ip, buf1, sizeof(buf1)));
5546 }
5547
5548 /* Check duplicate address detection for IP */
5549 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n,
5550 n->r_vtep_ip,
5551 do_dad,
5552 &is_dup_detect,
5553 false);
5554 /* Install the entry. */
5555 if (!is_dup_detect)
5556 zvni_neigh_install(zvni, n);
5557 }
5558
5559 zvni_probe_neigh_on_mac_add(zvni, mac);
5560
5561 /* Update seq number. */
5562 n->rem_seq = seq;
5563 }
5564
5565 /* Process a remote MACIP delete from BGP. */
5566 static void process_remote_macip_del(vni_t vni,
5567 struct ethaddr *macaddr,
5568 uint16_t ipa_len,
5569 struct ipaddr *ipaddr,
5570 struct in_addr vtep_ip)
5571 {
5572 zebra_vni_t *zvni;
5573 zebra_mac_t *mac = NULL;
5574 zebra_neigh_t *n = NULL;
5575 struct interface *ifp = NULL;
5576 struct zebra_if *zif = NULL;
5577 struct zebra_ns *zns;
5578 struct zebra_l2info_vxlan *vxl;
5579 struct zebra_vrf *zvrf;
5580 char buf[ETHER_ADDR_STRLEN];
5581 char buf1[INET6_ADDRSTRLEN];
5582
5583 /* Locate VNI hash entry - expected to exist. */
5584 zvni = zvni_lookup(vni);
5585 if (!zvni) {
5586 if (IS_ZEBRA_DEBUG_VXLAN)
5587 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
5588 return;
5589 }
5590
5591 ifp = zvni->vxlan_if;
5592 if (ifp)
5593 zif = ifp->info;
5594 if (!ifp ||
5595 !if_is_operative(ifp) ||
5596 !zif ||
5597 !zif->brslave_info.br_if) {
5598 if (IS_ZEBRA_DEBUG_VXLAN)
5599 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
5600 vni);
5601 return;
5602 }
5603 zns = zebra_ns_lookup(NS_DEFAULT);
5604 vxl = &zif->l2info.vxl;
5605
5606 /* The remote VTEP specified is normally expected to exist, but
5607 * it is possible that the peer may delete the VTEP before deleting
5608 * any MACs referring to the VTEP, in which case the handler (see
5609 * remote_vtep_del) would have already deleted the MACs.
5610 */
5611 if (!zvni_vtep_find(zvni, &vtep_ip))
5612 return;
5613
5614 mac = zvni_mac_lookup(zvni, macaddr);
5615 if (ipa_len)
5616 n = zvni_neigh_lookup(zvni, ipaddr);
5617
5618 if (n && !mac) {
5619 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
5620 prefix_mac2str(macaddr, buf, sizeof(buf)),
5621 ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni);
5622 return;
5623 }
5624
5625 /* If the remote mac or neighbor doesn't exist there is nothing
5626 * more to do. Otherwise, uninstall the entry and then remove it.
5627 */
5628 if (!mac && !n)
5629 return;
5630
5631 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
5632
5633 /* Ignore the delete if this mac is a gateway mac-ip */
5634 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
5635 && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
5636 zlog_warn(
5637 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
5638 vni,
5639 prefix_mac2str(macaddr, buf, sizeof(buf)),
5640 ipa_len ? " IP " : "",
5641 ipa_len ?
5642 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
5643 return;
5644 }
5645
5646 /* Uninstall remote neighbor or MAC. */
5647 if (n) {
5648 if (zvrf->dad_freeze &&
5649 CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE) &&
5650 CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) &&
5651 (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) {
5652 struct interface *vlan_if;
5653
5654 vlan_if = zvni_map_to_svi(vxl->access_vlan,
5655 zif->brslave_info.br_if);
5656 if (IS_ZEBRA_DEBUG_VXLAN)
5657 zlog_debug("%s: IP %s (flags 0x%x intf %s) is remote and duplicate, read kernel for local entry",
5658 __PRETTY_FUNCTION__,
5659 ipaddr2str(ipaddr, buf1,
5660 sizeof(buf1)), n->flags,
5661 vlan_if->name);
5662 neigh_read_specific_ip(ipaddr, vlan_if);
5663 }
5664
5665 /* When the MAC changes for an IP, it is possible the
5666 * client may update the new MAC before trying to delete the
5667 * "old" neighbor (as these are two different MACIP routes).
5668 * Do the delete only if the MAC matches.
5669 */
5670 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5671 && (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) {
5672 zvni_neigh_uninstall(zvni, n);
5673 zvni_neigh_del(zvni, n);
5674 zvni_deref_ip2mac(zvni, mac);
5675 }
5676 } else {
5677 /* DAD: when MAC is freeze state as remote learn event,
5678 * remote mac-ip delete event is received will result in freeze
5679 * entry removal, first fetch kernel for the same entry present
5680 * as LOCAL and reachable, avoid deleting this entry instead
5681 * use kerenel local entry to update during unfreeze time.
5682 */
5683 if (zvrf->dad_freeze &&
5684 CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE) &&
5685 CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5686 if (IS_ZEBRA_DEBUG_VXLAN)
5687 zlog_debug("%s: MAC %s (flags 0x%x) is remote and duplicate, read kernel for local entry",
5688 __PRETTY_FUNCTION__,
5689 prefix_mac2str(macaddr, buf,
5690 sizeof(buf)),
5691 mac->flags);
5692 macfdb_read_specific_mac(zns, zif->brslave_info.br_if,
5693 macaddr, vxl->access_vlan);
5694 }
5695
5696 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5697 zvni_process_neigh_on_remote_mac_del(zvni, mac);
5698 /*
5699 * the remote sequence number in the auto mac entry
5700 * needs to be reset to 0 as the mac entry may have
5701 * been removed on all VTEPs (including
5702 * the originating one)
5703 */
5704 mac->rem_seq = 0;
5705
5706 /* If all remote neighbors referencing a remote MAC
5707 * go away, we need to uninstall the MAC.
5708 */
5709 if (remote_neigh_count(mac) == 0) {
5710 zvni_mac_uninstall(zvni, mac);
5711 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5712 }
5713 if (list_isempty(mac->neigh_list))
5714 zvni_mac_del(zvni, mac);
5715 else
5716 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5717 }
5718 }
5719 }
5720
5721
5722 /* Public functions */
5723
5724 int is_l3vni_for_prefix_routes_only(vni_t vni)
5725 {
5726 zebra_l3vni_t *zl3vni = NULL;
5727
5728 zl3vni = zl3vni_lookup(vni);
5729 if (!zl3vni)
5730 return 0;
5731
5732 return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
5733 }
5734
5735 /* handle evpn route in vrf table */
5736 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
5737 struct ipaddr *vtep_ip,
5738 struct prefix *host_prefix)
5739 {
5740 zebra_l3vni_t *zl3vni = NULL;
5741 struct ipaddr ipv4_vtep;
5742
5743 zl3vni = zl3vni_from_vrf(vrf_id);
5744 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
5745 return;
5746
5747 /*
5748 * add the next hop neighbor -
5749 * neigh to be installed is the ipv6 nexthop neigh
5750 */
5751 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
5752
5753 /*
5754 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
5755 * address. Rmac is programmed against the ipv4 vtep because we only
5756 * support ipv4 tunnels in the h/w right now
5757 */
5758 memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
5759 ipv4_vtep.ipa_type = IPADDR_V4;
5760 if (vtep_ip->ipa_type == IPADDR_V6)
5761 ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
5762 &(ipv4_vtep.ipaddr_v4));
5763 else
5764 memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
5765 sizeof(struct in_addr));
5766
5767 /*
5768 * add the rmac - remote rmac to be installed is against the ipv4
5769 * nexthop address
5770 */
5771 zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
5772 }
5773
5774 /* handle evpn vrf route delete */
5775 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
5776 struct ipaddr *vtep_ip,
5777 struct prefix *host_prefix)
5778 {
5779 zebra_l3vni_t *zl3vni = NULL;
5780 zebra_neigh_t *nh = NULL;
5781 zebra_mac_t *zrmac = NULL;
5782
5783 zl3vni = zl3vni_from_vrf(vrf_id);
5784 if (!zl3vni)
5785 return;
5786
5787 /* find the next hop entry and rmac entry */
5788 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
5789 if (!nh)
5790 return;
5791 zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
5792
5793 /* delete the next hop entry */
5794 zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
5795
5796 /* delete the rmac entry */
5797 if (zrmac)
5798 zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix);
5799
5800 }
5801
5802 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
5803 struct ethaddr *rmac, bool use_json)
5804 {
5805 zebra_l3vni_t *zl3vni = NULL;
5806 zebra_mac_t *zrmac = NULL;
5807 json_object *json = NULL;
5808
5809 if (!is_evpn_enabled()) {
5810 if (use_json)
5811 vty_out(vty, "{}\n");
5812 return;
5813 }
5814
5815 if (use_json)
5816 json = json_object_new_object();
5817
5818 zl3vni = zl3vni_lookup(l3vni);
5819 if (!zl3vni) {
5820 if (use_json)
5821 vty_out(vty, "{}\n");
5822 else
5823 vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
5824 return;
5825 }
5826
5827 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
5828 if (!zrmac) {
5829 if (use_json)
5830 vty_out(vty, "{}\n");
5831 else
5832 vty_out(vty,
5833 "%% Requested RMAC doesn't exist in L3-VNI %u",
5834 l3vni);
5835 return;
5836 }
5837
5838 zl3vni_print_rmac(zrmac, vty, json);
5839
5840 if (use_json) {
5841 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5842 json, JSON_C_TO_STRING_PRETTY));
5843 json_object_free(json);
5844 }
5845 }
5846
5847 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
5848 {
5849 zebra_l3vni_t *zl3vni;
5850 uint32_t num_rmacs;
5851 struct rmac_walk_ctx wctx;
5852 json_object *json = NULL;
5853
5854 if (!is_evpn_enabled())
5855 return;
5856
5857 zl3vni = zl3vni_lookup(l3vni);
5858 if (!zl3vni) {
5859 if (use_json)
5860 vty_out(vty, "{}\n");
5861 else
5862 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5863 return;
5864 }
5865 num_rmacs = hashcount(zl3vni->rmac_table);
5866 if (!num_rmacs)
5867 return;
5868
5869 if (use_json)
5870 json = json_object_new_object();
5871
5872 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
5873 wctx.vty = vty;
5874 wctx.json = json;
5875 if (!use_json) {
5876 vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
5877 num_rmacs);
5878 vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
5879 } else
5880 json_object_int_add(json, "numRmacs", num_rmacs);
5881
5882 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
5883
5884 if (use_json) {
5885 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5886 json, JSON_C_TO_STRING_PRETTY));
5887 json_object_free(json);
5888 }
5889 }
5890
5891 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
5892 {
5893 json_object *json = NULL;
5894 void *args[2];
5895
5896 if (!is_evpn_enabled()) {
5897 if (use_json)
5898 vty_out(vty, "{}\n");
5899 return;
5900 }
5901
5902 if (use_json)
5903 json = json_object_new_object();
5904
5905 args[0] = vty;
5906 args[1] = json;
5907 hash_iterate(zrouter.l3vni_table,
5908 (void (*)(struct hash_bucket *,
5909 void *))zl3vni_print_rmac_hash_all_vni,
5910 args);
5911
5912 if (use_json) {
5913 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5914 json, JSON_C_TO_STRING_PRETTY));
5915 json_object_free(json);
5916 }
5917 }
5918
5919 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
5920 struct ipaddr *ip, bool use_json)
5921 {
5922 zebra_l3vni_t *zl3vni = NULL;
5923 zebra_neigh_t *n = NULL;
5924 json_object *json = NULL;
5925
5926 if (!is_evpn_enabled()) {
5927 if (use_json)
5928 vty_out(vty, "{}\n");
5929 return;
5930 }
5931
5932 if (use_json)
5933 json = json_object_new_object();
5934
5935 zl3vni = zl3vni_lookup(l3vni);
5936 if (!zl3vni) {
5937 if (use_json)
5938 vty_out(vty, "{}\n");
5939 else
5940 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5941 return;
5942 }
5943
5944 n = zl3vni_nh_lookup(zl3vni, ip);
5945 if (!n) {
5946 if (use_json)
5947 vty_out(vty, "{}\n");
5948 else
5949 vty_out(vty,
5950 "%% Requested next-hop not present for L3-VNI %u",
5951 l3vni);
5952 return;
5953 }
5954
5955 zl3vni_print_nh(n, vty, json);
5956
5957 if (use_json) {
5958 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5959 json, JSON_C_TO_STRING_PRETTY));
5960 json_object_free(json);
5961 }
5962 }
5963
5964 void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
5965 {
5966 uint32_t num_nh;
5967 struct nh_walk_ctx wctx;
5968 json_object *json = NULL;
5969 zebra_l3vni_t *zl3vni = NULL;
5970
5971 if (!is_evpn_enabled())
5972 return;
5973
5974 zl3vni = zl3vni_lookup(l3vni);
5975 if (!zl3vni) {
5976 if (use_json)
5977 vty_out(vty, "{}\n");
5978 else
5979 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
5980 return;
5981 }
5982
5983 num_nh = hashcount(zl3vni->nh_table);
5984 if (!num_nh)
5985 return;
5986
5987 if (use_json)
5988 json = json_object_new_object();
5989
5990 wctx.vty = vty;
5991 wctx.json = json;
5992 if (!use_json) {
5993 vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
5994 num_nh);
5995 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
5996 } else
5997 json_object_int_add(json, "numNextHops", num_nh);
5998
5999 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
6000
6001 if (use_json) {
6002 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6003 json, JSON_C_TO_STRING_PRETTY));
6004 json_object_free(json);
6005 }
6006 }
6007
6008 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
6009 {
6010 json_object *json = NULL;
6011 void *args[2];
6012
6013 if (!is_evpn_enabled()) {
6014 if (use_json)
6015 vty_out(vty, "{}\n");
6016 return;
6017 }
6018
6019 if (use_json)
6020 json = json_object_new_object();
6021
6022 args[0] = vty;
6023 args[1] = json;
6024 hash_iterate(zrouter.l3vni_table,
6025 (void (*)(struct hash_bucket *,
6026 void *))zl3vni_print_nh_hash_all_vni,
6027 args);
6028
6029 if (use_json) {
6030 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6031 json, JSON_C_TO_STRING_PRETTY));
6032 json_object_free(json);
6033 }
6034 }
6035
6036 /*
6037 * Display L3 VNI information (VTY command handler).
6038 */
6039 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
6040 {
6041 void *args[2];
6042 json_object *json = NULL;
6043 zebra_l3vni_t *zl3vni = NULL;
6044
6045 if (!is_evpn_enabled()) {
6046 if (use_json)
6047 vty_out(vty, "{}\n");
6048 return;
6049 }
6050
6051 zl3vni = zl3vni_lookup(vni);
6052 if (!zl3vni) {
6053 if (use_json)
6054 vty_out(vty, "{}\n");
6055 else
6056 vty_out(vty, "%% VNI %u does not exist\n", vni);
6057 return;
6058 }
6059
6060 if (use_json)
6061 json = json_object_new_object();
6062
6063 args[0] = vty;
6064 args[1] = json;
6065 zl3vni_print(zl3vni, (void *)args);
6066
6067 if (use_json) {
6068 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6069 json, JSON_C_TO_STRING_PRETTY));
6070 json_object_free(json);
6071 }
6072 }
6073
6074 void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
6075 json_object *json_vrfs)
6076 {
6077 char buf[ETHER_ADDR_STRLEN];
6078 zebra_l3vni_t *zl3vni = NULL;
6079
6080 zl3vni = zl3vni_lookup(zvrf->l3vni);
6081 if (!zl3vni)
6082 return;
6083
6084 if (!json_vrfs) {
6085 vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
6086 zvrf_name(zvrf), zl3vni->vni,
6087 zl3vni_vxlan_if_name(zl3vni),
6088 zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
6089 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
6090 } else {
6091 json_object *json_vrf = NULL;
6092
6093 json_vrf = json_object_new_object();
6094 json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
6095 json_object_int_add(json_vrf, "vni", zl3vni->vni);
6096 json_object_string_add(json_vrf, "vxlanIntf",
6097 zl3vni_vxlan_if_name(zl3vni));
6098 json_object_string_add(json_vrf, "sviIntf",
6099 zl3vni_svi_if_name(zl3vni));
6100 json_object_string_add(json_vrf, "state",
6101 zl3vni_state2str(zl3vni));
6102 json_object_string_add(
6103 json_vrf, "routerMac",
6104 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
6105 json_object_array_add(json_vrfs, json_vrf);
6106 }
6107 }
6108
6109 /*
6110 * Display Neighbors for a VNI (VTY command handler).
6111 */
6112 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
6113 vni_t vni, bool use_json)
6114 {
6115 zebra_vni_t *zvni;
6116 uint32_t num_neigh;
6117 struct neigh_walk_ctx wctx;
6118 json_object *json = NULL;
6119
6120 if (!is_evpn_enabled())
6121 return;
6122 zvni = zvni_lookup(vni);
6123 if (!zvni) {
6124 if (use_json)
6125 vty_out(vty, "{}\n");
6126 else
6127 vty_out(vty, "%% VNI %u does not exist\n", vni);
6128 return;
6129 }
6130 num_neigh = hashcount(zvni->neigh_table);
6131 if (!num_neigh)
6132 return;
6133
6134 if (use_json)
6135 json = json_object_new_object();
6136
6137 /* Since we have IPv6 addresses to deal with which can vary widely in
6138 * size, we try to be a bit more elegant in display by first computing
6139 * the maximum width.
6140 */
6141 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
6142 wctx.zvni = zvni;
6143 wctx.vty = vty;
6144 wctx.addr_width = 15;
6145 wctx.json = json;
6146 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
6147
6148 if (!use_json) {
6149 vty_out(vty,
6150 "Number of ARPs (local and remote) known for this VNI: %u\n",
6151 num_neigh);
6152 vty_out(vty, "%*s %-6s %-8s %-17s %-21s %s\n", -wctx.addr_width,
6153 "IP", "Type", "State", "MAC", "Remote VTEP", "Seq #'s");
6154 } else
6155 json_object_int_add(json, "numArpNd", num_neigh);
6156
6157 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
6158 if (use_json) {
6159 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6160 json, JSON_C_TO_STRING_PRETTY));
6161 json_object_free(json);
6162 }
6163 }
6164
6165 /*
6166 * Display neighbors across all VNIs (VTY command handler).
6167 */
6168 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
6169 bool print_dup, bool use_json)
6170 {
6171 json_object *json = NULL;
6172 void *args[3];
6173
6174 if (!is_evpn_enabled())
6175 return;
6176
6177 if (use_json)
6178 json = json_object_new_object();
6179
6180 args[0] = vty;
6181 args[1] = json;
6182 args[2] = (void *)(ptrdiff_t)print_dup;
6183
6184 hash_iterate(zvrf->vni_table,
6185 (void (*)(struct hash_bucket *,
6186 void *))zvni_print_neigh_hash_all_vni,
6187 args);
6188 if (use_json) {
6189 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6190 json, JSON_C_TO_STRING_PRETTY));
6191 json_object_free(json);
6192 }
6193 }
6194
6195 /*
6196 * Display neighbors across all VNIs in detail(VTY command handler).
6197 */
6198 void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
6199 struct zebra_vrf *zvrf,
6200 bool print_dup, bool use_json)
6201 {
6202 json_object *json = NULL;
6203 void *args[3];
6204
6205 if (!is_evpn_enabled())
6206 return;
6207
6208 if (use_json)
6209 json = json_object_new_object();
6210
6211 args[0] = vty;
6212 args[1] = json;
6213 args[2] = (void *)(ptrdiff_t)print_dup;
6214
6215 hash_iterate(zvrf->vni_table,
6216 (void (*)(struct hash_bucket *,
6217 void *))zvni_print_neigh_hash_all_vni_detail,
6218 args);
6219 if (use_json) {
6220 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6221 json, JSON_C_TO_STRING_PRETTY));
6222 json_object_free(json);
6223 }
6224 }
6225
6226 /*
6227 * Display specific neighbor for a VNI, if present (VTY command handler).
6228 */
6229 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
6230 struct zebra_vrf *zvrf, vni_t vni,
6231 struct ipaddr *ip, bool use_json)
6232 {
6233 zebra_vni_t *zvni;
6234 zebra_neigh_t *n;
6235 json_object *json = NULL;
6236
6237 if (!is_evpn_enabled())
6238 return;
6239 zvni = zvni_lookup(vni);
6240 if (!zvni) {
6241 if (use_json)
6242 vty_out(vty, "{}\n");
6243 else
6244 vty_out(vty, "%% VNI %u does not exist\n", vni);
6245 return;
6246 }
6247 n = zvni_neigh_lookup(zvni, ip);
6248 if (!n) {
6249 if (!use_json)
6250 vty_out(vty,
6251 "%% Requested neighbor does not exist in VNI %u\n",
6252 vni);
6253 return;
6254 }
6255 if (use_json)
6256 json = json_object_new_object();
6257
6258 zvni_print_neigh(n, vty, json);
6259
6260 if (use_json) {
6261 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6262 json, JSON_C_TO_STRING_PRETTY));
6263 json_object_free(json);
6264 }
6265 }
6266
6267 /*
6268 * Display neighbors for a VNI from specific VTEP (VTY command handler).
6269 * By definition, these are remote neighbors.
6270 */
6271 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
6272 vni_t vni, struct in_addr vtep_ip,
6273 bool use_json)
6274 {
6275 zebra_vni_t *zvni;
6276 uint32_t num_neigh;
6277 struct neigh_walk_ctx wctx;
6278 json_object *json = NULL;
6279
6280 if (!is_evpn_enabled())
6281 return;
6282 zvni = zvni_lookup(vni);
6283 if (!zvni) {
6284 if (use_json)
6285 vty_out(vty, "{}\n");
6286 else
6287 vty_out(vty, "%% VNI %u does not exist\n", vni);
6288 return;
6289 }
6290 num_neigh = hashcount(zvni->neigh_table);
6291 if (!num_neigh)
6292 return;
6293
6294 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
6295 wctx.zvni = zvni;
6296 wctx.vty = vty;
6297 wctx.addr_width = 15;
6298 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
6299 wctx.r_vtep_ip = vtep_ip;
6300 wctx.json = json;
6301 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
6302 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
6303
6304 if (use_json) {
6305 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6306 json, JSON_C_TO_STRING_PRETTY));
6307 json_object_free(json);
6308 }
6309 }
6310
6311 /*
6312 * Display Duplicate detected Neighbors for a VNI
6313 * (VTY command handler).
6314 */
6315 void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
6316 struct zebra_vrf *zvrf,
6317 vni_t vni,
6318 bool use_json)
6319 {
6320 zebra_vni_t *zvni;
6321 uint32_t num_neigh;
6322 struct neigh_walk_ctx wctx;
6323 json_object *json = NULL;
6324
6325 if (!is_evpn_enabled())
6326 return;
6327
6328 zvni = zvni_lookup(vni);
6329 if (!zvni) {
6330 vty_out(vty, "%% VNI %u does not exist\n", vni);
6331 return;
6332 }
6333
6334 num_neigh = hashcount(zvni->neigh_table);
6335 if (!num_neigh)
6336 return;
6337
6338 num_neigh = num_dup_detected_neighs(zvni);
6339 if (!num_neigh)
6340 return;
6341
6342 if (use_json)
6343 json = json_object_new_object();
6344
6345 /* Since we have IPv6 addresses to deal with which can vary widely in
6346 * size, we try to be a bit more elegant in display by first computing
6347 * the maximum width.
6348 */
6349 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
6350 wctx.zvni = zvni;
6351 wctx.vty = vty;
6352 wctx.addr_width = 15;
6353 wctx.json = json;
6354 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
6355
6356 if (!use_json) {
6357 vty_out(vty,
6358 "Number of ARPs (local and remote) known for this VNI: %u\n",
6359 num_neigh);
6360 vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
6361 -wctx.addr_width, "IP", "Type",
6362 "State", "MAC", "Remote VTEP");
6363 } else
6364 json_object_int_add(json, "numArpNd", num_neigh);
6365
6366 hash_iterate(zvni->neigh_table, zvni_print_dad_neigh_hash, &wctx);
6367
6368 if (use_json) {
6369 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6370 json, JSON_C_TO_STRING_PRETTY));
6371 json_object_free(json);
6372 }
6373 }
6374
6375 /*
6376 * Display MACs for a VNI (VTY command handler).
6377 */
6378 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
6379 vni_t vni, bool use_json)
6380 {
6381 zebra_vni_t *zvni;
6382 uint32_t num_macs;
6383 struct mac_walk_ctx wctx;
6384 json_object *json = NULL;
6385 json_object *json_mac = NULL;
6386
6387 if (!is_evpn_enabled())
6388 return;
6389 zvni = zvni_lookup(vni);
6390 if (!zvni) {
6391 if (use_json)
6392 vty_out(vty, "{}\n");
6393 else
6394 vty_out(vty, "%% VNI %u does not exist\n", vni);
6395 return;
6396 }
6397 num_macs = num_valid_macs(zvni);
6398 if (!num_macs)
6399 return;
6400
6401 if (use_json) {
6402 json = json_object_new_object();
6403 json_mac = json_object_new_object();
6404 }
6405
6406 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6407 wctx.zvni = zvni;
6408 wctx.vty = vty;
6409 wctx.json = json_mac;
6410
6411 if (!use_json) {
6412 vty_out(vty,
6413 "Number of MACs (local and remote) known for this VNI: %u\n",
6414 num_macs);
6415 vty_out(vty, "%-17s %-6s %-21s %-5s %s\n", "MAC", "Type",
6416 "Intf/Remote VTEP", "VLAN", "Seq #'s");
6417 } else
6418 json_object_int_add(json, "numMacs", num_macs);
6419
6420 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
6421
6422 if (use_json) {
6423 json_object_object_add(json, "macs", json_mac);
6424 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6425 json, JSON_C_TO_STRING_PRETTY));
6426 json_object_free(json);
6427 }
6428 }
6429
6430 /*
6431 * Display MACs for all VNIs (VTY command handler).
6432 */
6433 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
6434 bool print_dup, bool use_json)
6435 {
6436 struct mac_walk_ctx wctx;
6437 json_object *json = NULL;
6438
6439 if (!is_evpn_enabled()) {
6440 if (use_json)
6441 vty_out(vty, "{}\n");
6442 return;
6443 }
6444 if (use_json)
6445 json = json_object_new_object();
6446
6447 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6448 wctx.vty = vty;
6449 wctx.json = json;
6450 wctx.print_dup = print_dup;
6451 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
6452
6453 if (use_json) {
6454 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6455 json, JSON_C_TO_STRING_PRETTY));
6456 json_object_free(json);
6457 }
6458 }
6459
6460 /*
6461 * Display MACs in detail for all VNIs (VTY command handler).
6462 */
6463 void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
6464 struct zebra_vrf *zvrf,
6465 bool print_dup, bool use_json)
6466 {
6467 struct mac_walk_ctx wctx;
6468 json_object *json = NULL;
6469
6470 if (!is_evpn_enabled()) {
6471 if (use_json)
6472 vty_out(vty, "{}\n");
6473 return;
6474 }
6475 if (use_json)
6476 json = json_object_new_object();
6477
6478 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6479 wctx.vty = vty;
6480 wctx.json = json;
6481 wctx.print_dup = print_dup;
6482 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni_detail,
6483 &wctx);
6484
6485 if (use_json) {
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_vtep(struct vty *vty,
6496 struct zebra_vrf *zvrf,
6497 struct in_addr vtep_ip, bool use_json)
6498 {
6499 struct mac_walk_ctx wctx;
6500 json_object *json = NULL;
6501
6502 if (!is_evpn_enabled())
6503 return;
6504
6505 if (use_json)
6506 json = json_object_new_object();
6507
6508 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6509 wctx.vty = vty;
6510 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
6511 wctx.r_vtep_ip = vtep_ip;
6512 wctx.json = json;
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 specific MAC for a VNI, if present (VTY command handler).
6524 */
6525 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
6526 vni_t vni, struct ethaddr *macaddr,
6527 bool use_json)
6528 {
6529 zebra_vni_t *zvni;
6530 zebra_mac_t *mac;
6531 json_object *json = NULL;
6532
6533 if (!is_evpn_enabled())
6534 return;
6535
6536 zvni = zvni_lookup(vni);
6537 if (!zvni) {
6538 if (use_json)
6539 vty_out(vty, "{}\n");
6540 else
6541 vty_out(vty, "%% VNI %u does not exist\n", vni);
6542 return;
6543 }
6544 mac = zvni_mac_lookup(zvni, macaddr);
6545 if (!mac) {
6546 if (use_json)
6547 vty_out(vty, "{}\n");
6548 else
6549 vty_out(vty,
6550 "%% Requested MAC does not exist in VNI %u\n",
6551 vni);
6552 return;
6553 }
6554
6555 if (use_json)
6556 json = json_object_new_object();
6557
6558 zvni_print_mac(mac, vty, json);
6559 if (use_json) {
6560 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6561 json, JSON_C_TO_STRING_PRETTY));
6562 json_object_free(json);
6563 }
6564 }
6565
6566 /* Print Duplicate MACs per VNI */
6567 void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
6568 struct zebra_vrf *zvrf,
6569 vni_t vni, bool use_json)
6570 {
6571 zebra_vni_t *zvni;
6572 struct mac_walk_ctx wctx;
6573 uint32_t num_macs;
6574 json_object *json = NULL;
6575 json_object *json_mac = NULL;
6576
6577 if (!is_evpn_enabled())
6578 return;
6579
6580 zvni = zvni_lookup(vni);
6581 if (!zvni) {
6582 vty_out(vty, "%% VNI %u does not exist\n", vni);
6583 return;
6584 }
6585
6586 num_macs = num_valid_macs(zvni);
6587 if (!num_macs)
6588 return;
6589
6590 num_macs = num_dup_detected_macs(zvni);
6591 if (!num_macs)
6592 return;
6593
6594 if (use_json) {
6595 json = json_object_new_object();
6596 json_mac = json_object_new_object();
6597 }
6598
6599 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6600 wctx.zvni = zvni;
6601 wctx.vty = vty;
6602 wctx.json = json_mac;
6603
6604 if (!use_json) {
6605 vty_out(vty,
6606 "Number of MACs (local and remote) known for this VNI: %u\n",
6607 num_macs);
6608 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
6609 "Intf/Remote VTEP", "VLAN");
6610 } else
6611 json_object_int_add(json, "numMacs", num_macs);
6612
6613 hash_iterate(zvni->mac_table, zvni_print_dad_mac_hash, &wctx);
6614
6615 if (use_json) {
6616 json_object_object_add(json, "macs", json_mac);
6617 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6618 json, JSON_C_TO_STRING_PRETTY));
6619 json_object_free(json);
6620 }
6621
6622 }
6623
6624 int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
6625 struct zebra_vrf *zvrf,
6626 vni_t vni, struct ethaddr *macaddr)
6627 {
6628 zebra_vni_t *zvni;
6629 zebra_mac_t *mac;
6630 struct listnode *node = NULL;
6631 zebra_neigh_t *nbr = NULL;
6632
6633 if (!is_evpn_enabled())
6634 return CMD_SUCCESS;
6635
6636 zvni = zvni_lookup(vni);
6637 if (!zvni) {
6638 vty_out(vty, "%% VNI %u does not exist\n", vni);
6639 return CMD_WARNING;
6640 }
6641
6642 mac = zvni_mac_lookup(zvni, macaddr);
6643 if (!mac) {
6644 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
6645 vni);
6646 return CMD_WARNING;
6647 }
6648
6649 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
6650 vty_out(vty, "%% Requested MAC is not duplicate detected\n");
6651 return CMD_WARNING;
6652 }
6653
6654 /* Remove all IPs as duplicate associcated with this MAC */
6655 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
6656 /* For local neigh mark inactive so MACIP update is generated
6657 * to BGP. This is a scenario where MAC update received
6658 * and detected as duplicate which marked neigh as duplicate.
6659 * Later local neigh update did not get a chance to relay
6660 * to BGP. Similarly remote macip update, neigh needs to be
6661 * installed locally.
6662 */
6663 if (zvrf->dad_freeze &&
6664 CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
6665 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
6666 ZEBRA_NEIGH_SET_INACTIVE(nbr);
6667 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
6668 zvni_neigh_install(zvni, nbr);
6669 }
6670
6671 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6672 nbr->dad_count = 0;
6673 nbr->detect_start_time.tv_sec = 0;
6674 nbr->dad_dup_detect_time = 0;
6675 }
6676
6677 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
6678 mac->dad_count = 0;
6679 mac->detect_start_time.tv_sec = 0;
6680 mac->detect_start_time.tv_usec = 0;
6681 mac->dad_dup_detect_time = 0;
6682 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
6683
6684 /* warn-only action return */
6685 if (!zvrf->dad_freeze)
6686 return CMD_SUCCESS;
6687
6688 /* Local: Notify Peer VTEPs, Remote: Install the entry */
6689 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
6690 /* Inform to BGP */
6691 if (zvni_mac_send_add_to_client(zvni->vni,
6692 &mac->macaddr,
6693 mac->flags,
6694 mac->loc_seq))
6695 return CMD_SUCCESS;
6696
6697 /* Process all neighbors associated with this MAC. */
6698 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
6699
6700 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
6701 zvni_process_neigh_on_remote_mac_add(zvni, mac);
6702
6703 /* Install the entry. */
6704 zvni_mac_install(zvni, mac);
6705 }
6706
6707 return CMD_SUCCESS;
6708 }
6709
6710 int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
6711 struct zebra_vrf *zvrf,
6712 vni_t vni, struct ipaddr *ip)
6713 {
6714 zebra_vni_t *zvni;
6715 zebra_neigh_t *nbr;
6716 zebra_mac_t *mac;
6717 char buf[INET6_ADDRSTRLEN];
6718 char buf2[ETHER_ADDR_STRLEN];
6719
6720 if (!is_evpn_enabled())
6721 return CMD_SUCCESS;
6722
6723 zvni = zvni_lookup(vni);
6724 if (!zvni) {
6725 vty_out(vty, "%% VNI %u does not exist\n", vni);
6726 return CMD_WARNING;
6727 }
6728
6729 nbr = zvni_neigh_lookup(zvni, ip);
6730 if (!nbr) {
6731 vty_out(vty,
6732 "%% Requested host IP does not exist in VNI %u\n",
6733 vni);
6734 return CMD_WARNING;
6735 }
6736
6737 ipaddr2str(&nbr->ip, buf, sizeof(buf));
6738
6739 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
6740 vty_out(vty,
6741 "%% Requsted host IP %s is not duplicate detected\n",
6742 buf);
6743 return CMD_WARNING;
6744 }
6745
6746 mac = zvni_mac_lookup(zvni, &nbr->emac);
6747
6748 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
6749 vty_out(vty,
6750 "%% Requested IP's associated MAC %s is still in duplicate state\n",
6751 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
6752 return CMD_WARNING_CONFIG_FAILED;
6753 }
6754
6755 if (IS_ZEBRA_DEBUG_VXLAN)
6756 zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
6757 __PRETTY_FUNCTION__, buf, nbr->flags,
6758 nbr->loc_seq);
6759
6760 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6761 nbr->dad_count = 0;
6762 nbr->detect_start_time.tv_sec = 0;
6763 nbr->detect_start_time.tv_usec = 0;
6764 nbr->dad_dup_detect_time = 0;
6765 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
6766
6767 if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
6768 zvni_neigh_send_add_to_client(zvni->vni, ip,
6769 &nbr->emac,
6770 nbr->flags, nbr->loc_seq);
6771 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
6772 zvni_neigh_install(zvni, nbr);
6773 }
6774
6775 return CMD_SUCCESS;
6776 }
6777
6778 static void zvni_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt)
6779 {
6780 struct mac_walk_ctx *wctx = ctxt;
6781 zebra_mac_t *mac;
6782 zebra_vni_t *zvni;
6783 struct listnode *node = NULL;
6784 zebra_neigh_t *nbr = NULL;
6785
6786 mac = (zebra_mac_t *)bucket->data;
6787 if (!mac)
6788 return;
6789
6790 zvni = wctx->zvni;
6791
6792 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
6793 return;
6794
6795 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
6796 mac->dad_count = 0;
6797 mac->detect_start_time.tv_sec = 0;
6798 mac->detect_start_time.tv_usec = 0;
6799 mac->dad_dup_detect_time = 0;
6800 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
6801
6802 /* Remove all IPs as duplicate associcated with this MAC */
6803 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
6804 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
6805 && nbr->dad_count)
6806 ZEBRA_NEIGH_SET_INACTIVE(nbr);
6807
6808 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6809 nbr->dad_count = 0;
6810 nbr->detect_start_time.tv_sec = 0;
6811 nbr->dad_dup_detect_time = 0;
6812 }
6813
6814 /* Local: Notify Peer VTEPs, Remote: Install the entry */
6815 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
6816 /* Inform to BGP */
6817 if (zvni_mac_send_add_to_client(zvni->vni,
6818 &mac->macaddr,
6819 mac->flags, mac->loc_seq))
6820 return;
6821
6822 /* Process all neighbors associated with this MAC. */
6823 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
6824
6825 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
6826 zvni_process_neigh_on_remote_mac_add(zvni, mac);
6827
6828 /* Install the entry. */
6829 zvni_mac_install(zvni, mac);
6830 }
6831 }
6832
6833 static void zvni_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt)
6834 {
6835 struct neigh_walk_ctx *wctx = ctxt;
6836 zebra_neigh_t *nbr;
6837 zebra_vni_t *zvni;
6838 char buf[INET6_ADDRSTRLEN];
6839
6840 nbr = (zebra_neigh_t *)bucket->data;
6841 if (!nbr)
6842 return;
6843
6844 zvni = wctx->zvni;
6845
6846 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
6847 return;
6848
6849 if (IS_ZEBRA_DEBUG_VXLAN) {
6850 ipaddr2str(&nbr->ip, buf, sizeof(buf));
6851 zlog_debug(
6852 "%s: clear neigh %s dup state, flags 0x%x seq %u",
6853 __PRETTY_FUNCTION__, buf,
6854 nbr->flags, nbr->loc_seq);
6855 }
6856
6857 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
6858 nbr->dad_count = 0;
6859 nbr->detect_start_time.tv_sec = 0;
6860 nbr->detect_start_time.tv_usec = 0;
6861 nbr->dad_dup_detect_time = 0;
6862 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
6863
6864 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
6865 zvni_neigh_send_add_to_client(zvni->vni, &nbr->ip,
6866 &nbr->emac,
6867 nbr->flags, nbr->loc_seq);
6868 } else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
6869 zvni_neigh_install(zvni, nbr);
6870 }
6871 }
6872
6873 static void zvni_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket,
6874 void **args)
6875 {
6876 struct vty *vty;
6877 zebra_vni_t *zvni;
6878 struct zebra_vrf *zvrf;
6879 struct mac_walk_ctx m_wctx;
6880 struct neigh_walk_ctx n_wctx;
6881
6882 zvni = (zebra_vni_t *)bucket->data;
6883 if (!zvni)
6884 return;
6885
6886 vty = (struct vty *)args[0];
6887 zvrf = (struct zebra_vrf *)args[1];
6888
6889 if (hashcount(zvni->neigh_table)) {
6890 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6891 n_wctx.vty = vty;
6892 n_wctx.zvni = zvni;
6893 n_wctx.zvrf = zvrf;
6894 hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash,
6895 &n_wctx);
6896 }
6897
6898 if (num_valid_macs(zvni)) {
6899 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6900 m_wctx.zvni = zvni;
6901 m_wctx.vty = vty;
6902 m_wctx.zvrf = zvrf;
6903 hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
6904 }
6905
6906 }
6907
6908 int zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
6909 struct zebra_vrf *zvrf)
6910 {
6911 void *args[2];
6912
6913 if (!is_evpn_enabled())
6914 return CMD_SUCCESS;
6915
6916 args[0] = vty;
6917 args[1] = zvrf;
6918
6919 hash_iterate(zvrf->vni_table,
6920 (void (*)(struct hash_bucket *, void *))
6921 zvni_clear_dup_detect_hash_vni_all, args);
6922
6923 return CMD_SUCCESS;
6924 }
6925
6926 int zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
6927 struct zebra_vrf *zvrf,
6928 vni_t vni)
6929 {
6930 zebra_vni_t *zvni;
6931 struct mac_walk_ctx m_wctx;
6932 struct neigh_walk_ctx n_wctx;
6933
6934 if (!is_evpn_enabled())
6935 return CMD_SUCCESS;
6936
6937 zvni = zvni_lookup(vni);
6938 if (!zvni) {
6939 vty_out(vty, "%% VNI %u does not exist\n", vni);
6940 return CMD_WARNING;
6941 }
6942
6943 if (hashcount(zvni->neigh_table)) {
6944 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6945 n_wctx.vty = vty;
6946 n_wctx.zvni = zvni;
6947 n_wctx.zvrf = zvrf;
6948 hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash,
6949 &n_wctx);
6950 }
6951
6952 if (num_valid_macs(zvni)) {
6953 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6954 m_wctx.zvni = zvni;
6955 m_wctx.vty = vty;
6956 m_wctx.zvrf = zvrf;
6957 hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
6958 }
6959
6960 return CMD_SUCCESS;
6961 }
6962
6963 /*
6964 * Display MACs for a VNI from specific VTEP (VTY command handler).
6965 */
6966 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
6967 vni_t vni, struct in_addr vtep_ip,
6968 bool use_json)
6969 {
6970 zebra_vni_t *zvni;
6971 uint32_t num_macs;
6972 struct mac_walk_ctx wctx;
6973 json_object *json = NULL;
6974 json_object *json_mac = NULL;
6975
6976 if (!is_evpn_enabled())
6977 return;
6978 zvni = zvni_lookup(vni);
6979 if (!zvni) {
6980 if (use_json)
6981 vty_out(vty, "{}\n");
6982 else
6983 vty_out(vty, "%% VNI %u does not exist\n", vni);
6984 return;
6985 }
6986 num_macs = num_valid_macs(zvni);
6987 if (!num_macs)
6988 return;
6989
6990 if (use_json) {
6991 json = json_object_new_object();
6992 json_mac = json_object_new_object();
6993 }
6994
6995 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
6996 wctx.zvni = zvni;
6997 wctx.vty = vty;
6998 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
6999 wctx.r_vtep_ip = vtep_ip;
7000 wctx.json = json_mac;
7001 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
7002
7003 if (use_json) {
7004 json_object_int_add(json, "numMacs", wctx.count);
7005 if (wctx.count)
7006 json_object_object_add(json, "macs", json_mac);
7007 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7008 json, JSON_C_TO_STRING_PRETTY));
7009 json_object_free(json);
7010 }
7011 }
7012
7013
7014 /*
7015 * Display VNI information (VTY command handler).
7016 */
7017 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
7018 bool use_json)
7019 {
7020 json_object *json = NULL;
7021 void *args[2];
7022 zebra_l3vni_t *zl3vni = NULL;
7023 zebra_vni_t *zvni = NULL;
7024
7025 if (!is_evpn_enabled())
7026 return;
7027
7028 if (use_json)
7029 json = json_object_new_object();
7030 args[0] = vty;
7031 args[1] = json;
7032
7033 zl3vni = zl3vni_lookup(vni);
7034 if (zl3vni) {
7035 zl3vni_print(zl3vni, (void *)args);
7036 } else {
7037 zvni = zvni_lookup(vni);
7038 if (!zvni) {
7039 if (use_json)
7040 vty_out(vty, "{}\n");
7041 else
7042 vty_out(vty, "%% VNI %u does not exist\n", vni);
7043 return;
7044 }
7045
7046 zvni_print(zvni, (void *)args);
7047 }
7048
7049 if (use_json) {
7050 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7051 json, JSON_C_TO_STRING_PRETTY));
7052 json_object_free(json);
7053 }
7054 }
7055
7056 /* Display all global details for EVPN */
7057 void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
7058 {
7059 int num_l2vnis = 0;
7060 int num_l3vnis = 0;
7061 int num_vnis = 0;
7062 json_object *json = NULL;
7063 struct zebra_vrf *zvrf = NULL;
7064
7065 if (!is_evpn_enabled())
7066 return;
7067
7068 zvrf = zebra_vrf_get_evpn();
7069 if (!zvrf)
7070 return;
7071
7072 num_l3vnis = hashcount(zrouter.l3vni_table);
7073 num_l2vnis = hashcount(zvrf->vni_table);
7074 num_vnis = num_l2vnis + num_l3vnis;
7075
7076 if (uj) {
7077 json = json_object_new_object();
7078 json_object_string_add(json, "advertiseGatewayMacip",
7079 zvrf->advertise_gw_macip ? "Yes" : "No");
7080 json_object_int_add(json, "numVnis", num_vnis);
7081 json_object_int_add(json, "numL2Vnis", num_l2vnis);
7082 json_object_int_add(json, "numL3Vnis", num_l3vnis);
7083 if (zvrf->dup_addr_detect)
7084 json_object_boolean_true_add(json,
7085 "isDuplicateAddrDetection");
7086 else
7087 json_object_boolean_false_add(json,
7088 "isDuplicateAddrDetection");
7089 json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
7090 json_object_int_add(json, "detectionTime", zvrf->dad_time);
7091 json_object_int_add(json, "detectionFreezeTime",
7092 zvrf->dad_freeze_time);
7093
7094 } else {
7095 vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
7096 vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
7097 vty_out(vty, "Advertise gateway mac-ip: %s\n",
7098 zvrf->advertise_gw_macip ? "Yes" : "No");
7099 vty_out(vty, "Advertise svi mac-ip: %s\n",
7100 zvrf->advertise_svi_macip ? "Yes" : "No");
7101 vty_out(vty, "Duplicate address detection: %s\n",
7102 zvrf->dup_addr_detect ? "Enable" : "Disable");
7103 vty_out(vty, " Detection max-moves %u, time %d\n",
7104 zvrf->dad_max_moves, zvrf->dad_time);
7105 if (zvrf->dad_freeze) {
7106 if (zvrf->dad_freeze_time)
7107 vty_out(vty, " Detection freeze %u\n",
7108 zvrf->dad_freeze_time);
7109 else
7110 vty_out(vty, " Detection freeze %s\n",
7111 "permanent");
7112 }
7113 }
7114
7115 if (uj) {
7116 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7117 json, JSON_C_TO_STRING_PRETTY));
7118 json_object_free(json);
7119 }
7120 }
7121
7122 /*
7123 * Display VNI hash table (VTY command handler).
7124 */
7125 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
7126 bool use_json)
7127 {
7128 json_object *json = NULL;
7129 void *args[2];
7130
7131 if (!is_evpn_enabled())
7132 return;
7133
7134 if (use_json)
7135 json = json_object_new_object();
7136 else
7137 vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
7138 "Type", "VxLAN IF", "# MACs", "# ARPs",
7139 "# Remote VTEPs", "Tenant VRF");
7140
7141 args[0] = vty;
7142 args[1] = json;
7143
7144 /* Display all L2-VNIs */
7145 hash_iterate(zvrf->vni_table,
7146 (void (*)(struct hash_bucket *, void *))zvni_print_hash,
7147 args);
7148
7149 /* Display all L3-VNIs */
7150 hash_iterate(zrouter.l3vni_table,
7151 (void (*)(struct hash_bucket *, void *))zl3vni_print_hash,
7152 args);
7153
7154 if (use_json) {
7155 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7156 json, JSON_C_TO_STRING_PRETTY));
7157 json_object_free(json);
7158 }
7159 }
7160
7161 void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
7162 {
7163 struct stream *s;
7164 int time = 0;
7165 uint32_t max_moves = 0;
7166 uint32_t freeze_time = 0;
7167 bool dup_addr_detect = false;
7168 bool freeze = false;
7169
7170 s = msg;
7171 STREAM_GETL(s, dup_addr_detect);
7172 STREAM_GETL(s, time);
7173 STREAM_GETL(s, max_moves);
7174 STREAM_GETL(s, freeze);
7175 STREAM_GETL(s, freeze_time);
7176
7177 /* DAD previous state was enabled, and new state is disable,
7178 * clear all duplicate detected addresses.
7179 */
7180 if (zvrf->dup_addr_detect && !dup_addr_detect)
7181 zebra_vxlan_clear_dup_detect_vni_all(NULL, zvrf);
7182
7183 zvrf->dup_addr_detect = dup_addr_detect;
7184 zvrf->dad_time = time;
7185 zvrf->dad_max_moves = max_moves;
7186 zvrf->dad_freeze = freeze;
7187 zvrf->dad_freeze_time = freeze_time;
7188
7189 if (IS_ZEBRA_DEBUG_VXLAN)
7190 zlog_debug(
7191 "VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
7192 vrf_id_to_name(zvrf->vrf->vrf_id),
7193 zvrf->dup_addr_detect ? "enable" : "disable",
7194 zvrf->dad_max_moves,
7195 zvrf->dad_time,
7196 zvrf->dad_freeze ? "enable" : "disable",
7197 zvrf->dad_freeze_time);
7198
7199 stream_failure:
7200 return;
7201 }
7202
7203 /*
7204 * Display VNI hash table in detail(VTY command handler).
7205 */
7206 void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
7207 bool use_json)
7208 {
7209 json_object *json = NULL;
7210 struct zebra_ns *zns = NULL;
7211 struct zvni_evpn_show zes;
7212
7213 if (!is_evpn_enabled())
7214 return;
7215
7216 zns = zebra_ns_lookup(NS_DEFAULT);
7217 if (!zns)
7218 return;
7219
7220
7221 if (use_json)
7222 json = json_object_new_object();
7223
7224 zes.vty = vty;
7225 zes.json = json;
7226 zes.zvrf = zvrf;
7227
7228 /* Display all L2-VNIs */
7229 hash_iterate(
7230 zvrf->vni_table,
7231 (void (*)(struct hash_bucket *, void *))zvni_print_hash_detail,
7232 &zes);
7233
7234 /* Display all L3-VNIs */
7235 hash_iterate(zrouter.l3vni_table,
7236 (void (*)(struct hash_bucket *,
7237 void *))zl3vni_print_hash_detail,
7238 &zes);
7239
7240 if (use_json) {
7241 vty_out(vty, "%s\n",
7242 json_object_to_json_string_ext(
7243 json, JSON_C_TO_STRING_PRETTY));
7244 json_object_free(json);
7245 }
7246 }
7247
7248 /*
7249 * Handle neighbor delete notification from the kernel (on a VLAN device
7250 * / L3 interface). This may result in either the neighbor getting deleted
7251 * from our database or being re-added to the kernel (if it is a valid
7252 * remote neighbor).
7253 */
7254 int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
7255 struct interface *link_if,
7256 struct ipaddr *ip)
7257 {
7258 char buf[INET6_ADDRSTRLEN];
7259 char buf2[ETHER_ADDR_STRLEN];
7260 zebra_neigh_t *n = NULL;
7261 zebra_vni_t *zvni = NULL;
7262 zebra_mac_t *zmac = NULL;
7263 zebra_l3vni_t *zl3vni = NULL;
7264 struct zebra_vrf *zvrf;
7265
7266 /* check if this is a remote neigh entry corresponding to remote
7267 * next-hop
7268 */
7269 zl3vni = zl3vni_from_svi(ifp, link_if);
7270 if (zl3vni)
7271 return zl3vni_local_nh_del(zl3vni, ip);
7272
7273 /* We are only interested in neighbors on an SVI that resides on top
7274 * of a VxLAN bridge.
7275 */
7276 zvni = zvni_from_svi(ifp, link_if);
7277 if (!zvni)
7278 return 0;
7279
7280 if (!zvni->vxlan_if) {
7281 zlog_debug(
7282 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
7283 zvni->vni, zvni);
7284 return -1;
7285 }
7286
7287 if (IS_ZEBRA_DEBUG_VXLAN)
7288 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
7289 ipaddr2str(ip, buf, sizeof(buf)), ifp->name,
7290 ifp->ifindex, zvni->vni);
7291
7292 /* If entry doesn't exist, nothing to do. */
7293 n = zvni_neigh_lookup(zvni, ip);
7294 if (!n)
7295 return 0;
7296
7297 zmac = zvni_mac_lookup(zvni, &n->emac);
7298 if (!zmac) {
7299 if (IS_ZEBRA_DEBUG_VXLAN)
7300 zlog_debug(
7301 "Trying to del a neigh %s without a mac %s on VNI %u",
7302 ipaddr2str(ip, buf, sizeof(buf)),
7303 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
7304 zvni->vni);
7305
7306 return 0;
7307 }
7308
7309 /* If it is a remote entry, the kernel has aged this out or someone has
7310 * deleted it, it needs to be re-installed as Quagga is the owner.
7311 */
7312 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
7313 zvni_neigh_install(zvni, n);
7314 return 0;
7315 }
7316
7317 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
7318 if (!zvrf) {
7319 zlog_debug("%s: VNI %u vrf lookup failed.",
7320 __PRETTY_FUNCTION__, zvni->vni);
7321 return -1;
7322 }
7323
7324 /* In case of feeze action, if local neigh is in duplicate state,
7325 * Mark the Neigh as inactive before sending delete request to BGPd,
7326 * If BGPd has remote entry, it will re-install
7327 */
7328 if (zvrf->dad_freeze &&
7329 CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
7330 ZEBRA_NEIGH_SET_INACTIVE(n);
7331
7332 /* Remove neighbor from BGP. */
7333 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0, n->state);
7334
7335 /* Delete this neighbor entry. */
7336 zvni_neigh_del(zvni, n);
7337
7338 /* see if the AUTO mac needs to be deleted */
7339 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
7340 && !listcount(zmac->neigh_list))
7341 zvni_mac_del(zvni, zmac);
7342
7343 return 0;
7344 }
7345
7346 /*
7347 * Handle neighbor add or update notification from the kernel (on a VLAN
7348 * device / L3 interface). This is typically for a local neighbor but can
7349 * also be for a remote neighbor (e.g., ageout notification). It could
7350 * also be a "move" scenario.
7351 */
7352 int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
7353 struct interface *link_if,
7354 struct ipaddr *ip,
7355 struct ethaddr *macaddr,
7356 uint16_t state,
7357 bool is_ext,
7358 bool is_router)
7359 {
7360 char buf[ETHER_ADDR_STRLEN];
7361 char buf2[INET6_ADDRSTRLEN];
7362 zebra_vni_t *zvni = NULL;
7363 zebra_l3vni_t *zl3vni = NULL;
7364
7365 /* check if this is a remote neigh entry corresponding to remote
7366 * next-hop
7367 */
7368 zl3vni = zl3vni_from_svi(ifp, link_if);
7369 if (zl3vni)
7370 return zl3vni_local_nh_add_update(zl3vni, ip, state);
7371
7372 /* We are only interested in neighbors on an SVI that resides on top
7373 * of a VxLAN bridge.
7374 */
7375 zvni = zvni_from_svi(ifp, link_if);
7376 if (!zvni)
7377 return 0;
7378
7379 if (IS_ZEBRA_DEBUG_VXLAN)
7380 zlog_debug(
7381 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
7382 ipaddr2str(ip, buf2, sizeof(buf2)),
7383 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7384 ifp->ifindex, state, is_ext ? "ext-learned " : "",
7385 is_router ? "router " : "",
7386 zvni->vni);
7387
7388 /* Is this about a local neighbor or a remote one? */
7389 if (!is_ext)
7390 return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
7391 is_router);
7392
7393 return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
7394 }
7395
7396
7397 /*
7398 * Handle message from client to delete a remote MACIP for a VNI.
7399 */
7400 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
7401 {
7402 struct stream *s;
7403 vni_t vni;
7404 struct ethaddr macaddr;
7405 struct ipaddr ip;
7406 struct in_addr vtep_ip;
7407 uint16_t l = 0, ipa_len;
7408 char buf[ETHER_ADDR_STRLEN];
7409 char buf1[INET6_ADDRSTRLEN];
7410
7411 memset(&macaddr, 0, sizeof(struct ethaddr));
7412 memset(&ip, 0, sizeof(struct ipaddr));
7413 memset(&vtep_ip, 0, sizeof(struct in_addr));
7414
7415 s = msg;
7416
7417 while (l < hdr->length) {
7418 /* Obtain each remote MACIP and process. */
7419 /* Message contains VNI, followed by MAC followed by IP (if any)
7420 * followed by remote VTEP IP.
7421 */
7422 memset(&ip, 0, sizeof(ip));
7423 STREAM_GETL(s, vni);
7424 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
7425 STREAM_GETL(s, ipa_len);
7426 if (ipa_len) {
7427 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
7428 : IPADDR_V6;
7429 STREAM_GET(&ip.ip.addr, s, ipa_len);
7430 }
7431 l += 4 + ETH_ALEN + 4 + ipa_len;
7432 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
7433 l += IPV4_MAX_BYTELEN;
7434
7435 if (IS_ZEBRA_DEBUG_VXLAN)
7436 zlog_debug(
7437 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
7438 vni,
7439 prefix_mac2str(&macaddr, buf, sizeof(buf)),
7440 ipa_len ? " IP " : "",
7441 ipa_len ?
7442 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
7443 inet_ntoa(vtep_ip),
7444 zebra_route_string(client->proto));
7445
7446 process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
7447 }
7448
7449 stream_failure:
7450 return;
7451 }
7452
7453 /*
7454 * Handle message from client to add a remote MACIP for a VNI. This
7455 * could be just the add of a MAC address or the add of a neighbor
7456 * (IP+MAC).
7457 */
7458 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
7459 {
7460 struct stream *s;
7461 vni_t vni;
7462 struct ethaddr macaddr;
7463 struct ipaddr ip;
7464 struct in_addr vtep_ip;
7465 uint16_t l = 0, ipa_len;
7466 uint8_t flags = 0;
7467 uint32_t seq;
7468 char buf[ETHER_ADDR_STRLEN];
7469 char buf1[INET6_ADDRSTRLEN];
7470
7471 memset(&macaddr, 0, sizeof(struct ethaddr));
7472 memset(&ip, 0, sizeof(struct ipaddr));
7473 memset(&vtep_ip, 0, sizeof(struct in_addr));
7474
7475 if (!EVPN_ENABLED(zvrf)) {
7476 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
7477 return;
7478 }
7479
7480 s = msg;
7481
7482 while (l < hdr->length) {
7483 /* Obtain each remote MACIP and process. */
7484 /* Message contains VNI, followed by MAC followed by IP (if any)
7485 * followed by remote VTEP IP.
7486 */
7487 memset(&ip, 0, sizeof(ip));
7488 STREAM_GETL(s, vni);
7489 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
7490 STREAM_GETL(s, ipa_len);
7491 if (ipa_len) {
7492 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
7493 : IPADDR_V6;
7494 STREAM_GET(&ip.ip.addr, s, ipa_len);
7495 }
7496 l += 4 + ETH_ALEN + 4 + ipa_len;
7497 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
7498 l += IPV4_MAX_BYTELEN;
7499
7500 /* Get flags - sticky mac and/or gateway mac */
7501 STREAM_GETC(s, flags);
7502 l++;
7503 STREAM_GETL(s, seq);
7504 l += 4;
7505
7506 if (IS_ZEBRA_DEBUG_VXLAN)
7507 zlog_debug(
7508 "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
7509 vni,
7510 prefix_mac2str(&macaddr, buf, sizeof(buf)),
7511 ipa_len ? " IP " : "",
7512 ipa_len ?
7513 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
7514 flags, seq, inet_ntoa(vtep_ip),
7515 zebra_route_string(client->proto));
7516
7517 process_remote_macip_add(vni, &macaddr, ipa_len, &ip,
7518 flags, seq, vtep_ip);
7519 }
7520
7521 stream_failure:
7522 return;
7523 }
7524
7525 /*
7526 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
7527 * us, this must involve a multihoming scenario. Treat this as implicit delete
7528 * of any prior local MAC.
7529 */
7530 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
7531 struct interface *br_if,
7532 struct ethaddr *macaddr, vlanid_t vid)
7533 {
7534 struct zebra_if *zif;
7535 struct zebra_l2info_vxlan *vxl;
7536 vni_t vni;
7537 zebra_vni_t *zvni;
7538 zebra_mac_t *mac;
7539 char buf[ETHER_ADDR_STRLEN];
7540
7541 zif = ifp->info;
7542 assert(zif);
7543 vxl = &zif->l2info.vxl;
7544 vni = vxl->vni;
7545
7546 /* Check if EVPN is enabled. */
7547 if (!is_evpn_enabled())
7548 return 0;
7549
7550 /* Locate hash entry; it is expected to exist. */
7551 zvni = zvni_lookup(vni);
7552 if (!zvni)
7553 return 0;
7554
7555 /* If entry doesn't exist, nothing to do. */
7556 mac = zvni_mac_lookup(zvni, macaddr);
7557 if (!mac)
7558 return 0;
7559
7560 /* Is it a local entry? */
7561 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
7562 return 0;
7563
7564 if (IS_ZEBRA_DEBUG_VXLAN)
7565 zlog_debug(
7566 "Add/update remote MAC %s intf %s(%u) VNI %u flags 0x%x - del local",
7567 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7568 ifp->ifindex, vni, mac->flags);
7569
7570 /* Remove MAC from BGP. */
7571 zvni_mac_send_del_to_client(zvni->vni, macaddr);
7572
7573 /*
7574 * If there are no neigh associated with the mac delete the mac
7575 * else mark it as AUTO for forward reference
7576 */
7577 if (!listcount(mac->neigh_list)) {
7578 zvni_mac_del(zvni, mac);
7579 } else {
7580 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7581 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7582 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7583 }
7584
7585 return 0;
7586 }
7587
7588 /*
7589 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
7590 * This can happen because the remote MAC entries are also added as "dynamic",
7591 * so the kernel can ageout the entry.
7592 */
7593 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
7594 struct interface *br_if,
7595 struct ethaddr *macaddr, vlanid_t vid)
7596 {
7597 struct zebra_if *zif = NULL;
7598 struct zebra_l2info_vxlan *vxl = NULL;
7599 vni_t vni;
7600 zebra_vni_t *zvni = NULL;
7601 zebra_l3vni_t *zl3vni = NULL;
7602 zebra_mac_t *mac = NULL;
7603 char buf[ETHER_ADDR_STRLEN];
7604
7605 zif = ifp->info;
7606 assert(zif);
7607 vxl = &zif->l2info.vxl;
7608 vni = vxl->vni;
7609
7610 /* Check if EVPN is enabled. */
7611 if (!is_evpn_enabled())
7612 return 0;
7613
7614 /* check if this is a remote RMAC and readd simillar to remote macs */
7615 zl3vni = zl3vni_lookup(vni);
7616 if (zl3vni)
7617 return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
7618
7619 /* Locate hash entry; it is expected to exist. */
7620 zvni = zvni_lookup(vni);
7621 if (!zvni)
7622 return 0;
7623
7624 /* If entry doesn't exist, nothing to do. */
7625 mac = zvni_mac_lookup(zvni, macaddr);
7626 if (!mac)
7627 return 0;
7628
7629 /* Is it a remote entry? */
7630 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
7631 return 0;
7632
7633 if (IS_ZEBRA_DEBUG_VXLAN)
7634 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
7635 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7636 ifp->ifindex, vni);
7637
7638 zvni_mac_install(zvni, mac);
7639 return 0;
7640 }
7641
7642 /*
7643 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
7644 */
7645 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
7646 struct ethaddr *macaddr, vlanid_t vid)
7647 {
7648 zebra_vni_t *zvni;
7649 zebra_mac_t *mac;
7650 char buf[ETHER_ADDR_STRLEN];
7651
7652 /* We are interested in MACs only on ports or (port, VLAN) that
7653 * map to a VNI.
7654 */
7655 zvni = zvni_map_vlan(ifp, br_if, vid);
7656 if (!zvni)
7657 return 0;
7658 if (!zvni->vxlan_if) {
7659 zlog_debug(
7660 "VNI %u hash %p doesn't have intf upon local MAC DEL",
7661 zvni->vni, zvni);
7662 return -1;
7663 }
7664
7665 /* If entry doesn't exist, nothing to do. */
7666 mac = zvni_mac_lookup(zvni, macaddr);
7667 if (!mac)
7668 return 0;
7669
7670 /* Is it a local entry? */
7671 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
7672 return 0;
7673
7674 if (IS_ZEBRA_DEBUG_VXLAN)
7675 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u flags 0x%x",
7676 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
7677 ifp->ifindex, vid, zvni->vni, mac->flags);
7678
7679 /* Update all the neigh entries associated with this mac */
7680 zvni_process_neigh_on_local_mac_del(zvni, mac);
7681
7682 /* Remove MAC from BGP. */
7683 zvni_mac_send_del_to_client(zvni->vni, macaddr);
7684
7685 /*
7686 * If there are no neigh associated with the mac delete the mac
7687 * else mark it as AUTO for forward reference
7688 */
7689 if (!listcount(mac->neigh_list)) {
7690 zvni_mac_del(zvni, mac);
7691 } else {
7692 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7693 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7694 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7695 }
7696
7697 return 0;
7698 }
7699
7700 /*
7701 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
7702 */
7703 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
7704 struct interface *br_if,
7705 struct ethaddr *macaddr, vlanid_t vid,
7706 bool sticky)
7707 {
7708 zebra_vni_t *zvni;
7709 zebra_mac_t *mac;
7710 struct zebra_vrf *zvrf;
7711 char buf[ETHER_ADDR_STRLEN];
7712 bool mac_sticky = false;
7713 bool inform_client = false;
7714 bool upd_neigh = false;
7715 bool is_dup_detect = false;
7716 struct in_addr vtep_ip = {.s_addr = 0};
7717
7718 /* We are interested in MACs only on ports or (port, VLAN) that
7719 * map to a VNI.
7720 */
7721 zvni = zvni_map_vlan(ifp, br_if, vid);
7722 if (!zvni) {
7723 if (IS_ZEBRA_DEBUG_VXLAN)
7724 zlog_debug(
7725 "\tAdd/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
7726 sticky ? "sticky " : "",
7727 prefix_mac2str(macaddr, buf, sizeof(buf)),
7728 ifp->name, ifp->ifindex, vid);
7729 return 0;
7730 }
7731
7732 if (!zvni->vxlan_if) {
7733 if (IS_ZEBRA_DEBUG_VXLAN)
7734 zlog_debug(
7735 "\tVNI %u hash %p doesn't have intf upon local MAC ADD",
7736 zvni->vni, zvni);
7737 return -1;
7738 }
7739
7740 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
7741 if (!zvrf) {
7742 if (IS_ZEBRA_DEBUG_VXLAN)
7743 zlog_debug("\tNo Vrf found for vrf_id: %d",
7744 zvni->vxlan_if->vrf_id);
7745 return -1;
7746 }
7747
7748 /* Check if we need to create or update or it is a NO-OP. */
7749 mac = zvni_mac_lookup(zvni, macaddr);
7750 if (!mac) {
7751 if (IS_ZEBRA_DEBUG_VXLAN)
7752 zlog_debug(
7753 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
7754 sticky ? "sticky " : "",
7755 prefix_mac2str(macaddr, buf, sizeof(buf)),
7756 ifp->name, ifp->ifindex, vid, zvni->vni);
7757
7758 mac = zvni_mac_add(zvni, macaddr);
7759 if (!mac) {
7760 flog_err(
7761 EC_ZEBRA_MAC_ADD_FAILED,
7762 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
7763 prefix_mac2str(macaddr, buf, sizeof(buf)),
7764 ifp->name, ifp->ifindex, vid, zvni->vni);
7765 return -1;
7766 }
7767 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7768 mac->fwd_info.local.ifindex = ifp->ifindex;
7769 mac->fwd_info.local.vid = vid;
7770 if (sticky)
7771 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7772 inform_client = true;
7773
7774 } else {
7775 if (IS_ZEBRA_DEBUG_VXLAN)
7776 zlog_debug(
7777 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
7778 sticky ? "sticky " : "",
7779 prefix_mac2str(macaddr, buf, sizeof(buf)),
7780 ifp->name, ifp->ifindex, vid, zvni->vni,
7781 mac->flags);
7782
7783 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
7784 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
7785 mac_sticky = true;
7786
7787 /*
7788 * Update any changes and if changes are relevant to
7789 * BGP, note it.
7790 */
7791 if (mac_sticky == sticky
7792 && mac->fwd_info.local.ifindex == ifp->ifindex
7793 && mac->fwd_info.local.vid == vid) {
7794 if (IS_ZEBRA_DEBUG_VXLAN)
7795 zlog_debug(
7796 "\tAdd/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
7797 "entry exists and has not changed ",
7798 sticky ? "sticky " : "",
7799 prefix_mac2str(macaddr, buf,
7800 sizeof(buf)),
7801 ifp->name, ifp->ifindex, vid,
7802 zvni->vni);
7803 return 0;
7804 }
7805 if (mac_sticky != sticky) {
7806 if (sticky)
7807 SET_FLAG(mac->flags,
7808 ZEBRA_MAC_STICKY);
7809 else
7810 UNSET_FLAG(mac->flags,
7811 ZEBRA_MAC_STICKY);
7812 inform_client = true;
7813 }
7814
7815 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
7816 mac->fwd_info.local.ifindex = ifp->ifindex;
7817 mac->fwd_info.local.vid = vid;
7818
7819 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
7820 CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
7821 bool do_dad = false;
7822
7823 /*
7824 * MAC has either moved or was "internally" created due
7825 * to a neighbor learn and is now actually learnt. If
7826 * it was learnt as a remote sticky MAC, this is an
7827 * operator error.
7828 */
7829 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
7830 flog_warn(
7831 EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
7832 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
7833 prefix_mac2str(macaddr, buf,
7834 sizeof(buf)),
7835 inet_ntoa(mac->fwd_info.r_vtep_ip),
7836 zvni->vni);
7837 return 0;
7838 }
7839
7840 /* If an actual move, compute MAC's seq number */
7841 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
7842 mac->loc_seq = MAX(mac->rem_seq + 1,
7843 mac->loc_seq);
7844 vtep_ip = mac->fwd_info.r_vtep_ip;
7845 /* Trigger DAD for remote MAC */
7846 do_dad = true;
7847 }
7848
7849 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
7850 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7851 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
7852 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
7853 mac->fwd_info.local.ifindex = ifp->ifindex;
7854 mac->fwd_info.local.vid = vid;
7855 if (sticky)
7856 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7857 else
7858 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7859 /*
7860 * We have to inform BGP of this MAC as well as process
7861 * all neighbors.
7862 */
7863 inform_client = true;
7864 upd_neigh = true;
7865
7866 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac, vtep_ip,
7867 do_dad,
7868 &is_dup_detect,
7869 true);
7870 if (is_dup_detect) {
7871 inform_client = false;
7872 upd_neigh = false;
7873 }
7874 }
7875 }
7876
7877 /* Inform BGP if required. */
7878 if (inform_client) {
7879 if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
7880 mac->flags, mac->loc_seq))
7881 return -1;
7882 }
7883
7884 /* Process all neighbors associated with this MAC, if required. */
7885 if (upd_neigh)
7886 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
7887
7888 return 0;
7889 }
7890
7891 /*
7892 * Handle message from client to delete a remote VTEP for a VNI.
7893 */
7894 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
7895 {
7896 struct stream *s;
7897 unsigned short l = 0;
7898 vni_t vni;
7899 struct in_addr vtep_ip;
7900 zebra_vni_t *zvni;
7901 zebra_vtep_t *zvtep;
7902 struct interface *ifp;
7903 struct zebra_if *zif;
7904
7905 if (!is_evpn_enabled()) {
7906 zlog_debug(
7907 "%s: EVPN is not enabled yet we have received a vtep del command",
7908 __PRETTY_FUNCTION__);
7909 return;
7910 }
7911
7912 if (!EVPN_ENABLED(zvrf)) {
7913 zlog_debug("Recv MACIP DEL for non-EVPN VRF %u",
7914 zvrf_id(zvrf));
7915 return;
7916 }
7917
7918 s = msg;
7919
7920 while (l < hdr->length) {
7921 int flood_control __attribute__((unused));
7922
7923 /* Obtain each remote VTEP and process. */
7924 STREAM_GETL(s, vni);
7925 l += 4;
7926 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
7927 l += IPV4_MAX_BYTELEN;
7928
7929 /* Flood control is intentionally ignored right now */
7930 STREAM_GETL(s, flood_control);
7931 l += 4;
7932
7933 if (IS_ZEBRA_DEBUG_VXLAN)
7934 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
7935 inet_ntoa(vtep_ip), vni,
7936 zebra_route_string(client->proto));
7937
7938 /* Locate VNI hash entry - expected to exist. */
7939 zvni = zvni_lookup(vni);
7940 if (!zvni) {
7941 if (IS_ZEBRA_DEBUG_VXLAN)
7942 zlog_debug(
7943 "Failed to locate VNI hash upon remote VTEP DEL, "
7944 "VNI %u",
7945 vni);
7946 continue;
7947 }
7948
7949 ifp = zvni->vxlan_if;
7950 if (!ifp) {
7951 zlog_debug(
7952 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
7953 zvni->vni, zvni);
7954 continue;
7955 }
7956 zif = ifp->info;
7957
7958 /* If down or not mapped to a bridge, we're done. */
7959 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
7960 continue;
7961
7962 /* If the remote VTEP does not exist, there's nothing more to
7963 * do.
7964 * Otherwise, uninstall any remote MACs pointing to this VTEP
7965 * and
7966 * then, the VTEP entry itself and remove it.
7967 */
7968 zvtep = zvni_vtep_find(zvni, &vtep_ip);
7969 if (!zvtep)
7970 continue;
7971
7972 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
7973 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
7974 zvni_vtep_uninstall(zvni, &vtep_ip);
7975 zvni_vtep_del(zvni, zvtep);
7976 }
7977
7978 stream_failure:
7979 return;
7980 }
7981
7982 /*
7983 * Handle message from client to add a remote VTEP for a VNI.
7984 */
7985 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
7986 {
7987 struct stream *s;
7988 unsigned short l = 0;
7989 vni_t vni;
7990 struct in_addr vtep_ip;
7991 zebra_vni_t *zvni;
7992 struct interface *ifp;
7993 struct zebra_if *zif;
7994 int flood_control;
7995 zebra_vtep_t *zvtep;
7996
7997 if (!is_evpn_enabled()) {
7998 zlog_debug(
7999 "%s: EVPN not enabled yet we received a vtep_add zapi call",
8000 __PRETTY_FUNCTION__);
8001 return;
8002 }
8003
8004 if (!EVPN_ENABLED(zvrf)) {
8005 zlog_debug("Recv MACIP ADD for non-EVPN VRF %u",
8006 zvrf_id(zvrf));
8007 return;
8008 }
8009
8010 s = msg;
8011
8012 while (l < hdr->length) {
8013 /* Obtain each remote VTEP and process. */
8014 STREAM_GETL(s, vni);
8015 l += 4;
8016 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
8017 STREAM_GETL(s, flood_control);
8018 l += IPV4_MAX_BYTELEN + 4;
8019
8020 if (IS_ZEBRA_DEBUG_VXLAN)
8021 zlog_debug("Recv VTEP_ADD %s VNI %u flood %d from %s",
8022 inet_ntoa(vtep_ip), vni, flood_control,
8023 zebra_route_string(client->proto));
8024
8025 /* Locate VNI hash entry - expected to exist. */
8026 zvni = zvni_lookup(vni);
8027 if (!zvni) {
8028 flog_err(
8029 EC_ZEBRA_VTEP_ADD_FAILED,
8030 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
8031 vni);
8032 continue;
8033 }
8034
8035 ifp = zvni->vxlan_if;
8036 if (!ifp) {
8037 flog_err(
8038 EC_ZEBRA_VTEP_ADD_FAILED,
8039 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
8040 zvni->vni, zvni);
8041 continue;
8042 }
8043
8044 zif = ifp->info;
8045
8046 /* If down or not mapped to a bridge, we're done. */
8047 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8048 continue;
8049
8050 zvtep = zvni_vtep_find(zvni, &vtep_ip);
8051 if (zvtep) {
8052 /* If the remote VTEP already exists check if
8053 * the flood mode has changed
8054 */
8055 if (zvtep->flood_control != flood_control) {
8056 if (zvtep->flood_control
8057 == VXLAN_FLOOD_DISABLED)
8058 /* old mode was head-end-replication but
8059 * is no longer; get rid of the HER fdb
8060 * entry installed before
8061 */
8062 zvni_vtep_uninstall(zvni, &vtep_ip);
8063 zvtep->flood_control = flood_control;
8064 zvni_vtep_install(zvni, zvtep);
8065 }
8066 } else {
8067 zvtep = zvni_vtep_add(zvni, &vtep_ip, flood_control);
8068 if (zvtep)
8069 zvni_vtep_install(zvni, zvtep);
8070 else
8071 flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
8072 "Failed to add remote VTEP, VNI %u zvni %p",
8073 vni, zvni);
8074 }
8075 }
8076
8077 stream_failure:
8078 return;
8079 }
8080
8081 /*
8082 * Add/Del gateway macip to evpn
8083 * g/w can be:
8084 * 1. SVI interface on a vlan aware bridge
8085 * 2. SVI interface on a vlan unaware bridge
8086 * 3. vrr interface (MACVLAN) associated to a SVI
8087 * We advertise macip routes for an interface if it is associated to VxLan vlan
8088 */
8089 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
8090 int add)
8091 {
8092 struct ipaddr ip;
8093 struct ethaddr macaddr;
8094 zebra_vni_t *zvni = NULL;
8095
8096 memset(&ip, 0, sizeof(struct ipaddr));
8097 memset(&macaddr, 0, sizeof(struct ethaddr));
8098
8099 /* Check if EVPN is enabled. */
8100 if (!is_evpn_enabled())
8101 return 0;
8102
8103 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
8104 struct interface *svi_if =
8105 NULL; /* SVI corresponding to the MACVLAN */
8106 struct zebra_if *ifp_zif =
8107 NULL; /* Zebra daemon specific info for MACVLAN */
8108 struct zebra_if *svi_if_zif =
8109 NULL; /* Zebra daemon specific info for SVI*/
8110
8111 ifp_zif = ifp->info;
8112 if (!ifp_zif)
8113 return -1;
8114
8115 /*
8116 * for a MACVLAN interface the link represents the svi_if
8117 */
8118 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
8119 ifp_zif->link_ifindex);
8120 if (!svi_if) {
8121 zlog_debug("MACVLAN %s(%u) without link information",
8122 ifp->name, ifp->ifindex);
8123 return -1;
8124 }
8125
8126 if (IS_ZEBRA_IF_VLAN(svi_if)) {
8127 /*
8128 * If it is a vlan aware bridge then the link gives the
8129 * bridge information
8130 */
8131 struct interface *svi_if_link = NULL;
8132
8133 svi_if_zif = svi_if->info;
8134 if (svi_if_zif) {
8135 svi_if_link = if_lookup_by_index_per_ns(
8136 zebra_ns_lookup(NS_DEFAULT),
8137 svi_if_zif->link_ifindex);
8138 zvni = zvni_from_svi(svi_if, svi_if_link);
8139 }
8140 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
8141 /*
8142 * If it is a vlan unaware bridge then svi is the bridge
8143 * itself
8144 */
8145 zvni = zvni_from_svi(svi_if, svi_if);
8146 }
8147 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
8148 struct zebra_if *svi_if_zif =
8149 NULL; /* Zebra daemon specific info for SVI */
8150 struct interface *svi_if_link =
8151 NULL; /* link info for the SVI = bridge info */
8152
8153 svi_if_zif = ifp->info;
8154 if (svi_if_zif) {
8155 svi_if_link = if_lookup_by_index_per_ns(
8156 zebra_ns_lookup(NS_DEFAULT),
8157 svi_if_zif->link_ifindex);
8158 if (svi_if_link)
8159 zvni = zvni_from_svi(ifp, svi_if_link);
8160 }
8161 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
8162 zvni = zvni_from_svi(ifp, ifp);
8163 }
8164
8165 if (!zvni)
8166 return 0;
8167
8168 if (!zvni->vxlan_if) {
8169 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
8170 zvni->vni, zvni);
8171 return -1;
8172 }
8173
8174
8175 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
8176
8177 if (p->family == AF_INET) {
8178 ip.ipa_type = IPADDR_V4;
8179 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
8180 sizeof(struct in_addr));
8181 } else if (p->family == AF_INET6) {
8182 ip.ipa_type = IPADDR_V6;
8183 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
8184 sizeof(struct in6_addr));
8185 }
8186
8187
8188 if (add)
8189 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
8190 else
8191 zvni_gw_macip_del(ifp, zvni, &ip);
8192
8193 return 0;
8194 }
8195
8196 /*
8197 * Handle SVI interface going down.
8198 * SVI can be associated to either L3-VNI or L2-VNI.
8199 * For L2-VNI: At this point, this is a NOP since
8200 * the kernel deletes the neighbor entries on this SVI (if any).
8201 * We only need to update the vrf corresponding to zvni.
8202 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
8203 * from bgp
8204 */
8205 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
8206 {
8207 zebra_l3vni_t *zl3vni = NULL;
8208
8209 zl3vni = zl3vni_from_svi(ifp, link_if);
8210 if (zl3vni) {
8211
8212 /* process l3-vni down */
8213 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8214
8215 /* remove association with svi-if */
8216 zl3vni->svi_if = NULL;
8217 } else {
8218 zebra_vni_t *zvni = NULL;
8219
8220 /* since we dont have svi corresponding to zvni, we associate it
8221 * to default vrf. Note: the corresponding neigh entries on the
8222 * SVI would have already been deleted */
8223 zvni = zvni_from_svi(ifp, link_if);
8224 if (zvni) {
8225 zvni->vrf_id = VRF_DEFAULT;
8226
8227 /* update the tenant vrf in BGP */
8228 zvni_send_add_to_client(zvni);
8229 }
8230 }
8231 return 0;
8232 }
8233
8234 /*
8235 * Handle SVI interface coming up.
8236 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
8237 * vxlan intf).
8238 * For L2-VNI: we need to install any remote neighbors entried (used for
8239 * apr-suppression)
8240 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
8241 */
8242 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
8243 {
8244 zebra_vni_t *zvni = NULL;
8245 zebra_l3vni_t *zl3vni = NULL;
8246
8247 zl3vni = zl3vni_from_svi(ifp, link_if);
8248 if (zl3vni) {
8249
8250 /* associate with svi */
8251 zl3vni->svi_if = ifp;
8252
8253 /* process oper-up */
8254 if (is_l3vni_oper_up(zl3vni))
8255 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8256 } else {
8257
8258 /* process SVI up for l2-vni */
8259 struct neigh_walk_ctx n_wctx;
8260
8261 zvni = zvni_from_svi(ifp, link_if);
8262 if (!zvni)
8263 return 0;
8264
8265 if (!zvni->vxlan_if) {
8266 zlog_debug(
8267 "VNI %u hash %p doesn't have intf upon SVI up",
8268 zvni->vni, zvni);
8269 return -1;
8270 }
8271
8272 if (IS_ZEBRA_DEBUG_VXLAN)
8273 zlog_debug(
8274 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
8275 ifp->name, ifp->ifindex, zvni->vni,
8276 vrf_id_to_name(ifp->vrf_id));
8277
8278 /* update the vrf information for l2-vni and inform bgp */
8279 zvni->vrf_id = ifp->vrf_id;
8280 zvni_send_add_to_client(zvni);
8281
8282 /* Install any remote neighbors for this VNI. */
8283 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
8284 n_wctx.zvni = zvni;
8285 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
8286 &n_wctx);
8287 }
8288
8289 return 0;
8290 }
8291
8292 /*
8293 * Handle VxLAN interface down
8294 */
8295 int zebra_vxlan_if_down(struct interface *ifp)
8296 {
8297 vni_t vni;
8298 struct zebra_if *zif = NULL;
8299 struct zebra_l2info_vxlan *vxl = NULL;
8300 zebra_l3vni_t *zl3vni = NULL;
8301 zebra_vni_t *zvni;
8302
8303 /* Check if EVPN is enabled. */
8304 if (!is_evpn_enabled())
8305 return 0;
8306
8307 zif = ifp->info;
8308 assert(zif);
8309 vxl = &zif->l2info.vxl;
8310 vni = vxl->vni;
8311
8312 zl3vni = zl3vni_lookup(vni);
8313 if (zl3vni) {
8314 /* process-if-down for l3-vni */
8315 if (IS_ZEBRA_DEBUG_VXLAN)
8316 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
8317 ifp->ifindex, vni);
8318
8319 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8320 } else {
8321 /* process if-down for l2-vni */
8322 if (IS_ZEBRA_DEBUG_VXLAN)
8323 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
8324 ifp->ifindex, vni);
8325
8326 /* Locate hash entry; it is expected to exist. */
8327 zvni = zvni_lookup(vni);
8328 if (!zvni) {
8329 zlog_debug(
8330 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
8331 ifp->name, ifp->ifindex, vni);
8332 return -1;
8333 }
8334
8335 assert(zvni->vxlan_if == ifp);
8336
8337 /* Delete this VNI from BGP. */
8338 zvni_send_del_to_client(zvni->vni);
8339
8340 /* Free up all neighbors and MACs, if any. */
8341 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
8342 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
8343
8344 /* Free up all remote VTEPs, if any. */
8345 zvni_vtep_del_all(zvni, 1);
8346 }
8347 return 0;
8348 }
8349
8350 /*
8351 * Handle VxLAN interface up - update BGP if required.
8352 */
8353 int zebra_vxlan_if_up(struct interface *ifp)
8354 {
8355 vni_t vni;
8356 struct zebra_if *zif = NULL;
8357 struct zebra_l2info_vxlan *vxl = NULL;
8358 zebra_vni_t *zvni = NULL;
8359 zebra_l3vni_t *zl3vni = NULL;
8360
8361 /* Check if EVPN is enabled. */
8362 if (!is_evpn_enabled())
8363 return 0;
8364
8365 zif = ifp->info;
8366 assert(zif);
8367 vxl = &zif->l2info.vxl;
8368 vni = vxl->vni;
8369
8370 zl3vni = zl3vni_lookup(vni);
8371 if (zl3vni) {
8372
8373 if (IS_ZEBRA_DEBUG_VXLAN)
8374 zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp->name,
8375 ifp->ifindex, vni);
8376
8377 /* we need to associate with SVI, if any, we can associate with
8378 * svi-if only after association with vxlan-intf is complete
8379 */
8380 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8381
8382 if (is_l3vni_oper_up(zl3vni))
8383 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8384 } else {
8385 /* Handle L2-VNI add */
8386 struct interface *vlan_if = NULL;
8387
8388 if (IS_ZEBRA_DEBUG_VXLAN)
8389 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
8390 ifp->ifindex, vni);
8391
8392 /* Locate hash entry; it is expected to exist. */
8393 zvni = zvni_lookup(vni);
8394 if (!zvni) {
8395 zlog_debug(
8396 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
8397 ifp->name, ifp->ifindex, vni);
8398 return -1;
8399 }
8400
8401 assert(zvni->vxlan_if == ifp);
8402 vlan_if = zvni_map_to_svi(vxl->access_vlan,
8403 zif->brslave_info.br_if);
8404 if (vlan_if) {
8405 zvni->vrf_id = vlan_if->vrf_id;
8406 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
8407 if (zl3vni)
8408 listnode_add_sort(zl3vni->l2vnis, zvni);
8409 }
8410
8411 /* If part of a bridge, inform BGP about this VNI. */
8412 /* Also, read and populate local MACs and neighbors. */
8413 if (zif->brslave_info.br_if) {
8414 zvni_send_add_to_client(zvni);
8415 zvni_read_mac_neigh(zvni, ifp);
8416 }
8417 }
8418
8419 return 0;
8420 }
8421
8422 /*
8423 * Handle VxLAN interface delete. Locate and remove entry in hash table
8424 * and update BGP, if required.
8425 */
8426 int zebra_vxlan_if_del(struct interface *ifp)
8427 {
8428 vni_t vni;
8429 struct zebra_if *zif = NULL;
8430 struct zebra_l2info_vxlan *vxl = NULL;
8431 zebra_vni_t *zvni = NULL;
8432 zebra_l3vni_t *zl3vni = NULL;
8433
8434 /* Check if EVPN is enabled. */
8435 if (!is_evpn_enabled())
8436 return 0;
8437
8438 zif = ifp->info;
8439 assert(zif);
8440 vxl = &zif->l2info.vxl;
8441 vni = vxl->vni;
8442
8443 zl3vni = zl3vni_lookup(vni);
8444 if (zl3vni) {
8445
8446 if (IS_ZEBRA_DEBUG_VXLAN)
8447 zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
8448 ifp->ifindex);
8449
8450 /* process oper-down for l3-vni */
8451 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8452
8453 /* remove the association with vxlan_if */
8454 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
8455 zl3vni->vxlan_if = NULL;
8456 } else {
8457
8458 /* process if-del for l2-vni*/
8459 if (IS_ZEBRA_DEBUG_VXLAN)
8460 zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name,
8461 ifp->ifindex);
8462
8463 /* Locate hash entry; it is expected to exist. */
8464 zvni = zvni_lookup(vni);
8465 if (!zvni) {
8466 zlog_debug(
8467 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
8468 ifp->name, ifp->ifindex, vni);
8469 return 0;
8470 }
8471
8472 /* remove from l3-vni list */
8473 zl3vni = zl3vni_from_vrf(zvni->vrf_id);
8474 if (zl3vni)
8475 listnode_delete(zl3vni->l2vnis, zvni);
8476
8477 /* Delete VNI from BGP. */
8478 zvni_send_del_to_client(zvni->vni);
8479
8480 /* Free up all neighbors and MAC, if any. */
8481 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
8482 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
8483
8484 /* Free up all remote VTEPs, if any. */
8485 zvni_vtep_del_all(zvni, 0);
8486
8487 /* Delete the hash entry. */
8488 if (zvni_del(zvni)) {
8489 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
8490 "Failed to del VNI hash %p, IF %s(%u) VNI %u",
8491 zvni, ifp->name, ifp->ifindex, zvni->vni);
8492 return -1;
8493 }
8494 }
8495 return 0;
8496 }
8497
8498 /*
8499 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
8500 */
8501 int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
8502 {
8503 vni_t vni;
8504 struct zebra_if *zif = NULL;
8505 struct zebra_l2info_vxlan *vxl = NULL;
8506 zebra_vni_t *zvni = NULL;
8507 zebra_l3vni_t *zl3vni = NULL;
8508
8509 /* Check if EVPN is enabled. */
8510 if (!is_evpn_enabled())
8511 return 0;
8512
8513 zif = ifp->info;
8514 assert(zif);
8515 vxl = &zif->l2info.vxl;
8516 vni = vxl->vni;
8517
8518 zl3vni = zl3vni_lookup(vni);
8519 if (zl3vni) {
8520
8521 if (IS_ZEBRA_DEBUG_VXLAN)
8522 zlog_debug(
8523 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
8524 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
8525 inet_ntoa(vxl->vtep_ip),
8526 zif->brslave_info.bridge_ifindex, chgflags);
8527
8528 /* Removed from bridge? Cleanup and return */
8529 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
8530 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
8531 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8532 return 0;
8533 }
8534
8535 /* access-vlan change - process oper down, associate with new
8536 * svi_if and then process oper up again
8537 */
8538 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
8539 if (if_is_operative(ifp)) {
8540 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8541 zl3vni->svi_if = NULL;
8542 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8543 zl3vni->local_vtep_ip = vxl->vtep_ip;
8544 if (is_l3vni_oper_up(zl3vni))
8545 zebra_vxlan_process_l3vni_oper_up(
8546 zl3vni);
8547 }
8548 }
8549
8550 /*
8551 * local-ip change - process oper down, associate with new
8552 * local-ip and then process oper up again
8553 */
8554 if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) {
8555 if (if_is_operative(ifp)) {
8556 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8557 zl3vni->local_vtep_ip = vxl->vtep_ip;
8558 if (is_l3vni_oper_up(zl3vni))
8559 zebra_vxlan_process_l3vni_oper_up(
8560 zl3vni);
8561 }
8562 }
8563
8564 /* Update local tunnel IP. */
8565 zl3vni->local_vtep_ip = vxl->vtep_ip;
8566
8567 /* if we have a valid new master, process l3-vni oper up */
8568 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
8569 if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni))
8570 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8571 }
8572 } else {
8573
8574 /* Update VNI hash. */
8575 zvni = zvni_lookup(vni);
8576 if (!zvni) {
8577 zlog_debug(
8578 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
8579 ifp->name, ifp->ifindex, vni);
8580 return -1;
8581 }
8582
8583 if (IS_ZEBRA_DEBUG_VXLAN)
8584 zlog_debug(
8585 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
8586 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
8587 inet_ntoa(vxl->vtep_ip),
8588 zif->brslave_info.bridge_ifindex, chgflags);
8589
8590 /* Removed from bridge? Cleanup and return */
8591 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
8592 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
8593 /* Delete from client, remove all remote VTEPs */
8594 /* Also, free up all MACs and neighbors. */
8595 zvni_send_del_to_client(zvni->vni);
8596 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
8597 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
8598 zvni_vtep_del_all(zvni, 1);
8599 return 0;
8600 }
8601
8602 /* Handle other changes. */
8603 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
8604 /* Remove all existing local neigh and MACs for this VNI
8605 * (including from BGP)
8606 */
8607 zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
8608 zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
8609 }
8610
8611 if (zvni->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
8612 zvni->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
8613 zebra_vxlan_sg_deref(zvni->local_vtep_ip,
8614 zvni->mcast_grp);
8615 zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
8616 zvni->local_vtep_ip = vxl->vtep_ip;
8617 zvni->mcast_grp = vxl->mcast_grp;
8618 }
8619 zvni->vxlan_if = ifp;
8620
8621 /* Take further actions needed.
8622 * Note that if we are here, there is a change of interest.
8623 */
8624 /* If down or not mapped to a bridge, we're done. */
8625 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8626 return 0;
8627
8628 /* Inform BGP, if there is a change of interest. */
8629 if (chgflags
8630 & (ZEBRA_VXLIF_MASTER_CHANGE |
8631 ZEBRA_VXLIF_LOCAL_IP_CHANGE |
8632 ZEBRA_VXLIF_MCAST_GRP_CHANGE))
8633 zvni_send_add_to_client(zvni);
8634
8635 /* If there is a valid new master or a VLAN mapping change,
8636 * read and populate local MACs and neighbors.
8637 * Also, reinstall any remote MACs and neighbors
8638 * for this VNI (based on new VLAN).
8639 */
8640 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
8641 zvni_read_mac_neigh(zvni, ifp);
8642 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
8643 struct mac_walk_ctx m_wctx;
8644 struct neigh_walk_ctx n_wctx;
8645
8646 zvni_read_mac_neigh(zvni, ifp);
8647
8648 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
8649 m_wctx.zvni = zvni;
8650 hash_iterate(zvni->mac_table, zvni_install_mac_hash,
8651 &m_wctx);
8652
8653 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
8654 n_wctx.zvni = zvni;
8655 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
8656 &n_wctx);
8657 }
8658 }
8659
8660 return 0;
8661 }
8662
8663 /*
8664 * Handle VxLAN interface add.
8665 */
8666 int zebra_vxlan_if_add(struct interface *ifp)
8667 {
8668 vni_t vni;
8669 struct zebra_if *zif = NULL;
8670 struct zebra_l2info_vxlan *vxl = NULL;
8671 zebra_vni_t *zvni = NULL;
8672 zebra_l3vni_t *zl3vni = NULL;
8673
8674 /* Check if EVPN is enabled. */
8675 if (!is_evpn_enabled())
8676 return 0;
8677
8678 zif = ifp->info;
8679 assert(zif);
8680 vxl = &zif->l2info.vxl;
8681 vni = vxl->vni;
8682
8683 zl3vni = zl3vni_lookup(vni);
8684 if (zl3vni) {
8685
8686 /* process if-add for l3-vni*/
8687 if (IS_ZEBRA_DEBUG_VXLAN)
8688 zlog_debug(
8689 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
8690 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
8691 inet_ntoa(vxl->vtep_ip),
8692 zif->brslave_info.bridge_ifindex);
8693
8694 /* associate with vxlan_if */
8695 zl3vni->local_vtep_ip = vxl->vtep_ip;
8696 zl3vni->vxlan_if = ifp;
8697
8698 /* Associate with SVI, if any. We can associate with svi-if only
8699 * after association with vxlan_if is complete */
8700 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8701
8702 if (is_l3vni_oper_up(zl3vni))
8703 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8704 } else {
8705
8706 /* process if-add for l2-vni */
8707 struct interface *vlan_if = NULL;
8708
8709 /* Create or update VNI hash. */
8710 zvni = zvni_lookup(vni);
8711 if (!zvni) {
8712 zvni = zvni_add(vni);
8713 if (!zvni) {
8714 flog_err(
8715 EC_ZEBRA_VNI_ADD_FAILED,
8716 "Failed to add VNI hash, IF %s(%u) VNI %u",
8717 ifp->name, ifp->ifindex, vni);
8718 return -1;
8719 }
8720 }
8721
8722 if (zvni->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
8723 zvni->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
8724 zebra_vxlan_sg_deref(zvni->local_vtep_ip,
8725 zvni->mcast_grp);
8726 zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
8727 zvni->local_vtep_ip = vxl->vtep_ip;
8728 zvni->mcast_grp = vxl->mcast_grp;
8729 }
8730 zvni->vxlan_if = ifp;
8731 vlan_if = zvni_map_to_svi(vxl->access_vlan,
8732 zif->brslave_info.br_if);
8733 if (vlan_if) {
8734 zvni->vrf_id = vlan_if->vrf_id;
8735 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
8736 if (zl3vni)
8737 listnode_add_sort(zl3vni->l2vnis, zvni);
8738 }
8739
8740 if (IS_ZEBRA_DEBUG_VXLAN) {
8741 char addr_buf1[INET_ADDRSTRLEN];
8742 char addr_buf2[INET_ADDRSTRLEN];
8743
8744 inet_ntop(AF_INET, &vxl->vtep_ip,
8745 addr_buf1, INET_ADDRSTRLEN);
8746 inet_ntop(AF_INET, &vxl->mcast_grp,
8747 addr_buf2, INET_ADDRSTRLEN);
8748
8749 zlog_debug(
8750 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s mcast_grp %s master %u",
8751 vni,
8752 vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
8753 : VRF_DEFAULT_NAME,
8754 ifp->name, ifp->ifindex, vxl->access_vlan,
8755 addr_buf1, addr_buf2,
8756 zif->brslave_info.bridge_ifindex);
8757 }
8758
8759 /* If down or not mapped to a bridge, we're done. */
8760 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
8761 return 0;
8762
8763 /* Inform BGP */
8764 zvni_send_add_to_client(zvni);
8765
8766 /* Read and populate local MACs and neighbors */
8767 zvni_read_mac_neigh(zvni, ifp);
8768 }
8769
8770 return 0;
8771 }
8772
8773 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
8774 char *err, int err_str_sz, int filter,
8775 int add)
8776 {
8777 zebra_l3vni_t *zl3vni = NULL;
8778 struct zebra_vrf *zvrf_evpn = NULL;
8779
8780 zvrf_evpn = zebra_vrf_get_evpn();
8781 if (!zvrf_evpn)
8782 return -1;
8783
8784 if (IS_ZEBRA_DEBUG_VXLAN)
8785 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
8786 add ? "ADD" : "DEL");
8787
8788 if (add) {
8789
8790 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
8791
8792 /* check if the vni is already present under zvrf */
8793 if (zvrf->l3vni) {
8794 snprintf(err, err_str_sz,
8795 "VNI is already configured under the vrf");
8796 return -1;
8797 }
8798
8799 /* check if this VNI is already present in the system */
8800 zl3vni = zl3vni_lookup(vni);
8801 if (zl3vni) {
8802 snprintf(err, err_str_sz,
8803 "VNI is already configured as L3-VNI");
8804 return -1;
8805 }
8806
8807 /* add the L3-VNI to the global table */
8808 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
8809 if (!zl3vni) {
8810 snprintf(err, err_str_sz, "Could not add L3-VNI");
8811 return -1;
8812 }
8813
8814 /* associate the vrf with vni */
8815 zvrf->l3vni = vni;
8816
8817 /* set the filter in l3vni to denote if we are using l3vni only
8818 * for prefix routes
8819 */
8820 if (filter)
8821 SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
8822
8823 /* associate with vxlan-intf;
8824 * we need to associate with the vxlan-intf first
8825 */
8826 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
8827
8828 /* associate with corresponding SVI interface, we can associate
8829 * with svi-if only after vxlan interface association is
8830 * complete
8831 */
8832 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
8833
8834 /* formulate l2vni list */
8835 hash_iterate(zvrf_evpn->vni_table, zvni_add_to_l3vni_list,
8836 zl3vni);
8837
8838 if (is_l3vni_oper_up(zl3vni))
8839 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8840
8841 } else {
8842 zl3vni = zl3vni_lookup(vni);
8843 if (!zl3vni) {
8844 snprintf(err, err_str_sz, "VNI doesn't exist");
8845 return -1;
8846 }
8847
8848 if (zvrf->l3vni != vni) {
8849 snprintf(err, err_str_sz,
8850 "VNI %d doesn't exist in VRF: %s",
8851 vni, zvrf->vrf->name);
8852 return -1;
8853 }
8854
8855 if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
8856 snprintf(err, ERR_STR_SZ,
8857 "prefix-routes-only is not set for the vni");
8858 return -1;
8859 }
8860
8861 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8862
8863 /* delete and uninstall all rmacs */
8864 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
8865 zl3vni);
8866
8867 /* delete and uninstall all next-hops */
8868 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
8869 zl3vni);
8870
8871 zvrf->l3vni = 0;
8872 zl3vni_del(zl3vni);
8873
8874 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
8875 }
8876 return 0;
8877 }
8878
8879 int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
8880 {
8881 zebra_l3vni_t *zl3vni = NULL;
8882
8883 if (zvrf->l3vni)
8884 zl3vni = zl3vni_lookup(zvrf->l3vni);
8885 if (!zl3vni)
8886 return 0;
8887
8888 zl3vni->vrf_id = zvrf_id(zvrf);
8889 if (is_l3vni_oper_up(zl3vni))
8890 zebra_vxlan_process_l3vni_oper_up(zl3vni);
8891 return 0;
8892 }
8893
8894 int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
8895 {
8896 zebra_l3vni_t *zl3vni = NULL;
8897
8898 if (zvrf->l3vni)
8899 zl3vni = zl3vni_lookup(zvrf->l3vni);
8900 if (!zl3vni)
8901 return 0;
8902
8903 zl3vni->vrf_id = VRF_UNKNOWN;
8904 zebra_vxlan_process_l3vni_oper_down(zl3vni);
8905 return 0;
8906 }
8907
8908 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
8909 {
8910 zebra_l3vni_t *zl3vni = NULL;
8911 vni_t vni;
8912
8913 if (zvrf->l3vni)
8914 zl3vni = zl3vni_lookup(zvrf->l3vni);
8915 if (!zl3vni)
8916 return 0;
8917
8918 vni = zl3vni->vni;
8919 zl3vni_del(zl3vni);
8920 zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
8921
8922 return 0;
8923 }
8924
8925 /*
8926 * Handle message from client to specify the flooding mechanism for
8927 * BUM packets. The default is to do head-end (ingress) replication
8928 * and the other supported option is to disable it. This applies to
8929 * all BUM traffic and disabling it applies to both the transmit and
8930 * receive direction.
8931 */
8932 void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
8933 {
8934 struct stream *s;
8935 enum vxlan_flood_control flood_ctrl;
8936
8937 if (!EVPN_ENABLED(zvrf)) {
8938 zlog_err("EVPN flood control for non-EVPN VRF %u",
8939 zvrf_id(zvrf));
8940 return;
8941 }
8942
8943 s = msg;
8944 STREAM_GETC(s, flood_ctrl);
8945
8946 if (IS_ZEBRA_DEBUG_VXLAN)
8947 zlog_debug("EVPN flood control %u, currently %u",
8948 flood_ctrl, zvrf->vxlan_flood_ctrl);
8949
8950 if (zvrf->vxlan_flood_ctrl == flood_ctrl)
8951 return;
8952
8953 zvrf->vxlan_flood_ctrl = flood_ctrl;
8954
8955 /* Install or uninstall flood entries corresponding to
8956 * remote VTEPs.
8957 */
8958 hash_iterate(zvrf->vni_table, zvni_handle_flooding_remote_vteps,
8959 zvrf);
8960
8961 stream_failure:
8962 return;
8963 }
8964
8965 /*
8966 * Handle message from client to enable/disable advertisement of svi macip
8967 * routes
8968 */
8969 void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
8970 {
8971 struct stream *s;
8972 int advertise;
8973 vni_t vni = 0;
8974 zebra_vni_t *zvni = NULL;
8975 struct interface *ifp = NULL;
8976
8977 if (!EVPN_ENABLED(zvrf)) {
8978 zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
8979 zvrf_id(zvrf));
8980 return;
8981 }
8982
8983 s = msg;
8984 STREAM_GETC(s, advertise);
8985 STREAM_GETL(s, vni);
8986
8987 if (!vni) {
8988 if (IS_ZEBRA_DEBUG_VXLAN)
8989 zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
8990 advertise ? "enabled" : "disabled",
8991 advertise_gw_macip_enabled(NULL)
8992 ? "enabled"
8993 : "disabled");
8994
8995 if (zvrf->advertise_svi_macip == advertise)
8996 return;
8997
8998
8999 if (advertise) {
9000 zvrf->advertise_svi_macip = advertise;
9001 hash_iterate(zvrf->vni_table,
9002 zvni_gw_macip_add_for_vni_hash, NULL);
9003 } else {
9004 hash_iterate(zvrf->vni_table,
9005 zvni_svi_macip_del_for_vni_hash, NULL);
9006 zvrf->advertise_svi_macip = advertise;
9007 }
9008
9009 } else {
9010 struct zebra_if *zif = NULL;
9011 struct zebra_l2info_vxlan zl2_info;
9012 struct interface *vlan_if = NULL;
9013
9014 zvni = zvni_lookup(vni);
9015 if (!zvni)
9016 return;
9017
9018 if (IS_ZEBRA_DEBUG_VXLAN)
9019 zlog_debug(
9020 "EVPN SVI macip Adv %s on VNI %d , currently %s",
9021 advertise ? "enabled" : "disabled", vni,
9022 advertise_svi_macip_enabled(zvni)
9023 ? "enabled"
9024 : "disabled");
9025
9026 if (zvni->advertise_svi_macip == advertise)
9027 return;
9028
9029 ifp = zvni->vxlan_if;
9030 if (!ifp)
9031 return;
9032
9033 zif = ifp->info;
9034
9035 /* If down or not mapped to a bridge, we're done. */
9036 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
9037 return;
9038
9039 zl2_info = zif->l2info.vxl;
9040
9041 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
9042 zif->brslave_info.br_if);
9043 if (!vlan_if)
9044 return;
9045
9046 if (advertise) {
9047 zvni->advertise_svi_macip = advertise;
9048 /* Add primary SVI MAC-IP */
9049 zvni_add_macip_for_intf(vlan_if, zvni);
9050 } else {
9051 /* Del primary MAC-IP */
9052 zvni_del_macip_for_intf(vlan_if, zvni);
9053 zvni->advertise_svi_macip = advertise;
9054 }
9055 }
9056
9057 stream_failure:
9058 return;
9059 }
9060
9061 /*
9062 * Handle message from client to enable/disable advertisement of g/w macip
9063 * routes
9064 */
9065 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
9066 {
9067 struct stream *s;
9068 int advertise;
9069 vni_t vni = 0;
9070 zebra_vni_t *zvni = NULL;
9071 struct interface *ifp = NULL;
9072 struct zebra_if *zif = NULL;
9073 struct zebra_l2info_vxlan zl2_info;
9074 struct interface *vlan_if = NULL;
9075
9076 if (!EVPN_ENABLED(zvrf)) {
9077 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
9078 zvrf_id(zvrf));
9079 return;
9080 }
9081
9082 s = msg;
9083 STREAM_GETC(s, advertise);
9084 vni = stream_get3(s);
9085
9086 zvni = zvni_lookup(vni);
9087 if (!zvni)
9088 return;
9089
9090 if (zvni->advertise_subnet == advertise)
9091 return;
9092
9093 if (IS_ZEBRA_DEBUG_VXLAN)
9094 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
9095 advertise ? "enabled" : "disabled", vni,
9096 zvni->advertise_subnet ? "enabled" : "disabled");
9097
9098
9099 zvni->advertise_subnet = advertise;
9100
9101 ifp = zvni->vxlan_if;
9102 if (!ifp)
9103 return;
9104
9105 zif = ifp->info;
9106
9107 /* If down or not mapped to a bridge, we're done. */
9108 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
9109 return;
9110
9111 zl2_info = zif->l2info.vxl;
9112
9113 vlan_if =
9114 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
9115 if (!vlan_if)
9116 return;
9117
9118 if (zvni->advertise_subnet)
9119 zvni_advertise_subnet(zvni, vlan_if, 1);
9120 else
9121 zvni_advertise_subnet(zvni, vlan_if, 0);
9122
9123 stream_failure:
9124 return;
9125 }
9126
9127 /*
9128 * Handle message from client to enable/disable advertisement of g/w macip
9129 * routes
9130 */
9131 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
9132 {
9133 struct stream *s;
9134 int advertise;
9135 vni_t vni = 0;
9136 zebra_vni_t *zvni = NULL;
9137 struct interface *ifp = NULL;
9138
9139 if (!EVPN_ENABLED(zvrf)) {
9140 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
9141 zvrf_id(zvrf));
9142 return;
9143 }
9144
9145 s = msg;
9146 STREAM_GETC(s, advertise);
9147 STREAM_GETL(s, vni);
9148
9149 if (!vni) {
9150 if (IS_ZEBRA_DEBUG_VXLAN)
9151 zlog_debug("EVPN gateway macip Adv %s, currently %s",
9152 advertise ? "enabled" : "disabled",
9153 advertise_gw_macip_enabled(NULL)
9154 ? "enabled"
9155 : "disabled");
9156
9157 if (zvrf->advertise_gw_macip == advertise)
9158 return;
9159
9160 zvrf->advertise_gw_macip = advertise;
9161
9162 if (advertise_gw_macip_enabled(zvni))
9163 hash_iterate(zvrf->vni_table,
9164 zvni_gw_macip_add_for_vni_hash, NULL);
9165 else
9166 hash_iterate(zvrf->vni_table,
9167 zvni_gw_macip_del_for_vni_hash, NULL);
9168
9169 } else {
9170 struct zebra_if *zif = NULL;
9171 struct zebra_l2info_vxlan zl2_info;
9172 struct interface *vlan_if = NULL;
9173 struct interface *vrr_if = NULL;
9174
9175 zvni = zvni_lookup(vni);
9176 if (!zvni)
9177 return;
9178
9179 if (IS_ZEBRA_DEBUG_VXLAN)
9180 zlog_debug(
9181 "EVPN gateway macip Adv %s on VNI %d , currently %s",
9182 advertise ? "enabled" : "disabled", vni,
9183 advertise_gw_macip_enabled(zvni) ? "enabled"
9184 : "disabled");
9185
9186 if (zvni->advertise_gw_macip == advertise)
9187 return;
9188
9189 zvni->advertise_gw_macip = advertise;
9190
9191 ifp = zvni->vxlan_if;
9192 if (!ifp)
9193 return;
9194
9195 zif = ifp->info;
9196
9197 /* If down or not mapped to a bridge, we're done. */
9198 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
9199 return;
9200
9201 zl2_info = zif->l2info.vxl;
9202
9203 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
9204 zif->brslave_info.br_if);
9205 if (!vlan_if)
9206 return;
9207
9208 if (advertise_gw_macip_enabled(zvni)) {
9209 /* Add primary SVI MAC-IP */
9210 zvni_add_macip_for_intf(vlan_if, zvni);
9211
9212 /* Add VRR MAC-IP - if any*/
9213 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
9214 if (vrr_if)
9215 zvni_add_macip_for_intf(vrr_if, zvni);
9216 } else {
9217 /* Del primary MAC-IP */
9218 zvni_del_macip_for_intf(vlan_if, zvni);
9219
9220 /* Del VRR MAC-IP - if any*/
9221 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
9222 if (vrr_if)
9223 zvni_del_macip_for_intf(vrr_if, zvni);
9224 }
9225 }
9226
9227 stream_failure:
9228 return;
9229 }
9230
9231
9232 /*
9233 * Handle message from client to learn (or stop learning) about VNIs and MACs.
9234 * When enabled, the VNI hash table will be built and MAC FDB table read;
9235 * when disabled, the entries should be deleted and remote VTEPs and MACs
9236 * uninstalled from the kernel.
9237 * This also informs the setting for BUM handling at the time this change
9238 * occurs; it is relevant only when specifying "learn".
9239 */
9240 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
9241 {
9242 struct stream *s = NULL;
9243 int advertise = 0;
9244 enum vxlan_flood_control flood_ctrl;
9245
9246 /* Mismatch between EVPN VRF and current VRF (should be prevented by
9247 * bgpd's cli) */
9248 if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
9249 return;
9250
9251 s = msg;
9252 STREAM_GETC(s, advertise);
9253 STREAM_GETC(s, flood_ctrl);
9254
9255 if (IS_ZEBRA_DEBUG_VXLAN)
9256 zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
9257 zvrf_name(zvrf), zvrf_id(zvrf),
9258 advertise ? "enabled" : "disabled",
9259 is_evpn_enabled() ? "enabled" : "disabled",
9260 flood_ctrl);
9261
9262 if (zvrf->advertise_all_vni == advertise)
9263 return;
9264
9265 zvrf->advertise_all_vni = advertise;
9266 if (EVPN_ENABLED(zvrf)) {
9267 zrouter.evpn_vrf = zvrf;
9268
9269 /* Note BUM handling */
9270 zvrf->vxlan_flood_ctrl = flood_ctrl;
9271
9272 /* Build VNI hash table and inform BGP. */
9273 zvni_build_hash_table();
9274
9275 /* Add all SVI (L3 GW) MACs to BGP*/
9276 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
9277 NULL);
9278
9279 /* Read the MAC FDB */
9280 macfdb_read(zvrf->zns);
9281
9282 /* Read neighbors */
9283 neigh_read(zvrf->zns);
9284 } else {
9285 /* Cleanup VTEPs for all VNIs - uninstall from
9286 * kernel and free entries.
9287 */
9288 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
9289
9290 /* cleanup all l3vnis */
9291 hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
9292
9293 /* Mark as "no EVPN VRF" */
9294 zrouter.evpn_vrf = NULL;
9295 }
9296
9297 stream_failure:
9298 return;
9299 }
9300
9301 /*
9302 * Allocate VNI hash table for this VRF and do other initialization.
9303 * NOTE: Currently supported only for default VRF.
9304 */
9305 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
9306 {
9307 if (!zvrf)
9308 return;
9309 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
9310 "Zebra VRF VNI Table");
9311 zvrf->vxlan_sg_table = hash_create(zebra_vxlan_sg_hash_key_make,
9312 zebra_vxlan_sg_hash_eq, "Zebra VxLAN SG Table");
9313 }
9314
9315 /* Cleanup VNI info, but don't free the table. */
9316 void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
9317 {
9318 if (!zvrf)
9319 return;
9320 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
9321 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_cleanup, NULL);
9322 }
9323
9324 /* Close all VNI handling */
9325 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
9326 {
9327 if (!zvrf)
9328 return;
9329 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
9330 hash_free(zvrf->vni_table);
9331 }
9332
9333 /* init the l3vni table */
9334 void zebra_vxlan_init(void)
9335 {
9336 zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
9337 "Zebra VRF L3 VNI table");
9338 zrouter.evpn_vrf = NULL;
9339 }
9340
9341 /* free l3vni table */
9342 void zebra_vxlan_disable(void)
9343 {
9344 hash_free(zrouter.l3vni_table);
9345 }
9346
9347 /* get the l3vni svi ifindex */
9348 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
9349 {
9350 zebra_l3vni_t *zl3vni = NULL;
9351
9352 zl3vni = zl3vni_from_vrf(vrf_id);
9353 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
9354 return 0;
9355
9356 return zl3vni->svi_if->ifindex;
9357 }
9358
9359 static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
9360 {
9361 struct zebra_vrf *zvrf = NULL;
9362 zebra_neigh_t *nbr = NULL;
9363 zebra_vni_t *zvni = NULL;
9364 char buf1[INET6_ADDRSTRLEN];
9365 char buf2[ETHER_ADDR_STRLEN];
9366
9367 nbr = THREAD_ARG(t);
9368
9369 /* since this is asynchronous we need sanity checks*/
9370 zvrf = vrf_info_lookup(nbr->zvni->vrf_id);
9371 if (!zvrf)
9372 return 0;
9373
9374 zvni = zvni_lookup(nbr->zvni->vni);
9375 if (!zvni)
9376 return 0;
9377
9378 nbr = zvni_neigh_lookup(zvni, &nbr->ip);
9379 if (!nbr)
9380 return 0;
9381
9382 if (IS_ZEBRA_DEBUG_VXLAN)
9383 zlog_debug("%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
9384 __PRETTY_FUNCTION__,
9385 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)),
9386 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
9387 nbr->flags,
9388 nbr->dad_count, zvni->vni);
9389
9390 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
9391 nbr->dad_count = 0;
9392 nbr->detect_start_time.tv_sec = 0;
9393 nbr->detect_start_time.tv_usec = 0;
9394 nbr->dad_dup_detect_time = 0;
9395 nbr->dad_ip_auto_recovery_timer = NULL;
9396 ZEBRA_NEIGH_SET_ACTIVE(nbr);
9397
9398 /* Send to BGP */
9399 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
9400 zvni_neigh_send_add_to_client(zvni->vni, &nbr->ip, &nbr->emac,
9401 nbr->flags, nbr->loc_seq);
9402 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
9403 zvni_neigh_install(zvni, nbr);
9404 }
9405
9406 return 0;
9407 }
9408
9409 static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
9410 {
9411 struct zebra_vrf *zvrf = NULL;
9412 zebra_mac_t *mac = NULL;
9413 zebra_vni_t *zvni = NULL;
9414 struct listnode *node = NULL;
9415 zebra_neigh_t *nbr = NULL;
9416 char buf[ETHER_ADDR_STRLEN];
9417
9418 mac = THREAD_ARG(t);
9419
9420 /* since this is asynchronous we need sanity checks*/
9421 zvrf = vrf_info_lookup(mac->zvni->vrf_id);
9422 if (!zvrf)
9423 return 0;
9424
9425 zvni = zvni_lookup(mac->zvni->vni);
9426 if (!zvni)
9427 return 0;
9428
9429 mac = zvni_mac_lookup(zvni, &mac->macaddr);
9430 if (!mac)
9431 return 0;
9432
9433 if (IS_ZEBRA_DEBUG_VXLAN)
9434 zlog_debug("%s: duplicate addr mac %s flags 0x%x learn count %u host count %u auto recovery expired",
9435 __PRETTY_FUNCTION__,
9436 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
9437 mac->flags,
9438 mac->dad_count,
9439 listcount(mac->neigh_list));
9440
9441 /* Remove all IPs as duplicate associcated with this MAC */
9442 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
9443 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
9444 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
9445 ZEBRA_NEIGH_SET_INACTIVE(nbr);
9446 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
9447 zvni_neigh_install(zvni, nbr);
9448 }
9449
9450 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
9451 nbr->dad_count = 0;
9452 nbr->detect_start_time.tv_sec = 0;
9453 nbr->dad_dup_detect_time = 0;
9454 }
9455
9456 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
9457 mac->dad_count = 0;
9458 mac->detect_start_time.tv_sec = 0;
9459 mac->detect_start_time.tv_usec = 0;
9460 mac->dad_dup_detect_time = 0;
9461 mac->dad_mac_auto_recovery_timer = NULL;
9462
9463 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
9464 /* Inform to BGP */
9465 if (zvni_mac_send_add_to_client(zvni->vni, &mac->macaddr,
9466 mac->flags, mac->loc_seq))
9467 return -1;
9468
9469 /* Process all neighbors associated with this MAC. */
9470 zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
9471
9472 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
9473 zvni_process_neigh_on_remote_mac_add(zvni, mac);
9474
9475 /* Install the entry. */
9476 zvni_mac_install(zvni, mac);
9477 }
9478
9479 return 0;
9480 }
9481
9482 /************************** vxlan SG cache management ************************/
9483 /* Inform PIM about the mcast group */
9484 static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
9485 struct prefix_sg *sg,
9486 char *sg_str, uint16_t cmd)
9487 {
9488 struct zserv *client = NULL;
9489 struct stream *s = NULL;
9490
9491 client = zserv_find_client(ZEBRA_ROUTE_PIM, 0);
9492 if (!client)
9493 return 0;
9494
9495 if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
9496 return 0;
9497
9498 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
9499
9500 zclient_create_header(s, cmd, VRF_DEFAULT);
9501 stream_putl(s, IPV4_MAX_BYTELEN);
9502 stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
9503 stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
9504
9505 /* Write packet size. */
9506 stream_putw_at(s, 0, stream_get_endp(s));
9507
9508 if (IS_ZEBRA_DEBUG_VXLAN)
9509 zlog_debug(
9510 "Send %s %s to %s",
9511 (cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", sg_str,
9512 zebra_route_string(client->proto));
9513
9514 if (cmd == ZEBRA_VXLAN_SG_ADD)
9515 client->vxlan_sg_add_cnt++;
9516 else
9517 client->vxlan_sg_del_cnt++;
9518
9519 return zserv_send_message(client, s);
9520 }
9521
9522 static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
9523 {
9524 const zebra_vxlan_sg_t *vxlan_sg = p;
9525
9526 return (jhash_2words(vxlan_sg->sg.src.s_addr,
9527 vxlan_sg->sg.grp.s_addr, 0));
9528 }
9529
9530 static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
9531 {
9532 const zebra_vxlan_sg_t *sg1 = p1;
9533 const zebra_vxlan_sg_t *sg2 = p2;
9534
9535 return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
9536 && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
9537 }
9538
9539 static zebra_vxlan_sg_t *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
9540 struct prefix_sg *sg)
9541 {
9542 zebra_vxlan_sg_t *vxlan_sg;
9543
9544 vxlan_sg = XCALLOC(MTYPE_ZVXLAN_SG, sizeof(*vxlan_sg));
9545
9546 vxlan_sg->zvrf = zvrf;
9547 vxlan_sg->sg = *sg;
9548 prefix_sg2str(sg, vxlan_sg->sg_str);
9549
9550 vxlan_sg = hash_get(zvrf->vxlan_sg_table, vxlan_sg, hash_alloc_intern);
9551
9552 if (IS_ZEBRA_DEBUG_VXLAN)
9553 zlog_debug("vxlan SG %s created", vxlan_sg->sg_str);
9554
9555 return vxlan_sg;
9556 }
9557
9558 static zebra_vxlan_sg_t *zebra_vxlan_sg_find(struct zebra_vrf *zvrf,
9559 struct prefix_sg *sg)
9560 {
9561 zebra_vxlan_sg_t lookup;
9562
9563 lookup.sg = *sg;
9564 return hash_lookup(zvrf->vxlan_sg_table, &lookup);
9565 }
9566
9567 static zebra_vxlan_sg_t *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
9568 struct prefix_sg *sg)
9569 {
9570 zebra_vxlan_sg_t *vxlan_sg;
9571 zebra_vxlan_sg_t *parent = NULL;
9572 struct in_addr sip;
9573
9574 vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
9575 if (vxlan_sg)
9576 return vxlan_sg;
9577
9578 /* create a *G entry for every BUM group implicitly -
9579 * 1. The SG entry is used by pimd to setup the vxlan-origination-mroute
9580 * 2. the XG entry is used by pimd to setup the
9581 * vxlan-termination-mroute
9582 */
9583 if (sg->src.s_addr) {
9584 memset(&sip, 0, sizeof(sip));
9585 parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
9586 if (!parent)
9587 return NULL;
9588 }
9589
9590 vxlan_sg = zebra_vxlan_sg_new(zvrf, sg);
9591 if (!vxlan_sg) {
9592 if (parent)
9593 zebra_vxlan_sg_do_deref(zvrf, sip, sg->grp);
9594 return vxlan_sg;
9595 }
9596
9597 zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
9598 ZEBRA_VXLAN_SG_ADD);
9599
9600 return vxlan_sg;
9601 }
9602
9603 static void zebra_vxlan_sg_del(zebra_vxlan_sg_t *vxlan_sg)
9604 {
9605 struct in_addr sip;
9606 struct zebra_vrf *zvrf;
9607
9608 zvrf = vrf_info_lookup(VRF_DEFAULT);
9609 if (!zvrf)
9610 return;
9611
9612 /* On SG entry deletion remove the reference to its parent XG
9613 * entry
9614 */
9615 if (vxlan_sg->sg.src.s_addr) {
9616 memset(&sip, 0, sizeof(sip));
9617 zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
9618 }
9619
9620 zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
9621 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
9622
9623 hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
9624
9625 if (IS_ZEBRA_DEBUG_VXLAN)
9626 zlog_debug("VXLAN SG %s deleted", vxlan_sg->sg_str);
9627
9628 XFREE(MTYPE_ZVXLAN_SG, vxlan_sg);
9629 }
9630
9631 static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
9632 struct in_addr sip, struct in_addr mcast_grp)
9633 {
9634 zebra_vxlan_sg_t *vxlan_sg;
9635 struct prefix_sg sg;
9636
9637 sg.family = AF_INET;
9638 sg.prefixlen = IPV4_MAX_BYTELEN;
9639 sg.src = sip;
9640 sg.grp = mcast_grp;
9641 vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
9642 if (!vxlan_sg)
9643 return;
9644
9645 if (vxlan_sg->ref_cnt)
9646 --vxlan_sg->ref_cnt;
9647
9648 if (!vxlan_sg->ref_cnt)
9649 zebra_vxlan_sg_del(vxlan_sg);
9650 }
9651
9652 static zebra_vxlan_sg_t *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
9653 struct in_addr sip, struct in_addr mcast_grp)
9654 {
9655 zebra_vxlan_sg_t *vxlan_sg;
9656 struct prefix_sg sg;
9657
9658 sg.family = AF_INET;
9659 sg.prefixlen = IPV4_MAX_BYTELEN;
9660 sg.src = sip;
9661 sg.grp = mcast_grp;
9662 vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
9663 if (vxlan_sg)
9664 ++vxlan_sg->ref_cnt;
9665
9666 return vxlan_sg;
9667 }
9668
9669 static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
9670 struct in_addr mcast_grp)
9671 {
9672 struct zebra_vrf *zvrf;
9673
9674 if (!local_vtep_ip.s_addr || !mcast_grp.s_addr)
9675 return;
9676
9677 zvrf = vrf_info_lookup(VRF_DEFAULT);
9678 if (!zvrf)
9679 return;
9680
9681 zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
9682 }
9683
9684 static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
9685 struct in_addr mcast_grp)
9686 {
9687 struct zebra_vrf *zvrf;
9688
9689 if (!local_vtep_ip.s_addr || !mcast_grp.s_addr)
9690 return;
9691
9692 zvrf = vrf_info_lookup(VRF_DEFAULT);
9693 if (!zvrf)
9694 return;
9695 zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
9696 }
9697
9698 static void zebra_vxlan_sg_cleanup(struct hash_backet *backet, void *arg)
9699 {
9700 zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data;
9701
9702 zebra_vxlan_sg_del(vxlan_sg);
9703 }
9704
9705 static void zebra_vxlan_sg_replay_send(struct hash_backet *backet, void *arg)
9706 {
9707 zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data;
9708
9709 zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
9710 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
9711 }
9712
9713 /* Handle message from client to replay vxlan SG entries */
9714 void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
9715 {
9716 if (IS_ZEBRA_DEBUG_VXLAN)
9717 zlog_debug("VxLAN SG updates to PIM, start");
9718
9719 SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
9720
9721 if (!EVPN_ENABLED(zvrf)) {
9722 zlog_debug("VxLAN SG replay request on unexpected vrf %d",
9723 zvrf->vrf->vrf_id);
9724 return;
9725 }
9726
9727 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
9728 }
9729
9730 /************************** EVPN BGP config management ************************/
9731 /* Notify Local MACs to the clienti, skips GW MAC */
9732 static void zvni_send_mac_hash_entry_to_client(struct hash_bucket *bucket,
9733 void *arg)
9734 {
9735 struct mac_walk_ctx *wctx = arg;
9736 zebra_mac_t *zmac = bucket->data;
9737
9738 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_DEF_GW))
9739 return;
9740
9741 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL))
9742 zvni_mac_send_add_to_client(wctx->zvni->vni, &zmac->macaddr,
9743 zmac->flags, zmac->loc_seq);
9744 }
9745
9746 /* Iterator to Notify Local MACs of a L2VNI */
9747 static void zvni_send_mac_to_client(zebra_vni_t *zvni)
9748 {
9749 struct mac_walk_ctx wctx;
9750
9751 if (!zvni->mac_table)
9752 return;
9753
9754 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
9755 wctx.zvni = zvni;
9756
9757 hash_iterate(zvni->mac_table, zvni_send_mac_hash_entry_to_client,
9758 &wctx);
9759 }
9760
9761 /* Notify Neighbor entries to the Client, skips the GW entry */
9762 static void zvni_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
9763 void *arg)
9764 {
9765 struct mac_walk_ctx *wctx = arg;
9766 zebra_neigh_t *zn = bucket->data;
9767 zebra_mac_t *zmac = NULL;
9768
9769 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
9770 return;
9771
9772 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL) &&
9773 IS_ZEBRA_NEIGH_ACTIVE(zn)) {
9774 zmac = zvni_mac_lookup(wctx->zvni, &zn->emac);
9775 if (!zmac)
9776 return;
9777
9778 zvni_neigh_send_add_to_client(wctx->zvni->vni, &zn->ip,
9779 &zn->emac, zn->flags,
9780 zn->loc_seq);
9781 }
9782 }
9783
9784 /* Iterator of a specific L2VNI */
9785 static void zvni_send_neigh_to_client(zebra_vni_t *zvni)
9786 {
9787 struct neigh_walk_ctx wctx;
9788
9789 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
9790 wctx.zvni = zvni;
9791
9792 hash_iterate(zvni->neigh_table, zvni_send_neigh_hash_entry_to_client,
9793 &wctx);
9794 }
9795
9796 static void zvni_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt)
9797 {
9798 zebra_vni_t *zvni = NULL;
9799
9800 zvni = (zebra_vni_t *)bucket->data;
9801 zvni->advertise_gw_macip = 0;
9802 zvni->advertise_svi_macip = 0;
9803 zvni->advertise_subnet = 0;
9804
9805 zvni_neigh_del_all(zvni, 1, 0,
9806 DEL_REMOTE_NEIGH | DEL_REMOTE_NEIGH_FROM_VTEP);
9807 zvni_mac_del_all(zvni, 1, 0,
9808 DEL_REMOTE_MAC | DEL_REMOTE_MAC_FROM_VTEP);
9809 zvni_vtep_del_all(zvni, 1);
9810 }
9811
9812 /* Cleanup EVPN configuration of a specific VRF */
9813 static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
9814 {
9815 zebra_l3vni_t *zl3vni = NULL;
9816
9817 zvrf->advertise_all_vni = 0;
9818 zvrf->advertise_gw_macip = 0;
9819 zvrf->advertise_svi_macip = 0;
9820 zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
9821
9822 hash_iterate(zvrf->vni_table, zvni_evpn_cfg_cleanup, NULL);
9823
9824 if (zvrf->l3vni)
9825 zl3vni = zl3vni_lookup(zvrf->l3vni);
9826 if (zl3vni) {
9827 /* delete and uninstall all rmacs */
9828 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
9829 zl3vni);
9830 /* delete and uninstall all next-hops */
9831 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
9832 zl3vni);
9833 }
9834 }
9835
9836 /* Cleanup BGP EVPN configuration upon client disconnect */
9837 static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
9838 {
9839 struct vrf *vrf;
9840 struct zebra_vrf *zvrf;
9841
9842 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
9843 zvrf = vrf->info;
9844 if (zvrf)
9845 zebra_evpn_vrf_cfg_cleanup(zvrf);
9846 }
9847
9848 return 0;
9849 }
9850
9851 static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
9852 {
9853 struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
9854
9855 if (CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
9856 if (IS_ZEBRA_DEBUG_VXLAN)
9857 zlog_debug("VxLAN SG updates to PIM, stop");
9858 UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
9859 }
9860
9861 return 0;
9862 }
9863
9864 static int zebra_evpn_cfg_clean_up(struct zserv *client)
9865 {
9866 if (client->proto == ZEBRA_ROUTE_BGP)
9867 return zebra_evpn_bgp_cfg_clean_up(client);
9868
9869 if (client->proto == ZEBRA_ROUTE_PIM)
9870 return zebra_evpn_pim_cfg_clean_up(client);
9871
9872 return 0;
9873 }
9874
9875 /* Cleanup BGP EVPN configuration upon client disconnect */
9876 extern void zebra_evpn_init(void)
9877 {
9878 hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
9879 }