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