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