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