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