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