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