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