]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
zebra: clone zebra_vxlan.c to zebra_evpn_mac.c
[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_evpn_mh.h"
54 #include "zebra/zebra_router.h"
55 //commment for cloning
56
57 DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
58 DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN, "EVPN hash");
59 DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
60 DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN_VTEP, "EVPN remote VTEP/PTUN");
61 DEFINE_MTYPE_STATIC(ZEBRA, MAC, "EVPN MAC");
62 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "EVPN Neighbor");
63 DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group");
64
65 DEFINE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni,
66 bool delete, const char *reason), (rmac, zl3vni, delete, reason))
67
68 /* definitions */
69 /* PMSI strings. */
70 #define VXLAN_FLOOD_STR_NO_INFO "-"
71 #define VXLAN_FLOOD_STR_DEFAULT VXLAN_FLOOD_STR_NO_INFO
72 static const struct message zvtep_flood_str[] = {
73 {VXLAN_FLOOD_DISABLED, VXLAN_FLOOD_STR_NO_INFO},
74 {VXLAN_FLOOD_PIM_SM, "PIM-SM"},
75 {VXLAN_FLOOD_HEAD_END_REPL, "HER"},
76 {0}
77 };
78
79 /* static function declarations */
80 static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
81 uint16_t cmd);
82 static void zevpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
83 static void zevpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt);
84 static void zevpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt);
85 static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
86 void **args);
87 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
88 json_object *json);
89 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
90 json_object *json);
91 static void zevpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
92 static void zevpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt);
93 static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt);
94 static void zevpn_print(zebra_evpn_t *zevpn, void **ctxt);
95 static void zevpn_print_hash(struct hash_bucket *bucket, void *ctxt[]);
96
97 static int zevpn_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
98 struct ipaddr *ip, uint8_t flags,
99 uint32_t seq, int state,
100 struct zebra_evpn_es *es,
101 uint16_t cmd);
102 static unsigned int neigh_hash_keymake(const void *p);
103 static void *zevpn_neigh_alloc(void *p);
104 static zebra_neigh_t *zevpn_neigh_add(zebra_evpn_t *zevpn, struct ipaddr *ip,
105 struct ethaddr *mac, zebra_mac_t *zmac,
106 uint32_t n_flags);
107 static int zevpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n);
108 static void zevpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client,
109 uint32_t flags);
110 static zebra_neigh_t *zevpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip);
111 static int zevpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
112 struct ethaddr *mac, zebra_mac_t *zmac,
113 uint32_t flags, uint32_t seq);
114 static int zevpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
115 struct ethaddr *mac,
116 uint32_t flags, int state, bool force);
117 static int zevpn_rem_neigh_install(zebra_evpn_t *zevpn,
118 zebra_neigh_t *n, bool was_static);
119 static int zevpn_neigh_uninstall(zebra_evpn_t *zevpn, zebra_neigh_t *n);
120 static int zevpn_neigh_probe(zebra_evpn_t *zevpn, zebra_neigh_t *n);
121 static zebra_evpn_t *zevpn_from_svi(struct interface *ifp,
122 struct interface *br_if);
123 static struct interface *zevpn_map_to_svi(vlanid_t vid, struct interface *br_if);
124 static struct interface *zevpn_map_to_macvlan(struct interface *br_if,
125 struct interface *svi_if);
126
127 /* l3-vni next-hop neigh related APIs */
128 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
129 const struct ipaddr *ip);
130 static void *zl3vni_nh_alloc(void *p);
131 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
132 const struct ipaddr *vtep_ip,
133 const struct ethaddr *rmac);
134 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
135 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
136 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
137
138 /* l3-vni rmac related APIs */
139 static void zl3vni_print_rmac_hash(struct hash_bucket *, void *);
140 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
141 const struct ethaddr *rmac);
142 static void *zl3vni_rmac_alloc(void *p);
143 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
144 const struct ethaddr *rmac);
145 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
146 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
147 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
148
149 /* l3-vni related APIs*/
150 static void *zl3vni_alloc(void *p);
151 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
152 static int zl3vni_del(zebra_l3vni_t *zl3vni);
153 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni);
154 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni);
155
156 static unsigned int mac_hash_keymake(const void *p);
157 static bool mac_cmp(const void *p1, const void *p2);
158 static void *zevpn_mac_alloc(void *p);
159 static zebra_mac_t *zevpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr);
160 static int zevpn_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac);
161 static void zevpn_mac_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client,
162 uint32_t flags);
163 static zebra_mac_t *zevpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *macaddr);
164 static int zevpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
165 uint32_t flags, uint32_t seq, struct zebra_evpn_es *es);
166 static int zevpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
167 uint32_t flags, bool force);
168 static zebra_evpn_t *zevpn_map_vlan(struct interface *ifp,
169 struct interface *br_if, vlanid_t vid);
170 static int zevpn_rem_mac_install(zebra_evpn_t *zevpn,
171 zebra_mac_t *mac, bool was_static);
172 static int zevpn_rem_mac_uninstall(zebra_evpn_t *zevpn, zebra_mac_t *mac);
173 static void zevpn_install_mac_hash(struct hash_bucket *bucket, void *ctxt);
174
175 static unsigned int evpn_hash_keymake(const void *p);
176 static void *zevpn_alloc(void *p);
177 static zebra_evpn_t *zevpn_add(vni_t vni);
178 static int zevpn_del(zebra_evpn_t *zevpn);
179 static int zevpn_send_add_to_client(zebra_evpn_t *zevpn);
180 static int zevpn_send_del_to_client(zebra_evpn_t *zevpn);
181 static void zevpn_build_hash_table(void);
182 static int zevpn_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
183 static zebra_vtep_t *zevpn_vtep_find(zebra_evpn_t *zevpn, struct in_addr *vtep_ip);
184 static zebra_vtep_t *zevpn_vtep_add(zebra_evpn_t *zevpn, struct in_addr *vtep_ip,
185 int flood_control);
186 static int zevpn_vtep_del(zebra_evpn_t *zevpn, zebra_vtep_t *zvtep);
187 static int zevpn_vtep_del_all(zebra_evpn_t *zevpn, int uninstall);
188 static int zevpn_vtep_install(zebra_evpn_t *zevpn, zebra_vtep_t *zvtep);
189 static int zevpn_vtep_uninstall(zebra_evpn_t *zevpn, struct in_addr *vtep_ip);
190 static int zevpn_del_macip_for_intf(struct interface *ifp, zebra_evpn_t *zevpn);
191 static int zevpn_add_macip_for_intf(struct interface *ifp, zebra_evpn_t *zevpn);
192 static int zevpn_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
193 struct ethaddr *macaddr, struct ipaddr *ip);
194 static int zevpn_gw_macip_del(struct interface *ifp, zebra_evpn_t *zevpn,
195 struct ipaddr *ip);
196 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
197 static int advertise_gw_macip_enabled(zebra_evpn_t *zevpn);
198 static int advertise_svi_macip_enabled(zebra_evpn_t *zevpn);
199 static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
200 zebra_mac_t *old_zmac,
201 zebra_mac_t *new_zmac,
202 zebra_neigh_t *nbr);
203 static int remote_neigh_count(zebra_mac_t *zmac);
204 static void zevpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac);
205 static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t);
206 static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t);
207 static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
208 zebra_neigh_t *nbr,
209 struct in_addr vtep_ip,
210 bool do_dad,
211 bool *is_dup_detect,
212 bool is_local);
213 static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
214 zebra_mac_t *mac,
215 struct in_addr vtep_ip,
216 bool do_dad,
217 bool *is_dup_detect,
218 bool is_local);
219 static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
220 static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
221 static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
222 struct in_addr sip, struct in_addr mcast_grp);
223 static zebra_vxlan_sg_t *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf,
224 struct in_addr sip, struct in_addr mcast_grp);
225 static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
226 struct in_addr mcast_grp);
227 static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
228 struct in_addr mcast_grp);
229 static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg);
230
231 static void zevpn_send_mac_to_client(zebra_evpn_t *zvn);
232 static void zevpn_send_neigh_to_client(zebra_evpn_t *zevpn);
233 static void zebra_vxlan_rem_mac_del(zebra_evpn_t *zevpn,
234 zebra_mac_t *zmac);
235 static inline void zebra_vxlan_mac_stop_hold_timer(zebra_mac_t *mac);
236 static inline bool zebra_vxlan_mac_is_static(zebra_mac_t *mac);
237 static void zebra_vxlan_local_neigh_ref_mac(zebra_neigh_t *n,
238 struct ethaddr *macaddr, zebra_mac_t *mac,
239 bool send_mac_update);
240 static void zebra_vxlan_local_neigh_deref_mac(zebra_neigh_t *n,
241 bool send_mac_update);
242 static inline bool zebra_vxlan_neigh_is_ready_for_bgp(zebra_neigh_t *n);
243 static inline bool zebra_vxlan_neigh_clear_sync_info(zebra_neigh_t *n);
244 static void zebra_vxlan_sync_neigh_dp_install(zebra_neigh_t *n,
245 bool set_inactive, bool force_clear_static, const char *caller);
246 static inline bool zebra_vxlan_neigh_is_static(zebra_neigh_t *neigh);
247 static void zebra_vxlan_neigh_send_add_del_to_client(zebra_neigh_t *n,
248 bool old_bgp_ready, bool new_bgp_ready);
249
250 /* Private functions */
251 static int host_rb_entry_compare(const struct host_rb_entry *hle1,
252 const struct host_rb_entry *hle2)
253 {
254 if (hle1->p.family < hle2->p.family)
255 return -1;
256
257 if (hle1->p.family > hle2->p.family)
258 return 1;
259
260 if (hle1->p.prefixlen < hle2->p.prefixlen)
261 return -1;
262
263 if (hle1->p.prefixlen > hle2->p.prefixlen)
264 return 1;
265
266 if (hle1->p.family == AF_INET) {
267 if (hle1->p.u.prefix4.s_addr < hle2->p.u.prefix4.s_addr)
268 return -1;
269
270 if (hle1->p.u.prefix4.s_addr > hle2->p.u.prefix4.s_addr)
271 return 1;
272
273 return 0;
274 } else if (hle1->p.family == AF_INET6) {
275 return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
276 IPV6_MAX_BYTELEN);
277 } else {
278 zlog_debug("%s: Unexpected family type: %d", __func__,
279 hle1->p.family);
280 return 0;
281 }
282 }
283 RB_GENERATE(host_rb_tree_entry, host_rb_entry, hl_entry, host_rb_entry_compare);
284
285 static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe)
286 {
287 struct host_rb_entry *hle;
288 uint32_t count = 0;
289
290 RB_FOREACH (hle, host_rb_tree_entry, hrbe)
291 count++;
292
293 return count;
294 }
295
296 /*
297 * Return number of valid MACs in an EVPN's MAC hash table - all
298 * remote MACs and non-internal (auto) local MACs count.
299 */
300 static uint32_t num_valid_macs(zebra_evpn_t *zevpn)
301 {
302 unsigned int i;
303 uint32_t num_macs = 0;
304 struct hash *hash;
305 struct hash_bucket *hb;
306 zebra_mac_t *mac;
307
308 hash = zevpn->mac_table;
309 if (!hash)
310 return num_macs;
311 for (i = 0; i < hash->size; i++) {
312 for (hb = hash->index[i]; hb; hb = hb->next) {
313 mac = (zebra_mac_t *)hb->data;
314 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
315 || CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
316 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
317 num_macs++;
318 }
319 }
320
321 return num_macs;
322 }
323
324 static uint32_t num_dup_detected_macs(zebra_evpn_t *zevpn)
325 {
326 unsigned int i;
327 uint32_t num_macs = 0;
328 struct hash *hash;
329 struct hash_bucket *hb;
330 zebra_mac_t *mac;
331
332 hash = zevpn->mac_table;
333 if (!hash)
334 return num_macs;
335 for (i = 0; i < hash->size; i++) {
336 for (hb = hash->index[i]; hb; hb = hb->next) {
337 mac = (zebra_mac_t *)hb->data;
338 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
339 num_macs++;
340 }
341 }
342
343 return num_macs;
344 }
345
346 static uint32_t num_dup_detected_neighs(zebra_evpn_t *zevpn)
347 {
348 unsigned int i;
349 uint32_t num_neighs = 0;
350 struct hash *hash;
351 struct hash_bucket *hb;
352 zebra_neigh_t *nbr;
353
354 hash = zevpn->neigh_table;
355 if (!hash)
356 return num_neighs;
357 for (i = 0; i < hash->size; i++) {
358 for (hb = hash->index[i]; hb; hb = hb->next) {
359 nbr = (zebra_neigh_t *)hb->data;
360 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
361 num_neighs++;
362 }
363 }
364
365 return num_neighs;
366 }
367
368 static int advertise_gw_macip_enabled(zebra_evpn_t *zevpn)
369 {
370 struct zebra_vrf *zvrf;
371
372 zvrf = zebra_vrf_get_evpn();
373 if (zvrf && zvrf->advertise_gw_macip)
374 return 1;
375
376 if (zevpn && zevpn->advertise_gw_macip)
377 return 1;
378
379 return 0;
380 }
381
382 static int advertise_svi_macip_enabled(zebra_evpn_t *zevpn)
383 {
384 struct zebra_vrf *zvrf;
385
386 zvrf = zebra_vrf_get_evpn();
387 if (zvrf && zvrf->advertise_svi_macip)
388 return 1;
389
390 if (zevpn && zevpn->advertise_svi_macip)
391 return 1;
392
393 return 0;
394 }
395
396 /* As part Duplicate Address Detection (DAD) for IP mobility
397 * MAC binding changes, ensure to inherit duplicate flag
398 * from MAC.
399 */
400 static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
401 zebra_mac_t *old_zmac,
402 zebra_mac_t *new_zmac,
403 zebra_neigh_t *nbr)
404 {
405 bool is_old_mac_dup = false;
406 bool is_new_mac_dup = false;
407
408 if (!zvrf->dup_addr_detect)
409 return 0;
410 /* Check old or new MAC is detected as duplicate
411 * mark this neigh as duplicate
412 */
413 if (old_zmac)
414 is_old_mac_dup = CHECK_FLAG(old_zmac->flags,
415 ZEBRA_MAC_DUPLICATE);
416 if (new_zmac)
417 is_new_mac_dup = CHECK_FLAG(new_zmac->flags,
418 ZEBRA_MAC_DUPLICATE);
419 /* Old and/or new MAC can be in duplicate state,
420 * based on that IP/Neigh Inherits the flag.
421 * If New MAC is marked duplicate, inherit to the IP.
422 * If old MAC is duplicate but new MAC is not, clear
423 * duplicate flag for IP and reset detection params
424 * and let IP DAD retrigger.
425 */
426 if (is_new_mac_dup && !CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
427 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
428 /* Capture Duplicate detection time */
429 nbr->dad_dup_detect_time = monotime(NULL);
430 /* Mark neigh inactive */
431 ZEBRA_NEIGH_SET_INACTIVE(nbr);
432
433 return 1;
434 } else if (is_old_mac_dup && !is_new_mac_dup) {
435 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
436 nbr->dad_count = 0;
437 nbr->detect_start_time.tv_sec = 0;
438 nbr->detect_start_time.tv_usec = 0;
439 }
440 return 0;
441 }
442
443 static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
444 zebra_mac_t *mac,
445 struct in_addr vtep_ip,
446 bool do_dad,
447 bool *is_dup_detect,
448 bool is_local)
449 {
450 zebra_neigh_t *nbr;
451 struct listnode *node = NULL;
452 struct timeval elapsed = {0, 0};
453 char buf[ETHER_ADDR_STRLEN];
454 char buf1[INET6_ADDRSTRLEN];
455 bool reset_params = false;
456
457 if (!(zvrf->dup_addr_detect && do_dad))
458 return;
459
460 /* MAC is detected as duplicate,
461 * Local MAC event -> hold on advertising to BGP.
462 * Remote MAC event -> hold on installing it.
463 */
464 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
465 if (IS_ZEBRA_DEBUG_VXLAN)
466 zlog_debug(
467 "%s: duplicate addr MAC %s flags 0x%x skip update to client, learn count %u recover time %u",
468 __func__,
469 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
470 mac->flags, mac->dad_count,
471 zvrf->dad_freeze_time);
472
473 /* For duplicate MAC do not update
474 * client but update neigh due to
475 * this MAC update.
476 */
477 if (zvrf->dad_freeze)
478 *is_dup_detect = true;
479
480 return;
481 }
482
483 /* Check if detection time (M-secs) expired.
484 * Reset learn count and detection start time.
485 */
486 monotime_since(&mac->detect_start_time, &elapsed);
487 reset_params = (elapsed.tv_sec > zvrf->dad_time);
488 if (is_local && !reset_params) {
489 /* RFC-7432: A PE/VTEP that detects a MAC mobility
490 * event via LOCAL learning starts an M-second timer.
491 *
492 * NOTE: This is the START of the probe with count is
493 * 0 during LOCAL learn event.
494 * (mac->dad_count == 0 || elapsed.tv_sec >= zvrf->dad_time)
495 */
496 reset_params = !mac->dad_count;
497 }
498
499 if (reset_params) {
500 if (IS_ZEBRA_DEBUG_VXLAN)
501 zlog_debug(
502 "%s: duplicate addr MAC %s flags 0x%x detection time passed, reset learn count %u",
503 __func__,
504 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
505 mac->flags, mac->dad_count);
506
507 mac->dad_count = 0;
508 /* Start dup. addr detection (DAD) start time,
509 * ONLY during LOCAL learn.
510 */
511 if (is_local)
512 monotime(&mac->detect_start_time);
513
514 } else if (!is_local) {
515 /* For REMOTE MAC, increment detection count
516 * ONLY while in probe window, once window passed,
517 * next local learn event should trigger DAD.
518 */
519 mac->dad_count++;
520 }
521
522 /* For LOCAL MAC learn event, once count is reset above via either
523 * initial/start detection time or passed the probe time, the count
524 * needs to be incremented.
525 */
526 if (is_local)
527 mac->dad_count++;
528
529 if (mac->dad_count >= zvrf->dad_max_moves) {
530 flog_warn(EC_ZEBRA_DUP_MAC_DETECTED,
531 "VNI %u: MAC %s detected as duplicate during %s VTEP %s",
532 mac->zevpn->vni,
533 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
534 is_local ? "local update, last" :
535 "remote update, from", inet_ntoa(vtep_ip));
536
537 SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
538
539 /* Capture Duplicate detection time */
540 mac->dad_dup_detect_time = monotime(NULL);
541
542 /* Mark all IPs/Neighs as duplicate
543 * associcated with this MAC
544 */
545 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
546
547 /* Ony Mark IPs which are Local */
548 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
549 continue;
550
551 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
552
553 nbr->dad_dup_detect_time = monotime(NULL);
554
555 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
556 "VNI %u: MAC %s IP %s detected as duplicate during %s update, inherit duplicate from MAC",
557 mac->zevpn->vni,
558 prefix_mac2str(&mac->macaddr,
559 buf, sizeof(buf)),
560 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
561 is_local ? "local" : "remote");
562 }
563
564 /* Start auto recovery timer for this MAC */
565 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
566 if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
567 if (IS_ZEBRA_DEBUG_VXLAN)
568 zlog_debug(
569 "%s: duplicate addr MAC %s flags 0x%x auto recovery time %u start",
570 __func__,
571 prefix_mac2str(&mac->macaddr, buf,
572 sizeof(buf)),
573 mac->flags, zvrf->dad_freeze_time);
574
575 thread_add_timer(zrouter.master,
576 zebra_vxlan_dad_mac_auto_recovery_exp,
577 mac, zvrf->dad_freeze_time,
578 &mac->dad_mac_auto_recovery_timer);
579 }
580
581 /* In case of local update, do not inform to client (BGPd),
582 * upd_neigh for neigh sequence change.
583 */
584 if (zvrf->dad_freeze)
585 *is_dup_detect = true;
586 }
587 }
588
589 static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
590 zebra_neigh_t *nbr,
591 struct in_addr vtep_ip,
592 bool do_dad,
593 bool *is_dup_detect,
594 bool is_local)
595 {
596
597 struct timeval elapsed = {0, 0};
598 char buf[ETHER_ADDR_STRLEN];
599 char buf1[INET6_ADDRSTRLEN];
600 bool reset_params = false;
601
602 if (!zvrf->dup_addr_detect)
603 return;
604
605 /* IP is detected as duplicate or inherit dup
606 * state, hold on to install as remote entry
607 * only if freeze is enabled.
608 */
609 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
610 if (IS_ZEBRA_DEBUG_VXLAN)
611 zlog_debug(
612 "%s: duplicate addr MAC %s IP %s flags 0x%x skip installing, learn count %u recover time %u",
613 __func__,
614 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
615 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
616 nbr->flags, nbr->dad_count,
617 zvrf->dad_freeze_time);
618
619 if (zvrf->dad_freeze)
620 *is_dup_detect = true;
621
622 /* warn-only action, neigh will be installed.
623 * freeze action, it wil not be installed.
624 */
625 return;
626 }
627
628 if (!do_dad)
629 return;
630
631 /* Check if detection time (M-secs) expired.
632 * Reset learn count and detection start time.
633 * During remote mac add, count should already be 1
634 * via local learning.
635 */
636 monotime_since(&nbr->detect_start_time, &elapsed);
637 reset_params = (elapsed.tv_sec > zvrf->dad_time);
638
639 if (is_local && !reset_params) {
640 /* RFC-7432: A PE/VTEP that detects a MAC mobility
641 * event via LOCAL learning starts an M-second timer.
642 *
643 * NOTE: This is the START of the probe with count is
644 * 0 during LOCAL learn event.
645 */
646 reset_params = !nbr->dad_count;
647 }
648
649 if (reset_params) {
650 if (IS_ZEBRA_DEBUG_VXLAN)
651 zlog_debug(
652 "%s: duplicate addr MAC %s IP %s flags 0x%x detection time passed, reset learn count %u",
653 __func__,
654 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
655 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
656 nbr->flags, nbr->dad_count);
657 /* Reset learn count but do not start detection
658 * during REMOTE learn event.
659 */
660 nbr->dad_count = 0;
661 /* Start dup. addr detection (DAD) start time,
662 * ONLY during LOCAL learn.
663 */
664 if (is_local)
665 monotime(&nbr->detect_start_time);
666
667 } else if (!is_local) {
668 /* For REMOTE IP/Neigh, increment detection count
669 * ONLY while in probe window, once window passed,
670 * next local learn event should trigger DAD.
671 */
672 nbr->dad_count++;
673 }
674
675 /* For LOCAL IP/Neigh learn event, once count is reset above via either
676 * initial/start detection time or passed the probe time, the count
677 * needs to be incremented.
678 */
679 if (is_local)
680 nbr->dad_count++;
681
682 if (nbr->dad_count >= zvrf->dad_max_moves) {
683 flog_warn(EC_ZEBRA_DUP_IP_DETECTED,
684 "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s",
685 nbr->zevpn->vni,
686 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
687 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
688 is_local ? "local update, last" :
689 "remote update, from",
690 inet_ntoa(vtep_ip));
691
692 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
693
694 /* Capture Duplicate detection time */
695 nbr->dad_dup_detect_time = monotime(NULL);
696
697 /* Start auto recovery timer for this IP */
698 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
699 if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
700 if (IS_ZEBRA_DEBUG_VXLAN)
701 zlog_debug(
702 "%s: duplicate addr MAC %s IP %s flags 0x%x auto recovery time %u start",
703 __func__,
704 prefix_mac2str(&nbr->emac, buf,
705 sizeof(buf)),
706 ipaddr2str(&nbr->ip, buf1,
707 sizeof(buf1)),
708 nbr->flags, zvrf->dad_freeze_time);
709
710 thread_add_timer(zrouter.master,
711 zebra_vxlan_dad_ip_auto_recovery_exp,
712 nbr, zvrf->dad_freeze_time,
713 &nbr->dad_ip_auto_recovery_timer);
714 }
715 if (zvrf->dad_freeze)
716 *is_dup_detect = true;
717 }
718 }
719
720 /*
721 * Helper function to determine maximum width of neighbor IP address for
722 * display - just because we're dealing with IPv6 addresses that can
723 * widely vary.
724 */
725 static void zevpn_find_neigh_addr_width(struct hash_bucket *bucket, void *ctxt)
726 {
727 zebra_neigh_t *n;
728 char buf[INET6_ADDRSTRLEN];
729 struct neigh_walk_ctx *wctx = ctxt;
730 int width;
731
732 n = (zebra_neigh_t *)bucket->data;
733
734 ipaddr2str(&n->ip, buf, sizeof(buf));
735 width = strlen(buf);
736 if (width > wctx->addr_width)
737 wctx->addr_width = width;
738
739 }
740
741 /*
742 * Print a specific neighbor entry.
743 */
744 static void zevpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
745 {
746 struct vty *vty;
747 char buf1[ETHER_ADDR_STRLEN];
748 char buf2[INET6_ADDRSTRLEN];
749 const char *type_str;
750 const char *state_str;
751 bool flags_present = false;
752 struct zebra_vrf *zvrf = NULL;
753 struct timeval detect_start_time = {0, 0};
754 char timebuf[MONOTIME_STRLEN];
755 char thread_buf[THREAD_TIMER_STRLEN];
756
757 zvrf = zebra_vrf_get_evpn();
758 if (!zvrf)
759 return;
760
761 ipaddr2str(&n->ip, buf2, sizeof(buf2));
762 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
763 type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ?
764 "local" : "remote";
765 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
766 vty = (struct vty *)ctxt;
767 if (json == NULL) {
768 bool sync_info = false;
769
770 vty_out(vty, "IP: %s\n",
771 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
772 vty_out(vty, " Type: %s\n", type_str);
773 vty_out(vty, " State: %s\n", state_str);
774 vty_out(vty, " MAC: %s\n",
775 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
776 vty_out(vty, " Sync-info:");
777 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
778 vty_out(vty, " local-inactive");
779 sync_info = true;
780 }
781 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY)) {
782 vty_out(vty, " peer-proxy");
783 sync_info = true;
784 }
785 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
786 vty_out(vty, " peer-active");
787 sync_info = true;
788 }
789 if (n->hold_timer) {
790 vty_out(vty, " (ht: %s)",
791 thread_timer_to_hhmmss(
792 thread_buf,
793 sizeof(thread_buf),
794 n->hold_timer));
795 sync_info = true;
796 }
797 if (!sync_info)
798 vty_out(vty, " -");
799 vty_out(vty, "\n");
800 } else {
801 json_object_string_add(json, "ip", buf2);
802 json_object_string_add(json, "type", type_str);
803 json_object_string_add(json, "state", state_str);
804 json_object_string_add(json, "mac", buf1);
805 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
806 json_object_boolean_true_add(json,
807 "localInactive");
808 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY))
809 json_object_boolean_true_add(json,
810 "peerProxy");
811 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
812 json_object_boolean_true_add(json,
813 "peerActive");
814 if (n->hold_timer)
815 json_object_string_add(json, "peerActiveHold",
816 thread_timer_to_hhmmss(
817 thread_buf,
818 sizeof(thread_buf),
819 n->hold_timer));
820 }
821 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
822 if (n->mac->es) {
823 if (json)
824 json_object_string_add(json, "remoteEs",
825 n->mac->es->esi_str);
826 else
827 vty_out(vty, " Remote ES: %s\n",
828 n->mac->es->esi_str);
829 } else {
830 if (json)
831 json_object_string_add(json, "remoteVtep",
832 inet_ntoa(n->r_vtep_ip));
833 else
834 vty_out(vty, " Remote VTEP: %s\n",
835 inet_ntoa(n->r_vtep_ip));
836 }
837 }
838 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
839 if (!json) {
840 vty_out(vty, " Flags: Default-gateway");
841 flags_present = true;
842 } else
843 json_object_boolean_true_add(json, "defaultGateway");
844 }
845 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
846 if (!json) {
847 vty_out(vty,
848 flags_present ? " ,Router" : " Flags: Router");
849 flags_present = true;
850 }
851 }
852 if (json == NULL) {
853 if (flags_present)
854 vty_out(vty, "\n");
855 vty_out(vty, " Local Seq: %u Remote Seq: %u\n",
856 n->loc_seq, n->rem_seq);
857
858 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
859 vty_out(vty, " Duplicate, detected at %s",
860 time_to_string(n->dad_dup_detect_time,
861 timebuf));
862 } else if (n->dad_count) {
863 monotime_since(&n->detect_start_time,
864 &detect_start_time);
865 if (detect_start_time.tv_sec <= zvrf->dad_time) {
866 time_to_string(n->detect_start_time.tv_sec,
867 timebuf);
868 vty_out(vty,
869 " Duplicate detection started at %s, detection count %u\n",
870 timebuf, n->dad_count);
871 }
872 }
873 } else {
874 json_object_int_add(json, "localSequence", n->loc_seq);
875 json_object_int_add(json, "remoteSequence", n->rem_seq);
876 json_object_int_add(json, "detectionCount",
877 n->dad_count);
878 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
879 json_object_boolean_true_add(json, "isDuplicate");
880 else
881 json_object_boolean_false_add(json, "isDuplicate");
882
883
884 }
885 }
886
887 static void zevpn_print_neigh_hdr(struct vty *vty,
888 struct neigh_walk_ctx *wctx)
889 {
890 vty_out(vty,
891 "Flags: I=local-inactive, P=peer-active, X=peer-proxy\n");
892 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %s\n",
893 -wctx->addr_width, "Neighbor", "Type", "Flags",
894 "State", "MAC", "Remote ES/VTEP", "Seq #'s");
895 }
896
897 static char *zevpn_print_neigh_flags(zebra_neigh_t *n, char *flags_buf,
898 uint32_t flags_buf_sz)
899 {
900 snprintf(flags_buf, flags_buf_sz, "%s%s%s",
901 (n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE) ?
902 "P" : "",
903 (n->flags & ZEBRA_NEIGH_ES_PEER_PROXY) ?
904 "X" : "",
905 (n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) ?
906 "I" : "");
907
908 return flags_buf;
909 }
910
911 /*
912 * Print neighbor hash entry - called for display of all neighbors.
913 */
914 static void zevpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
915 {
916 struct vty *vty;
917 json_object *json_evpn = NULL, *json_row = NULL;
918 zebra_neigh_t *n;
919 char buf1[ETHER_ADDR_STRLEN];
920 char buf2[INET6_ADDRSTRLEN];
921 struct neigh_walk_ctx *wctx = ctxt;
922 const char *state_str;
923 char flags_buf[6];
924
925 vty = wctx->vty;
926 json_evpn = wctx->json;
927 n = (zebra_neigh_t *)bucket->data;
928
929 if (json_evpn)
930 json_row = json_object_new_object();
931
932 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
933 ipaddr2str(&n->ip, buf2, sizeof(buf2));
934 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
935 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
936 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
937 return;
938
939 if (json_vni == NULL) {
940 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
941 -wctx->addr_width, buf2, "local",
942 zevpn_print_neigh_flags(n, flags_buf,
943 sizeof(flags_buf)), state_str,
944 buf1, "", n->loc_seq, n->rem_seq);
945 } else {
946 json_object_string_add(json_row, "type", "local");
947 json_object_string_add(json_row, "state", state_str);
948 json_object_string_add(json_row, "mac", buf1);
949 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
950 json_object_boolean_true_add(
951 json_row, "defaultGateway");
952 json_object_int_add(json_row, "localSequence",
953 n->loc_seq);
954 json_object_int_add(json_row, "remoteSequence",
955 n->rem_seq);
956 json_object_int_add(json_row, "detectionCount",
957 n->dad_count);
958 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
959 json_object_boolean_true_add(json_row,
960 "isDuplicate");
961 else
962 json_object_boolean_false_add(json_row,
963 "isDuplicate");
964 }
965 wctx->count++;
966 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
967 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
968 !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
969 return;
970
971 if (json_vni == NULL) {
972 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
973 (wctx->count == 0))
974 zevpn_print_neigh_hdr(vty, wctx);
975 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
976 -wctx->addr_width, buf2, "remote",
977 zevpn_print_neigh_flags(n, flags_buf,
978 sizeof(flags_buf)),
979 state_str, buf1,
980 n->mac->es ? n->mac->es->esi_str :
981 inet_ntoa(n->r_vtep_ip),
982 n->loc_seq, n->rem_seq);
983 } else {
984 json_object_string_add(json_row, "type", "remote");
985 json_object_string_add(json_row, "state", state_str);
986 json_object_string_add(json_row, "mac", buf1);
987 if (n->mac->es)
988 json_object_string_add(json_row, "remoteEs",
989 n->mac->es->esi_str);
990 else
991 json_object_string_add(json_row, "remoteVtep",
992 inet_ntoa(n->r_vtep_ip));
993 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
994 json_object_boolean_true_add(json_row,
995 "defaultGateway");
996 json_object_int_add(json_row, "localSequence",
997 n->loc_seq);
998 json_object_int_add(json_row, "remoteSequence",
999 n->rem_seq);
1000 json_object_int_add(json_row, "detectionCount",
1001 n->dad_count);
1002 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1003 json_object_boolean_true_add(json_row,
1004 "isDuplicate");
1005 else
1006 json_object_boolean_false_add(json_row,
1007 "isDuplicate");
1008 }
1009 wctx->count++;
1010 }
1011
1012 if (json_evpn)
1013 json_object_object_add(json_evpn, buf2, json_row);
1014 }
1015
1016 /*
1017 * Print neighbor hash entry in detail - called for display of all neighbors.
1018 */
1019 static void zevpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt)
1020 {
1021 struct vty *vty;
1022 json_object *json_evpn = NULL, *json_row = NULL;
1023 zebra_neigh_t *n;
1024 char buf[INET6_ADDRSTRLEN];
1025 struct neigh_walk_ctx *wctx = ctxt;
1026
1027 vty = wctx->vty;
1028 json_evpn = wctx->json;
1029 n = (zebra_neigh_t *)bucket->data;
1030 if (!n)
1031 return;
1032
1033 ipaddr2str(&n->ip, buf, sizeof(buf));
1034 if (json_evpn)
1035 json_row = json_object_new_object();
1036
1037 zevpn_print_neigh(n, vty, json_row);
1038
1039 if (json_evpn)
1040 json_object_object_add(json_evpn, buf, json_row);
1041 }
1042
1043 /*
1044 * Print neighbors for all EVPN.
1045 */
1046 static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket,
1047 void **args)
1048 {
1049 struct vty *vty;
1050 json_object *json = NULL, *json_evpn = NULL;
1051 zebra_evpn_t *zevpn;
1052 uint32_t num_neigh;
1053 struct neigh_walk_ctx wctx;
1054 char vni_str[VNI_STR_LEN];
1055 uint32_t print_dup;
1056
1057 vty = (struct vty *)args[0];
1058 json = (json_object *)args[1];
1059 print_dup = (uint32_t)(uintptr_t)args[2];
1060
1061 zevpn = (zebra_evpn_t *)bucket->data;
1062
1063 num_neigh = hashcount(zevpn->neigh_table);
1064
1065 if (print_dup)
1066 num_neigh = num_dup_detected_neighs(zevpn);
1067
1068 if (json == NULL) {
1069 vty_out(vty,
1070 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
1071 zevpn->vni, num_neigh);
1072 } else {
1073 json_evpn = json_object_new_object();
1074 json_object_int_add(json_evpn, "numArpNd", num_neigh);
1075 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
1076 }
1077
1078 if (!num_neigh) {
1079 if (json)
1080 json_object_object_add(json, vni_str, json_evpn);
1081 return;
1082 }
1083
1084 /* Since we have IPv6 addresses to deal with which can vary widely in
1085 * size, we try to be a bit more elegant in display by first computing
1086 * the maximum width.
1087 */
1088 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1089 wctx.zevpn = zevpn;
1090 wctx.vty = vty;
1091 wctx.addr_width = 15;
1092 wctx.json = json_evpn;
1093 hash_iterate(zevpn->neigh_table, zevpn_find_neigh_addr_width, &wctx);
1094
1095 if (json == NULL)
1096 zevpn_print_neigh_hdr(vty, &wctx);
1097
1098 if (print_dup)
1099 hash_iterate(zevpn->neigh_table, zevpn_print_dad_neigh_hash,
1100 &wctx);
1101 else
1102 hash_iterate(zevpn->neigh_table, zevpn_print_neigh_hash, &wctx);
1103
1104 if (json)
1105 json_object_object_add(json, vni_str, json_evpn);
1106 }
1107
1108 static void zevpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1109 {
1110 zebra_neigh_t *nbr;
1111
1112 nbr = (zebra_neigh_t *)bucket->data;
1113 if (!nbr)
1114 return;
1115
1116 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
1117 zevpn_print_neigh_hash(bucket, ctxt);
1118 }
1119
1120 static void zevpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
1121 void *ctxt)
1122 {
1123 zebra_neigh_t *nbr;
1124
1125 nbr = (zebra_neigh_t *)bucket->data;
1126 if (!nbr)
1127 return;
1128
1129 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
1130 zevpn_print_neigh_hash_detail(bucket, ctxt);
1131 }
1132
1133 /*
1134 * Print neighbors for all EVPNs in detail.
1135 */
1136 static void zevpn_print_neigh_hash_all_evpn_detail(struct hash_bucket *bucket,
1137 void **args)
1138 {
1139 struct vty *vty;
1140 json_object *json = NULL, *json_evpn = NULL;
1141 zebra_evpn_t *zevpn;
1142 uint32_t num_neigh;
1143 struct neigh_walk_ctx wctx;
1144 char vni_str[VNI_STR_LEN];
1145 uint32_t print_dup;
1146
1147 vty = (struct vty *)args[0];
1148 json = (json_object *)args[1];
1149 print_dup = (uint32_t)(uintptr_t)args[2];
1150
1151 zevpn = (zebra_evpn_t *)bucket->data;
1152 if (!zevpn) {
1153 if (json)
1154 vty_out(vty, "{}\n");
1155 return;
1156 }
1157 num_neigh = hashcount(zevpn->neigh_table);
1158
1159 if (print_dup && num_dup_detected_neighs(zevpn) == 0)
1160 return;
1161
1162 if (json == NULL) {
1163 vty_out(vty,
1164 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
1165 zevpn->vni, num_neigh);
1166 } else {
1167 json_evpn = json_object_new_object();
1168 json_object_int_add(json_evpn, "numArpNd", num_neigh);
1169 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
1170 }
1171 if (!num_neigh) {
1172 if (json)
1173 json_object_object_add(json, vni_str, json_evpn);
1174 return;
1175 }
1176
1177 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1178 wctx.zevpn = zevpn;
1179 wctx.vty = vty;
1180 wctx.addr_width = 15;
1181 wctx.json = json_evpn;
1182
1183 if (print_dup)
1184 hash_iterate(zevpn->neigh_table,
1185 zevpn_print_dad_neigh_hash_detail, &wctx);
1186 else
1187 hash_iterate(zevpn->neigh_table, zevpn_print_neigh_hash_detail,
1188 &wctx);
1189
1190 if (json)
1191 json_object_object_add(json, vni_str, json_evpn);
1192 }
1193
1194 /* print a specific next hop for an l3vni */
1195 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
1196 json_object *json)
1197 {
1198 char buf1[ETHER_ADDR_STRLEN];
1199 char buf2[INET6_ADDRSTRLEN];
1200 json_object *json_hosts = NULL;
1201 struct host_rb_entry *hle;
1202
1203 if (!json) {
1204 vty_out(vty, "Ip: %s\n",
1205 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1206 vty_out(vty, " RMAC: %s\n",
1207 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1208 vty_out(vty, " Refcount: %d\n",
1209 rb_host_count(&n->host_rb));
1210 vty_out(vty, " Prefixes:\n");
1211 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
1212 vty_out(vty, " %s\n",
1213 prefix2str(&hle->p, buf2, sizeof(buf2)));
1214 } else {
1215 json_hosts = json_object_new_array();
1216 json_object_string_add(
1217 json, "ip", ipaddr2str(&(n->ip), buf2, sizeof(buf2)));
1218 json_object_string_add(
1219 json, "routerMac",
1220 prefix_mac2str(&n->emac, buf2, sizeof(buf2)));
1221 json_object_int_add(json, "refCount",
1222 rb_host_count(&n->host_rb));
1223 RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
1224 json_object_array_add(json_hosts,
1225 json_object_new_string(prefix2str(
1226 &hle->p, buf2, sizeof(buf2))));
1227 json_object_object_add(json, "prefixList", json_hosts);
1228 }
1229 }
1230
1231 /* Print a specific RMAC entry */
1232 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
1233 json_object *json)
1234 {
1235 char buf1[ETHER_ADDR_STRLEN];
1236 char buf2[PREFIX_STRLEN];
1237 json_object *json_hosts = NULL;
1238 struct host_rb_entry *hle;
1239
1240 if (!json) {
1241 vty_out(vty, "MAC: %s\n",
1242 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
1243 vty_out(vty, " Remote VTEP: %s\n",
1244 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1245 vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb));
1246 vty_out(vty, " Prefixes:\n");
1247 RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
1248 vty_out(vty, " %s\n",
1249 prefix2str(&hle->p, buf2, sizeof(buf2)));
1250 } else {
1251 json_hosts = json_object_new_array();
1252 json_object_string_add(
1253 json, "routerMac",
1254 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
1255 json_object_string_add(json, "vtepIp",
1256 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1257 json_object_int_add(json, "refCount",
1258 rb_host_count(&zrmac->host_rb));
1259 json_object_int_add(json, "localSequence", zrmac->loc_seq);
1260 json_object_int_add(json, "remoteSequence", zrmac->rem_seq);
1261 RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
1262 json_object_array_add(
1263 json_hosts,
1264 json_object_new_string(prefix2str(
1265 &hle->p, buf2, sizeof(buf2))));
1266 json_object_object_add(json, "prefixList", json_hosts);
1267 }
1268 }
1269
1270 static void
1271 zebra_vxlan_mac_get_access_info(zebra_mac_t *mac,
1272 struct interface **ifpP, vlanid_t *vid)
1273 {
1274 /* if the mac is associated with an ES we must get the access
1275 * info from the ES
1276 */
1277 if (mac->es) {
1278 struct zebra_if *zif;
1279
1280 /* get the access port from the es */
1281 *ifpP = mac->es->zif ? mac->es->zif->ifp : NULL;
1282 /* get the vlan from the EVPN */
1283 if (mac->zevpn->vxlan_if) {
1284 zif = mac->zevpn->vxlan_if->info;
1285 *vid = zif->l2info.vxl.access_vlan;
1286 } else {
1287 *vid = 0;
1288 }
1289 } else {
1290 struct zebra_ns *zns;
1291
1292 *vid = mac->fwd_info.local.vid;
1293 zns = zebra_ns_lookup(NS_DEFAULT);
1294 *ifpP = if_lookup_by_index_per_ns(zns,
1295 mac->fwd_info.local.ifindex);
1296 }
1297 }
1298
1299 /*
1300 * Print a specific MAC entry.
1301 */
1302 static void zevpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
1303 {
1304 struct vty *vty;
1305 zebra_neigh_t *n = NULL;
1306 struct listnode *node = NULL;
1307 char buf1[ETHER_ADDR_STRLEN];
1308 char buf2[INET6_ADDRSTRLEN];
1309 struct zebra_vrf *zvrf;
1310 struct timeval detect_start_time = {0, 0};
1311 char timebuf[MONOTIME_STRLEN];
1312 char thread_buf[THREAD_TIMER_STRLEN];
1313
1314 zvrf = zebra_vrf_get_evpn();
1315 if (!zvrf)
1316 return;
1317
1318 vty = (struct vty *)ctxt;
1319 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1320
1321 if (json) {
1322 json_object *json_mac = json_object_new_object();
1323
1324 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1325 struct interface *ifp;
1326 vlanid_t vid;
1327
1328 zebra_vxlan_mac_get_access_info(mac,
1329 &ifp, &vid);
1330 json_object_string_add(json_mac, "type", "local");
1331 if (ifp) {
1332 json_object_string_add(json_mac,
1333 "intf", ifp->name);
1334 json_object_int_add(json_mac,
1335 "ifindex", ifp->ifindex);
1336 }
1337 if (vid)
1338 json_object_int_add(json_mac, "vlan",
1339 vid);
1340 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1341 json_object_string_add(json_mac, "type", "remote");
1342 json_object_string_add(
1343 json_mac, "remoteVtep",
1344 inet_ntoa(mac->fwd_info.r_vtep_ip));
1345 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
1346 json_object_string_add(json_mac, "type", "auto");
1347
1348 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
1349 json_object_boolean_true_add(json_mac, "stickyMac");
1350
1351 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
1352 json_object_boolean_true_add(json_mac,
1353 "defaultGateway");
1354
1355 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
1356 json_object_boolean_true_add(json_mac,
1357 "remoteGatewayMac");
1358
1359 json_object_int_add(json_mac, "localSequence", mac->loc_seq);
1360 json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
1361
1362 json_object_int_add(json_mac, "detectionCount", mac->dad_count);
1363 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1364 json_object_boolean_true_add(json_mac, "isDuplicate");
1365 else
1366 json_object_boolean_false_add(json_mac, "isDuplicate");
1367
1368 json_object_int_add(json_mac, "syncNeighCount", mac->sync_neigh_cnt);
1369 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE))
1370 json_object_boolean_true_add(json_mac,
1371 "localInactive");
1372 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY))
1373 json_object_boolean_true_add(json_mac,
1374 "peerProxy");
1375 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE))
1376 json_object_boolean_true_add(json_mac,
1377 "peerActive");
1378 if (mac->hold_timer)
1379 json_object_string_add(json_mac, "peerActiveHold",
1380 thread_timer_to_hhmmss(
1381 thread_buf,
1382 sizeof(thread_buf),
1383 mac->hold_timer));
1384 if (mac->es)
1385 json_object_string_add(json_mac, "esi",
1386 mac->es->esi_str);
1387 /* print all the associated neigh */
1388 if (!listcount(mac->neigh_list))
1389 json_object_string_add(json_mac, "neighbors", "none");
1390 else {
1391 json_object *json_active_nbrs = json_object_new_array();
1392 json_object *json_inactive_nbrs =
1393 json_object_new_array();
1394 json_object *json_nbrs = json_object_new_object();
1395
1396 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
1397 if (IS_ZEBRA_NEIGH_ACTIVE(n))
1398 json_object_array_add(
1399 json_active_nbrs,
1400 json_object_new_string(
1401 ipaddr2str(
1402 &n->ip, buf2,
1403 sizeof(buf2))));
1404 else
1405 json_object_array_add(
1406 json_inactive_nbrs,
1407 json_object_new_string(
1408 ipaddr2str(
1409 &n->ip, buf2,
1410 sizeof(buf2))));
1411 }
1412
1413 json_object_object_add(json_nbrs, "active",
1414 json_active_nbrs);
1415 json_object_object_add(json_nbrs, "inactive",
1416 json_inactive_nbrs);
1417 json_object_object_add(json_mac, "neighbors",
1418 json_nbrs);
1419 }
1420
1421 json_object_object_add(json, buf1, json_mac);
1422 } else {
1423 vty_out(vty, "MAC: %s\n", buf1);
1424
1425 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1426 struct interface *ifp;
1427 vlanid_t vid;
1428
1429 zebra_vxlan_mac_get_access_info(mac,
1430 &ifp, &vid);
1431
1432 if (mac->es)
1433 vty_out(vty, " ESI: %s\n", mac->es->esi_str);
1434
1435 if (ifp)
1436 vty_out(vty, " Intf: %s(%u)",
1437 ifp->name, ifp->ifindex);
1438 else
1439 vty_out(vty, " Intf: -");
1440 vty_out(vty, " VLAN: %u", vid);
1441 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1442 if (mac->es)
1443 vty_out(vty, " Remote ES: %s",
1444 mac->es->esi_str);
1445 else
1446 vty_out(vty, " Remote VTEP: %s",
1447 inet_ntoa(mac->fwd_info.r_vtep_ip));
1448 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
1449 vty_out(vty, " Auto Mac ");
1450 }
1451
1452 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
1453 vty_out(vty, " Sticky Mac ");
1454
1455 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
1456 vty_out(vty, " Default-gateway Mac ");
1457
1458 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
1459 vty_out(vty, " Remote-gateway Mac ");
1460
1461 vty_out(vty, "\n");
1462 vty_out(vty, " Sync-info: neigh#: %u", mac->sync_neigh_cnt);
1463 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE))
1464 vty_out(vty, " local-inactive");
1465 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY))
1466 vty_out(vty, " peer-proxy");
1467 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE))
1468 vty_out(vty, " peer-active");
1469 if (mac->hold_timer)
1470 vty_out(vty, " (ht: %s)",
1471 thread_timer_to_hhmmss(
1472 thread_buf,
1473 sizeof(thread_buf),
1474 mac->hold_timer));
1475 vty_out(vty, "\n");
1476 vty_out(vty, " Local Seq: %u Remote Seq: %u",
1477 mac->loc_seq, mac->rem_seq);
1478 vty_out(vty, "\n");
1479
1480 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
1481 vty_out(vty, " Duplicate, detected at %s",
1482 time_to_string(mac->dad_dup_detect_time,
1483 timebuf));
1484 } else if (mac->dad_count) {
1485 monotime_since(&mac->detect_start_time,
1486 &detect_start_time);
1487 if (detect_start_time.tv_sec <= zvrf->dad_time) {
1488 time_to_string(mac->detect_start_time.tv_sec,
1489 timebuf);
1490 vty_out(vty,
1491 " Duplicate detection started at %s, detection count %u\n",
1492 timebuf, mac->dad_count);
1493 }
1494 }
1495
1496 /* print all the associated neigh */
1497 vty_out(vty, " Neighbors:\n");
1498 if (!listcount(mac->neigh_list))
1499 vty_out(vty, " No Neighbors\n");
1500 else {
1501 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
1502 vty_out(vty, " %s %s\n",
1503 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
1504 (IS_ZEBRA_NEIGH_ACTIVE(n)
1505 ? "Active"
1506 : "Inactive"));
1507 }
1508 }
1509
1510 vty_out(vty, "\n");
1511 }
1512 }
1513
1514 static char *zevpn_print_mac_flags(zebra_mac_t *mac, char *flags_buf,
1515 uint32_t flags_buf_sz)
1516 {
1517 snprintf(flags_buf, flags_buf_sz, "%s%s%s%s",
1518 mac->sync_neigh_cnt ?
1519 "N" : "",
1520 (mac->flags & ZEBRA_MAC_ES_PEER_ACTIVE) ?
1521 "P" : "",
1522 (mac->flags & ZEBRA_MAC_ES_PEER_PROXY) ?
1523 "X" : "",
1524 (mac->flags & ZEBRA_MAC_LOCAL_INACTIVE) ?
1525 "I" : "");
1526
1527 return flags_buf;
1528 }
1529
1530 /*
1531 * Print MAC hash entry - called for display of all MACs.
1532 */
1533 static void zevpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
1534 {
1535 struct vty *vty;
1536 json_object *json_mac_hdr = NULL, *json_mac = NULL;
1537 zebra_mac_t *mac;
1538 char buf1[ETHER_ADDR_STRLEN];
1539 struct mac_walk_ctx *wctx = ctxt;
1540 char flags_buf[6];
1541
1542 vty = wctx->vty;
1543 json_mac_hdr = wctx->json;
1544 mac = (zebra_mac_t *)bucket->data;
1545
1546 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1547
1548 if (json_mac_hdr)
1549 json_mac = json_object_new_object();
1550
1551 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
1552 struct interface *ifp;
1553 vlanid_t vid;
1554
1555 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
1556 return;
1557
1558 zebra_vxlan_mac_get_access_info(mac,
1559 &ifp, &vid);
1560 if (json_mac_hdr == NULL) {
1561 vty_out(vty, "%-17s %-6s %-5s %-30s", buf1, "local",
1562 zevpn_print_mac_flags(mac, flags_buf,
1563 sizeof(flags_buf)),
1564 ifp ? ifp->name : "-");
1565 } else {
1566 json_object_string_add(json_mac, "type", "local");
1567 if (ifp)
1568 json_object_string_add(json_mac,
1569 "intf", ifp->name);
1570 }
1571 if (vid) {
1572 if (json_mac_hdr == NULL)
1573 vty_out(vty, " %-5u", vid);
1574 else
1575 json_object_int_add(json_mac, "vlan", vid);
1576 } else /* No vid? fill out the space */
1577 if (json_mac_hdr == NULL)
1578 vty_out(vty, " %-5s", "");
1579 if (json_mac_hdr == NULL) {
1580 vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq);
1581 vty_out(vty, "\n");
1582 } else {
1583 json_object_int_add(json_mac, "localSequence",
1584 mac->loc_seq);
1585 json_object_int_add(json_mac, "remoteSequence",
1586 mac->rem_seq);
1587 json_object_int_add(json_mac, "detectionCount",
1588 mac->dad_count);
1589 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1590 json_object_boolean_true_add(json_mac,
1591 "isDuplicate");
1592 else
1593 json_object_boolean_false_add(json_mac,
1594 "isDuplicate");
1595 json_object_object_add(json_mac_hdr, buf1, json_mac);
1596 }
1597
1598 wctx->count++;
1599
1600 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
1601
1602 if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
1603 !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
1604 &wctx->r_vtep_ip))
1605 return;
1606
1607 if (json_mac_hdr == NULL) {
1608 if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
1609 (wctx->count == 0)) {
1610 vty_out(vty, "\nVNI %u\n\n", wctx->zevpn->vni);
1611 vty_out(vty, "%-17s %-6s %-5s%-30s %-5s %s\n",
1612 "MAC", "Type", "Flags",
1613 "Intf/Remote ES/VTEP",
1614 "VLAN", "Seq #'s");
1615 }
1616 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %u/%u\n", buf1,
1617 "remote",
1618 zevpn_print_mac_flags(mac, flags_buf,
1619 sizeof(flags_buf)),
1620 mac->es ? mac->es->esi_str :
1621 inet_ntoa(mac->fwd_info.r_vtep_ip),
1622 "", mac->loc_seq, mac->rem_seq);
1623 } else {
1624 json_object_string_add(json_mac, "type", "remote");
1625 json_object_string_add(json_mac, "remoteVtep",
1626 inet_ntoa(mac->fwd_info.r_vtep_ip));
1627 json_object_object_add(json_mac_hdr, buf1, json_mac);
1628 json_object_int_add(json_mac, "localSequence",
1629 mac->loc_seq);
1630 json_object_int_add(json_mac, "remoteSequence",
1631 mac->rem_seq);
1632 json_object_int_add(json_mac, "detectionCount",
1633 mac->dad_count);
1634 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1635 json_object_boolean_true_add(json_mac,
1636 "isDuplicate");
1637 else
1638 json_object_boolean_false_add(json_mac,
1639 "isDuplicate");
1640
1641 }
1642
1643 wctx->count++;
1644 }
1645 }
1646
1647 /* Print Duplicate MAC */
1648 static void zevpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt)
1649 {
1650 zebra_mac_t *mac;
1651
1652 mac = (zebra_mac_t *)bucket->data;
1653 if (!mac)
1654 return;
1655
1656 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1657 zevpn_print_mac_hash(bucket, ctxt);
1658 }
1659
1660 /*
1661 * Print MAC hash entry in detail - called for display of all MACs.
1662 */
1663 static void zevpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt)
1664 {
1665 struct vty *vty;
1666 json_object *json_mac_hdr = NULL;
1667 zebra_mac_t *mac;
1668 struct mac_walk_ctx *wctx = ctxt;
1669 char buf1[ETHER_ADDR_STRLEN];
1670
1671 vty = wctx->vty;
1672 json_mac_hdr = wctx->json;
1673 mac = (zebra_mac_t *)bucket->data;
1674 if (!mac)
1675 return;
1676
1677 wctx->count++;
1678 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
1679
1680 zevpn_print_mac(mac, vty, json_mac_hdr);
1681 }
1682
1683 /* Print Duplicate MAC in detail */
1684 static void zevpn_print_dad_mac_hash_detail(struct hash_bucket *bucket,
1685 void *ctxt)
1686 {
1687 zebra_mac_t *mac;
1688
1689 mac = (zebra_mac_t *)bucket->data;
1690 if (!mac)
1691 return;
1692
1693 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
1694 zevpn_print_mac_hash_detail(bucket, ctxt);
1695 }
1696
1697 /*
1698 * Print MACs for all EVPNs.
1699 */
1700 static void zevpn_print_mac_hash_all_evpn(struct hash_bucket *bucket, void *ctxt)
1701 {
1702 struct vty *vty;
1703 json_object *json = NULL, *json_evpn = NULL;
1704 json_object *json_mac = NULL;
1705 zebra_evpn_t *zevpn;
1706 uint32_t num_macs;
1707 struct mac_walk_ctx *wctx = ctxt;
1708 char vni_str[VNI_STR_LEN];
1709
1710 vty = wctx->vty;
1711 json = wctx->json;
1712
1713 zevpn = (zebra_evpn_t *)bucket->data;
1714 wctx->zevpn = zevpn;
1715
1716 /*We are iterating over a new VNI, set the count to 0*/
1717 wctx->count = 0;
1718
1719 num_macs = num_valid_macs(zevpn);
1720 if (!num_macs)
1721 return;
1722
1723 if (wctx->print_dup)
1724 num_macs = num_dup_detected_macs(zevpn);
1725
1726 if (json) {
1727 json_evpn = json_object_new_object();
1728 json_mac = json_object_new_object();
1729 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
1730 }
1731
1732 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
1733 if (json == NULL) {
1734 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
1735 zevpn->vni, num_macs);
1736 vty_out(vty,
1737 "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
1738 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
1739 "Type", "Flags", "Intf/Remote ES/VTEP",
1740 "VLAN", "Seq #'s");
1741 } else
1742 json_object_int_add(json_evpn, "numMacs", num_macs);
1743 }
1744
1745 if (!num_macs) {
1746 if (json) {
1747 json_object_int_add(json_evpn, "numMacs", num_macs);
1748 json_object_object_add(json, vni_str, json_evpn);
1749 }
1750 return;
1751 }
1752
1753 /* assign per-evpn to wctx->json object to fill macs
1754 * under the evpn. Re-assign primary json object to fill
1755 * next evpn information.
1756 */
1757 wctx->json = json_mac;
1758 if (wctx->print_dup)
1759 hash_iterate(zevpn->mac_table, zevpn_print_dad_mac_hash, wctx);
1760 else
1761 hash_iterate(zevpn->mac_table, zevpn_print_mac_hash, wctx);
1762 wctx->json = json;
1763 if (json) {
1764 if (wctx->count)
1765 json_object_object_add(json_evpn, "macs", json_mac);
1766 json_object_object_add(json, vni_str, json_evpn);
1767 }
1768 }
1769
1770 /*
1771 * Print MACs in detail for all EVPNs.
1772 */
1773 static void zevpn_print_mac_hash_all_evpn_detail(struct hash_bucket *bucket,
1774 void *ctxt)
1775 {
1776 struct vty *vty;
1777 json_object *json = NULL, *json_evpn = NULL;
1778 json_object *json_mac = NULL;
1779 zebra_evpn_t *zevpn;
1780 uint32_t num_macs;
1781 struct mac_walk_ctx *wctx = ctxt;
1782 char vni_str[VNI_STR_LEN];
1783
1784 vty = wctx->vty;
1785 json = wctx->json;
1786
1787 zevpn = (zebra_evpn_t *)bucket->data;
1788 if (!zevpn) {
1789 if (json)
1790 vty_out(vty, "{}\n");
1791 return;
1792 }
1793 wctx->zevpn = zevpn;
1794
1795 /*We are iterating over a new EVPN, set the count to 0*/
1796 wctx->count = 0;
1797
1798 num_macs = num_valid_macs(zevpn);
1799 if (!num_macs)
1800 return;
1801
1802 if (wctx->print_dup && (num_dup_detected_macs(zevpn) == 0))
1803 return;
1804
1805 if (json) {
1806 json_evpn = json_object_new_object();
1807 json_mac = json_object_new_object();
1808 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
1809 }
1810
1811 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
1812 if (json == NULL) {
1813 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
1814 zevpn->vni, num_macs);
1815 } else
1816 json_object_int_add(json_evpn, "numMacs", num_macs);
1817 }
1818 /* assign per-evpn to wctx->json object to fill macs
1819 * under the evpn. Re-assign primary json object to fill
1820 * next evpn information.
1821 */
1822 wctx->json = json_mac;
1823 if (wctx->print_dup)
1824 hash_iterate(zevpn->mac_table, zevpn_print_dad_mac_hash_detail,
1825 wctx);
1826 else
1827 hash_iterate(zevpn->mac_table, zevpn_print_mac_hash_detail, wctx);
1828 wctx->json = json;
1829 if (json) {
1830 if (wctx->count)
1831 json_object_object_add(json_evpn, "macs", json_mac);
1832 json_object_object_add(json, vni_str, json_evpn);
1833 }
1834 }
1835
1836 static void zl3vni_print_nh_hash(struct hash_bucket *bucket, void *ctx)
1837 {
1838 struct nh_walk_ctx *wctx = NULL;
1839 struct vty *vty = NULL;
1840 struct json_object *json_evpn = NULL;
1841 struct json_object *json_nh = NULL;
1842 zebra_neigh_t *n = NULL;
1843 char buf1[ETHER_ADDR_STRLEN];
1844 char buf2[INET6_ADDRSTRLEN];
1845
1846 wctx = (struct nh_walk_ctx *)ctx;
1847 vty = wctx->vty;
1848 json_evpn = wctx->json;
1849 if (json_evpn)
1850 json_nh = json_object_new_object();
1851 n = (zebra_neigh_t *)bucket->data;
1852
1853 if (!json_evpn) {
1854 vty_out(vty, "%-15s %-17s\n",
1855 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
1856 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1857 } else {
1858 json_object_string_add(json_nh, "nexthopIp",
1859 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1860 json_object_string_add(
1861 json_nh, "routerMac",
1862 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1863 json_object_object_add(json_evpn,
1864 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
1865 json_nh);
1866 }
1867 }
1868
1869 static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket,
1870 void **args)
1871 {
1872 struct vty *vty = NULL;
1873 json_object *json = NULL;
1874 json_object *json_evpn = NULL;
1875 zebra_l3vni_t *zl3vni = NULL;
1876 uint32_t num_nh = 0;
1877 struct nh_walk_ctx wctx;
1878 char vni_str[VNI_STR_LEN];
1879
1880 vty = (struct vty *)args[0];
1881 json = (struct json_object *)args[1];
1882
1883 zl3vni = (zebra_l3vni_t *)bucket->data;
1884
1885 num_nh = hashcount(zl3vni->nh_table);
1886 if (!num_nh)
1887 return;
1888
1889 if (json) {
1890 json_evpn = json_object_new_object();
1891 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1892 }
1893
1894 if (json == NULL) {
1895 vty_out(vty, "\nVNI %u #Next-Hops %u\n\n", zl3vni->vni, num_nh);
1896 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
1897 } else
1898 json_object_int_add(json_evpn, "numNextHops", num_nh);
1899
1900 memset(&wctx, 0, sizeof(struct nh_walk_ctx));
1901 wctx.vty = vty;
1902 wctx.json = json_evpn;
1903 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
1904 if (json)
1905 json_object_object_add(json, vni_str, json_evpn);
1906 }
1907
1908 static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket,
1909 void **args)
1910 {
1911 struct vty *vty = NULL;
1912 json_object *json = NULL;
1913 json_object *json_evpn = NULL;
1914 zebra_l3vni_t *zl3vni = NULL;
1915 uint32_t num_rmacs;
1916 struct rmac_walk_ctx wctx;
1917 char vni_str[VNI_STR_LEN];
1918
1919 vty = (struct vty *)args[0];
1920 json = (struct json_object *)args[1];
1921
1922 zl3vni = (zebra_l3vni_t *)bucket->data;
1923
1924 num_rmacs = hashcount(zl3vni->rmac_table);
1925 if (!num_rmacs)
1926 return;
1927
1928 if (json) {
1929 json_evpn = json_object_new_object();
1930 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1931 }
1932
1933 if (json == NULL) {
1934 vty_out(vty, "\nVNI %u #RMACs %u\n\n", zl3vni->vni, num_rmacs);
1935 vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
1936 } else
1937 json_object_int_add(json_evpn, "numRmacs", num_rmacs);
1938
1939 /* assign per-vni to wctx->json object to fill macs
1940 * under the vni. Re-assign primary json object to fill
1941 * next vni information.
1942 */
1943 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
1944 wctx.vty = vty;
1945 wctx.json = json_evpn;
1946 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
1947 if (json)
1948 json_object_object_add(json, vni_str, json_evpn);
1949 }
1950
1951 static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
1952 {
1953 zebra_mac_t *zrmac = NULL;
1954 struct rmac_walk_ctx *wctx = NULL;
1955 struct vty *vty = NULL;
1956 struct json_object *json = NULL;
1957 struct json_object *json_rmac = NULL;
1958 char buf[ETHER_ADDR_STRLEN];
1959
1960 wctx = (struct rmac_walk_ctx *)ctx;
1961 vty = wctx->vty;
1962 json = wctx->json;
1963 if (json)
1964 json_rmac = json_object_new_object();
1965 zrmac = (zebra_mac_t *)bucket->data;
1966
1967 if (!json) {
1968 vty_out(vty, "%-17s %-21s\n",
1969 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
1970 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1971 } else {
1972 json_object_string_add(
1973 json_rmac, "routerMac",
1974 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
1975 json_object_string_add(json_rmac, "vtepIp",
1976 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
1977 json_object_object_add(
1978 json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
1979 json_rmac);
1980 }
1981 }
1982
1983 /* print a specific L3 VNI entry */
1984 static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
1985 {
1986 char buf[ETHER_ADDR_STRLEN];
1987 struct vty *vty = NULL;
1988 json_object *json = NULL;
1989 zebra_evpn_t *zevpn = NULL;
1990 json_object *json_evpn_list = NULL;
1991 struct listnode *node = NULL, *nnode = NULL;
1992
1993 vty = ctx[0];
1994 json = ctx[1];
1995
1996 if (!json) {
1997 vty_out(vty, "VNI: %u\n", zl3vni->vni);
1998 vty_out(vty, " Type: %s\n", "L3");
1999 vty_out(vty, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
2000 vty_out(vty, " Local Vtep Ip: %s\n",
2001 inet_ntoa(zl3vni->local_vtep_ip));
2002 vty_out(vty, " Vxlan-Intf: %s\n",
2003 zl3vni_vxlan_if_name(zl3vni));
2004 vty_out(vty, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
2005 vty_out(vty, " State: %s\n", zl3vni_state2str(zl3vni));
2006 vty_out(vty, " VNI Filter: %s\n",
2007 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
2008 ? "prefix-routes-only"
2009 : "none");
2010 vty_out(vty, " System MAC: %s\n",
2011 zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
2012 vty_out(vty, " Router MAC: %s\n",
2013 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2014 vty_out(vty, " L2 VNIs: ");
2015 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn))
2016 vty_out(vty, "%u ", zevpn->vni);
2017 vty_out(vty, "\n");
2018 } else {
2019 json_evpn_list = json_object_new_array();
2020 json_object_int_add(json, "vni", zl3vni->vni);
2021 json_object_string_add(json, "type", "L3");
2022 json_object_string_add(json, "localVtepIp",
2023 inet_ntoa(zl3vni->local_vtep_ip));
2024 json_object_string_add(json, "vxlanIntf",
2025 zl3vni_vxlan_if_name(zl3vni));
2026 json_object_string_add(json, "sviIntf",
2027 zl3vni_svi_if_name(zl3vni));
2028 json_object_string_add(json, "state", zl3vni_state2str(zl3vni));
2029 json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
2030 json_object_string_add(
2031 json, "sysMac",
2032 zl3vni_sysmac2str(zl3vni, buf, sizeof(buf)));
2033 json_object_string_add(
2034 json, "routerMac",
2035 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
2036 json_object_string_add(
2037 json, "vniFilter",
2038 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
2039 ? "prefix-routes-only"
2040 : "none");
2041 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zevpn)) {
2042 json_object_array_add(json_evpn_list,
2043 json_object_new_int(zevpn->vni));
2044 }
2045 json_object_object_add(json, "l2Vnis", json_evpn_list);
2046 }
2047 }
2048
2049 /*
2050 * Print a specific EVPN entry.
2051 */
2052 static void zevpn_print(zebra_evpn_t *zevpn, void **ctxt)
2053 {
2054 struct vty *vty;
2055 zebra_vtep_t *zvtep;
2056 uint32_t num_macs;
2057 uint32_t num_neigh;
2058 json_object *json = NULL;
2059 json_object *json_vtep_list = NULL;
2060 json_object *json_ip_str = NULL;
2061
2062 vty = ctxt[0];
2063 json = ctxt[1];
2064
2065 if (json == NULL) {
2066 vty_out(vty, "VNI: %u\n", zevpn->vni);
2067 vty_out(vty, " Type: %s\n", "L2");
2068 vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zevpn->vrf_id));
2069 } else {
2070 json_object_int_add(json, "vni", zevpn->vni);
2071 json_object_string_add(json, "type", "L2");
2072 json_object_string_add(json, "vrf",
2073 vrf_id_to_name(zevpn->vrf_id));
2074 }
2075
2076 if (!zevpn->vxlan_if) { // unexpected
2077 if (json == NULL)
2078 vty_out(vty, " VxLAN interface: unknown\n");
2079 return;
2080 }
2081 num_macs = num_valid_macs(zevpn);
2082 num_neigh = hashcount(zevpn->neigh_table);
2083 if (json == NULL) {
2084 vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name);
2085 vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex);
2086 vty_out(vty, " Local VTEP IP: %s\n",
2087 inet_ntoa(zevpn->local_vtep_ip));
2088 vty_out(vty, " Mcast group: %s\n",
2089 inet_ntoa(zevpn->mcast_grp));
2090 } else {
2091 json_object_string_add(json, "vxlanInterface",
2092 zevpn->vxlan_if->name);
2093 json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex);
2094 json_object_string_add(json, "vtepIp",
2095 inet_ntoa(zevpn->local_vtep_ip));
2096 json_object_string_add(json, "mcastGroup",
2097 inet_ntoa(zevpn->mcast_grp));
2098 json_object_string_add(json, "advertiseGatewayMacip",
2099 zevpn->advertise_gw_macip ? "Yes" : "No");
2100 json_object_int_add(json, "numMacs", num_macs);
2101 json_object_int_add(json, "numArpNd", num_neigh);
2102 }
2103 if (!zevpn->vteps) {
2104 if (json == NULL)
2105 vty_out(vty, " No remote VTEPs known for this VNI\n");
2106 } else {
2107 if (json == NULL)
2108 vty_out(vty, " Remote VTEPs for this VNI:\n");
2109 else
2110 json_vtep_list = json_object_new_array();
2111 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
2112 const char *flood_str = lookup_msg(zvtep_flood_str,
2113 zvtep->flood_control,
2114 VXLAN_FLOOD_STR_DEFAULT);
2115
2116 if (json == NULL) {
2117 vty_out(vty, " %s flood: %s\n",
2118 inet_ntoa(zvtep->vtep_ip),
2119 flood_str);
2120 } else {
2121 json_ip_str = json_object_new_string(
2122 inet_ntoa(zvtep->vtep_ip));
2123 json_object_array_add(json_vtep_list,
2124 json_ip_str);
2125 }
2126 }
2127 if (json)
2128 json_object_object_add(json, "numRemoteVteps",
2129 json_vtep_list);
2130 }
2131 if (json == NULL) {
2132 vty_out(vty,
2133 " Number of MACs (local and remote) known for this VNI: %u\n",
2134 num_macs);
2135 vty_out(vty,
2136 " Number of ARPs (IPv4 and IPv6, local and remote) known for this VNI: %u\n",
2137 num_neigh);
2138 vty_out(vty, " Advertise-gw-macip: %s\n",
2139 zevpn->advertise_gw_macip ? "Yes" : "No");
2140 }
2141 }
2142
2143 /* print a L3 VNI hash entry */
2144 static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[])
2145 {
2146 struct vty *vty = NULL;
2147 json_object *json = NULL;
2148 json_object *json_evpn = NULL;
2149 zebra_l3vni_t *zl3vni = NULL;
2150
2151 vty = (struct vty *)ctx[0];
2152 json = (json_object *)ctx[1];
2153
2154 zl3vni = (zebra_l3vni_t *)bucket->data;
2155
2156 if (!json) {
2157 vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
2158 zl3vni->vni, "L3", zl3vni_vxlan_if_name(zl3vni),
2159 hashcount(zl3vni->rmac_table),
2160 hashcount(zl3vni->nh_table), "n/a",
2161 zl3vni_vrf_name(zl3vni));
2162 } else {
2163 char vni_str[VNI_STR_LEN];
2164
2165 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
2166 json_evpn = json_object_new_object();
2167 json_object_int_add(json_evpn, "vni", zl3vni->vni);
2168 json_object_string_add(json_evpn, "vxlanIf",
2169 zl3vni_vxlan_if_name(zl3vni));
2170 json_object_int_add(json_evpn, "numMacs",
2171 hashcount(zl3vni->rmac_table));
2172 json_object_int_add(json_evpn, "numArpNd",
2173 hashcount(zl3vni->nh_table));
2174 json_object_string_add(json_evpn, "numRemoteVteps", "n/a");
2175 json_object_string_add(json_evpn, "type", "L3");
2176 json_object_string_add(json_evpn, "tenantVrf",
2177 zl3vni_vrf_name(zl3vni));
2178 json_object_object_add(json, vni_str, json_evpn);
2179 }
2180 }
2181
2182 /* Private Structure to pass callback data for hash iterator */
2183 struct zevpn_show {
2184 struct vty *vty;
2185 json_object *json;
2186 struct zebra_vrf *zvrf;
2187 bool use_json;
2188 };
2189
2190 /* print a L3 VNI hash entry in detail*/
2191 static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
2192 {
2193 struct vty *vty = NULL;
2194 zebra_l3vni_t *zl3vni = NULL;
2195 json_object *json_array = NULL;
2196 bool use_json = false;
2197 struct zevpn_show *zes = data;
2198
2199 vty = zes->vty;
2200 json_array = zes->json;
2201 use_json = zes->use_json;
2202
2203 zl3vni = (zebra_l3vni_t *)bucket->data;
2204
2205 zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni,
2206 use_json, json_array);
2207
2208 if (!use_json)
2209 vty_out(vty, "\n");
2210 }
2211
2212
2213 /*
2214 * Print an EVPN hash entry - called for display of all VNIs.
2215 */
2216 static void zevpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
2217 {
2218 struct vty *vty;
2219 zebra_evpn_t *zevpn;
2220 zebra_vtep_t *zvtep;
2221 uint32_t num_vteps = 0;
2222 uint32_t num_macs = 0;
2223 uint32_t num_neigh = 0;
2224 json_object *json = NULL;
2225 json_object *json_evpn = NULL;
2226 json_object *json_ip_str = NULL;
2227 json_object *json_vtep_list = NULL;
2228
2229 vty = ctxt[0];
2230 json = ctxt[1];
2231
2232 zevpn = (zebra_evpn_t *)bucket->data;
2233
2234 zvtep = zevpn->vteps;
2235 while (zvtep) {
2236 num_vteps++;
2237 zvtep = zvtep->next;
2238 }
2239
2240 num_macs = num_valid_macs(zevpn);
2241 num_neigh = hashcount(zevpn->neigh_table);
2242 if (json == NULL)
2243 vty_out(vty, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
2244 zevpn->vni, "L2",
2245 zevpn->vxlan_if ? zevpn->vxlan_if->name : "unknown",
2246 num_macs, num_neigh, num_vteps,
2247 vrf_id_to_name(zevpn->vrf_id));
2248 else {
2249 char vni_str[VNI_STR_LEN];
2250 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
2251 json_evpn = json_object_new_object();
2252 json_object_int_add(json_evpn, "vni", zevpn->vni);
2253 json_object_string_add(json_evpn, "type", "L2");
2254 json_object_string_add(json_evpn, "vxlanIf",
2255 zevpn->vxlan_if ? zevpn->vxlan_if->name
2256 : "unknown");
2257 json_object_int_add(json_evpn, "numMacs", num_macs);
2258 json_object_int_add(json_evpn, "numArpNd", num_neigh);
2259 json_object_int_add(json_evpn, "numRemoteVteps", num_vteps);
2260 json_object_string_add(json_evpn, "tenantVrf",
2261 vrf_id_to_name(zevpn->vrf_id));
2262 if (num_vteps) {
2263 json_vtep_list = json_object_new_array();
2264 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
2265 json_ip_str = json_object_new_string(
2266 inet_ntoa(zvtep->vtep_ip));
2267 json_object_array_add(json_vtep_list,
2268 json_ip_str);
2269 }
2270 json_object_object_add(json_evpn, "remoteVteps",
2271 json_vtep_list);
2272 }
2273 json_object_object_add(json, vni_str, json_evpn);
2274 }
2275 }
2276
2277 /*
2278 * Print an EVPN hash entry in detail - called for display of all EVPNs.
2279 */
2280 static void zevpn_print_hash_detail(struct hash_bucket *bucket, void *data)
2281 {
2282 struct vty *vty;
2283 zebra_evpn_t *zevpn;
2284 json_object *json_array = NULL;
2285 bool use_json = false;
2286 struct zevpn_show *zes = data;
2287
2288 vty = zes->vty;
2289 json_array = zes->json;
2290 use_json = zes->use_json;
2291
2292 zevpn = (zebra_evpn_t *)bucket->data;
2293
2294 zebra_vxlan_print_vni(vty, zes->zvrf, zevpn->vni, use_json, json_array);
2295
2296 if (!use_json)
2297 vty_out(vty, "\n");
2298 }
2299
2300 /*
2301 * Inform BGP about local MACIP.
2302 */
2303 static int zevpn_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
2304 struct ipaddr *ip, uint8_t flags,
2305 uint32_t seq, int state,
2306 struct zebra_evpn_es *es,
2307 uint16_t cmd)
2308 {
2309 char buf[ETHER_ADDR_STRLEN];
2310 char buf2[INET6_ADDRSTRLEN];
2311 int ipa_len;
2312 struct zserv *client = NULL;
2313 struct stream *s = NULL;
2314 esi_t *esi = es ? &es->esi : zero_esi;
2315
2316 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
2317 /* BGP may not be running. */
2318 if (!client)
2319 return 0;
2320
2321 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2322
2323 zclient_create_header(s, cmd, zebra_vrf_get_evpn_id());
2324 stream_putl(s, vni);
2325 stream_put(s, macaddr->octet, ETH_ALEN);
2326 if (ip) {
2327 ipa_len = 0;
2328 if (IS_IPADDR_V4(ip))
2329 ipa_len = IPV4_MAX_BYTELEN;
2330 else if (IS_IPADDR_V6(ip))
2331 ipa_len = IPV6_MAX_BYTELEN;
2332
2333 stream_putl(s, ipa_len); /* IP address length */
2334 if (ipa_len)
2335 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
2336 } else
2337 stream_putl(s, 0); /* Just MAC. */
2338
2339 if (cmd == ZEBRA_MACIP_ADD) {
2340 stream_putc(s, flags); /* sticky mac/gateway mac */
2341 stream_putl(s, seq); /* sequence number */
2342 stream_put(s, esi, sizeof(esi_t));
2343 } else {
2344 stream_putl(s, state); /* state - active/inactive */
2345 }
2346
2347
2348 /* Write packet size. */
2349 stream_putw_at(s, 0, stream_get_endp(s));
2350
2351 if (IS_ZEBRA_DEBUG_VXLAN)
2352 zlog_debug(
2353 "Send MACIP %s f 0x%x MAC %s IP %s seq %u L2-VNI %u ESI %s to %s",
2354 (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags,
2355 prefix_mac2str(macaddr, buf, sizeof(buf)),
2356 ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni,
2357 es ? es->esi_str : "-",
2358 zebra_route_string(client->proto));
2359
2360 if (cmd == ZEBRA_MACIP_ADD)
2361 client->macipadd_cnt++;
2362 else
2363 client->macipdel_cnt++;
2364
2365 return zserv_send_message(client, s);
2366 }
2367
2368 /*
2369 * Make hash key for neighbors.
2370 */
2371 static unsigned int neigh_hash_keymake(const void *p)
2372 {
2373 const zebra_neigh_t *n = p;
2374 const struct ipaddr *ip = &n->ip;
2375
2376 if (IS_IPADDR_V4(ip))
2377 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
2378
2379 return jhash2(ip->ipaddr_v6.s6_addr32,
2380 array_size(ip->ipaddr_v6.s6_addr32), 0);
2381 }
2382
2383 /*
2384 * Compare two neighbor hash structures.
2385 */
2386 static bool neigh_cmp(const void *p1, const void *p2)
2387 {
2388 const zebra_neigh_t *n1 = p1;
2389 const zebra_neigh_t *n2 = p2;
2390
2391 if (n1 == NULL && n2 == NULL)
2392 return true;
2393
2394 if (n1 == NULL || n2 == NULL)
2395 return false;
2396
2397 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
2398 }
2399
2400 static int neigh_list_cmp(void *p1, void *p2)
2401 {
2402 const zebra_neigh_t *n1 = p1;
2403 const zebra_neigh_t *n2 = p2;
2404
2405 return memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr));
2406 }
2407
2408 /*
2409 * Callback to allocate neighbor hash entry.
2410 */
2411 static void *zevpn_neigh_alloc(void *p)
2412 {
2413 const zebra_neigh_t *tmp_n = p;
2414 zebra_neigh_t *n;
2415
2416 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
2417 *n = *tmp_n;
2418
2419 return ((void *)n);
2420 }
2421
2422 /*
2423 * Add neighbor entry.
2424 */
2425 static zebra_neigh_t *zevpn_neigh_add(zebra_evpn_t *zevpn, struct ipaddr *ip,
2426 struct ethaddr *mac, zebra_mac_t *zmac,
2427 uint32_t n_flags)
2428 {
2429 zebra_neigh_t tmp_n;
2430 zebra_neigh_t *n = NULL;
2431
2432 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
2433 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
2434 n = hash_get(zevpn->neigh_table, &tmp_n, zevpn_neigh_alloc);
2435 assert(n);
2436
2437 n->state = ZEBRA_NEIGH_INACTIVE;
2438 n->zevpn = zevpn;
2439 n->dad_ip_auto_recovery_timer = NULL;
2440 n->flags = n_flags;
2441
2442 if (!zmac)
2443 zmac = zevpn_mac_lookup(zevpn, mac);
2444 zebra_vxlan_local_neigh_ref_mac(n, mac,
2445 zmac, false /* send_mac_update */);
2446
2447 return n;
2448 }
2449
2450 /*
2451 * Delete neighbor entry.
2452 */
2453 static int zevpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n)
2454 {
2455 zebra_neigh_t *tmp_n;
2456
2457 if (n->mac)
2458 listnode_delete(n->mac->neigh_list, n);
2459
2460 /* Cancel auto recovery */
2461 THREAD_OFF(n->dad_ip_auto_recovery_timer);
2462
2463 /* Free the VNI hash entry and allocated memory. */
2464 tmp_n = hash_release(zevpn->neigh_table, n);
2465 XFREE(MTYPE_NEIGH, tmp_n);
2466
2467 return 0;
2468 }
2469
2470 /*
2471 * Free neighbor hash entry (callback)
2472 */
2473 static void zevpn_neigh_del_hash_entry(struct hash_bucket *bucket, void *arg)
2474 {
2475 struct neigh_walk_ctx *wctx = arg;
2476 zebra_neigh_t *n = bucket->data;
2477
2478 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
2479 || ((wctx->flags & DEL_REMOTE_NEIGH)
2480 && (n->flags & ZEBRA_NEIGH_REMOTE))
2481 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
2482 && (n->flags & ZEBRA_NEIGH_REMOTE)
2483 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
2484 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
2485 zevpn_neigh_send_del_to_client(wctx->zevpn->vni, &n->ip,
2486 &n->emac, n->flags, n->state,
2487 false /*force*/);
2488
2489 if (wctx->uninstall) {
2490 if (zebra_vxlan_neigh_is_static(n))
2491 zebra_vxlan_sync_neigh_dp_install(n,
2492 false /* set_inactive */,
2493 true /* force_clear_static */,
2494 __func__);
2495 if ((n->flags & ZEBRA_NEIGH_REMOTE))
2496 zevpn_neigh_uninstall(wctx->zevpn, n);
2497 }
2498
2499 zevpn_neigh_del(wctx->zevpn, n);
2500 }
2501
2502 return;
2503 }
2504
2505 /*
2506 * Delete all neighbor entries for this EVPN.
2507 */
2508 static void zevpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client,
2509 uint32_t flags)
2510 {
2511 struct neigh_walk_ctx wctx;
2512
2513 if (!zevpn->neigh_table)
2514 return;
2515
2516 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2517 wctx.zevpn = zevpn;
2518 wctx.uninstall = uninstall;
2519 wctx.upd_client = upd_client;
2520 wctx.flags = flags;
2521
2522 hash_iterate(zevpn->neigh_table, zevpn_neigh_del_hash_entry, &wctx);
2523 }
2524
2525 /*
2526 * Look up neighbor hash entry.
2527 */
2528 static zebra_neigh_t *zevpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip)
2529 {
2530 zebra_neigh_t tmp;
2531 zebra_neigh_t *n;
2532
2533 memset(&tmp, 0, sizeof(tmp));
2534 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
2535 n = hash_lookup(zevpn->neigh_table, &tmp);
2536
2537 return n;
2538 }
2539
2540 /*
2541 * Process all neighbors associated with a MAC upon the MAC being learnt
2542 * locally or undergoing any other change (such as sequence number).
2543 */
2544 static void zevpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn,
2545 zebra_mac_t *zmac, bool seq_change, bool es_change)
2546 {
2547 zebra_neigh_t *n = NULL;
2548 struct listnode *node = NULL;
2549 struct zebra_vrf *zvrf = NULL;
2550 char buf[ETHER_ADDR_STRLEN];
2551
2552 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
2553
2554 if (IS_ZEBRA_DEBUG_VXLAN)
2555 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
2556 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2557 seq_change ? "CHANGE" : "ADD", zevpn->vni);
2558
2559 /* Walk all neighbors and mark any inactive local neighbors as
2560 * active and/or update sequence number upon a move, and inform BGP.
2561 * The action for remote neighbors is TBD.
2562 * NOTE: We can't simply uninstall remote neighbors as the kernel may
2563 * accidentally end up deleting a just-learnt local neighbor.
2564 */
2565 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2566 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2567 if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change ||
2568 es_change) {
2569 ZEBRA_NEIGH_SET_ACTIVE(n);
2570 n->loc_seq = zmac->loc_seq;
2571 if (!(zvrf->dup_addr_detect &&
2572 zvrf->dad_freeze && !!CHECK_FLAG(n->flags,
2573 ZEBRA_NEIGH_DUPLICATE)))
2574 zevpn_neigh_send_add_to_client(
2575 zevpn->vni, &n->ip, &n->emac,
2576 n->mac, n->flags, n->loc_seq);
2577 }
2578 }
2579 }
2580 }
2581
2582 /*
2583 * Process all neighbors associated with a local MAC upon the MAC being
2584 * deleted.
2585 */
2586 static void zevpn_process_neigh_on_local_mac_del(zebra_evpn_t *zevpn,
2587 zebra_mac_t *zmac)
2588 {
2589 zebra_neigh_t *n = NULL;
2590 struct listnode *node = NULL;
2591 char buf[ETHER_ADDR_STRLEN];
2592
2593 if (IS_ZEBRA_DEBUG_VXLAN)
2594 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
2595 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2596 zevpn->vni);
2597
2598 /* Walk all local neighbors and mark as inactive and inform
2599 * BGP, if needed.
2600 * TBD: There is currently no handling for remote neighbors. We
2601 * don't expect them to exist, if they do, do we install the MAC
2602 * as a remote MAC and the neighbor as remote?
2603 */
2604 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2605 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2606 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
2607 ZEBRA_NEIGH_SET_INACTIVE(n);
2608 n->loc_seq = 0;
2609 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip,
2610 &n->emac, n->flags,
2611 ZEBRA_NEIGH_ACTIVE,
2612 false /*force*/);
2613 }
2614 }
2615 }
2616 }
2617
2618 /*
2619 * Process all neighbors associated with a MAC upon the MAC being remotely
2620 * learnt.
2621 */
2622 static void zevpn_process_neigh_on_remote_mac_add(zebra_evpn_t *zevpn,
2623 zebra_mac_t *zmac)
2624 {
2625 zebra_neigh_t *n = NULL;
2626 struct listnode *node = NULL;
2627 char buf[ETHER_ADDR_STRLEN];
2628
2629 if (IS_ZEBRA_DEBUG_VXLAN)
2630 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
2631 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
2632 zevpn->vni);
2633
2634 /* Walk all local neighbors and mark as inactive and inform
2635 * BGP, if needed.
2636 */
2637 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
2638 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2639 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
2640 ZEBRA_NEIGH_SET_INACTIVE(n);
2641 n->loc_seq = 0;
2642 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip,
2643 &n->emac, n->flags,
2644 ZEBRA_NEIGH_ACTIVE,
2645 false /* force */);
2646 }
2647 }
2648 }
2649 }
2650
2651 /*
2652 * Process all neighbors associated with a remote MAC upon the MAC being
2653 * deleted.
2654 */
2655 static void zevpn_process_neigh_on_remote_mac_del(zebra_evpn_t *zevpn,
2656 zebra_mac_t *zmac)
2657 {
2658 /* NOTE: Currently a NO-OP. */
2659 }
2660
2661 static void zevpn_probe_neigh_on_mac_add(zebra_evpn_t *zevpn, zebra_mac_t *zmac)
2662 {
2663 zebra_neigh_t *nbr = NULL;
2664 struct listnode *node = NULL;
2665
2666 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, nbr)) {
2667 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL) &&
2668 IS_ZEBRA_NEIGH_INACTIVE(nbr))
2669 zevpn_neigh_probe(zevpn, nbr);
2670 }
2671 }
2672
2673 /*
2674 * Inform BGP about local neighbor addition.
2675 */
2676 static int zevpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
2677 struct ethaddr *macaddr,
2678 zebra_mac_t *zmac,
2679 uint32_t neigh_flags,
2680 uint32_t seq)
2681 {
2682 uint8_t flags = 0;
2683
2684 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
2685 /* host reachability has not been verified locally */
2686
2687 /* if no ES peer is claiming reachability we can't advertise
2688 * the entry
2689 */
2690 if (!CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
2691 return 0;
2692
2693 /* ES peers are claiming reachability; we will
2694 * advertise the entry but with a proxy flag
2695 */
2696 SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT);
2697 }
2698
2699 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
2700 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
2701 /* Set router flag (R-bit) based on local neigh entry add */
2702 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
2703 SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
2704 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_SVI_IP))
2705 SET_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP);
2706
2707 return zevpn_macip_send_msg_to_client(vni, macaddr, ip, flags,
2708 seq, ZEBRA_NEIGH_ACTIVE,
2709 zmac ? zmac->es : NULL,
2710 ZEBRA_MACIP_ADD);
2711 }
2712
2713 /*
2714 * Inform BGP about local neighbor deletion.
2715 */
2716 static int zevpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
2717 struct ethaddr *macaddr, uint32_t flags,
2718 int state, bool force)
2719 {
2720 if (!force) {
2721 if (CHECK_FLAG(flags, ZEBRA_NEIGH_LOCAL_INACTIVE) &&
2722 !CHECK_FLAG(flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
2723 /* the neigh was not advertised - nothing to delete */
2724 return 0;
2725 }
2726
2727 return zevpn_macip_send_msg_to_client(vni, macaddr, ip, flags,
2728 0, state, NULL, ZEBRA_MACIP_DEL);
2729 }
2730
2731 /*
2732 * Install remote neighbor into the kernel.
2733 */
2734 static int zevpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n,
2735 bool was_static)
2736 {
2737 struct zebra_if *zif;
2738 struct zebra_l2info_vxlan *vxl;
2739 struct interface *vlan_if;
2740 int flags;
2741 int ret = 0;
2742
2743 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2744 return 0;
2745
2746 zif = zevpn->vxlan_if->info;
2747 if (!zif)
2748 return -1;
2749 vxl = &zif->l2info.vxl;
2750
2751 vlan_if = zevpn_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2752 if (!vlan_if)
2753 return -1;
2754
2755 flags = DPLANE_NTF_EXT_LEARNED;
2756 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
2757 flags |= DPLANE_NTF_ROUTER;
2758 ZEBRA_NEIGH_SET_ACTIVE(n);
2759
2760 dplane_rem_neigh_add(vlan_if, &n->ip, &n->emac, flags,
2761 was_static);
2762
2763 return ret;
2764 }
2765
2766 /*
2767 * Uninstall remote neighbor from the kernel.
2768 */
2769 static int zevpn_neigh_uninstall(zebra_evpn_t *zevpn, zebra_neigh_t *n)
2770 {
2771 struct zebra_if *zif;
2772 struct zebra_l2info_vxlan *vxl;
2773 struct interface *vlan_if;
2774
2775 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
2776 return 0;
2777
2778 if (!zevpn->vxlan_if) {
2779 if (IS_ZEBRA_DEBUG_VXLAN)
2780 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
2781 zevpn->vni, zevpn);
2782 return -1;
2783 }
2784
2785 zif = zevpn->vxlan_if->info;
2786 if (!zif)
2787 return -1;
2788 vxl = &zif->l2info.vxl;
2789 vlan_if = zevpn_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2790 if (!vlan_if)
2791 return -1;
2792
2793 ZEBRA_NEIGH_SET_INACTIVE(n);
2794 n->loc_seq = 0;
2795
2796 dplane_rem_neigh_delete(vlan_if, &n->ip);
2797
2798 return 0;
2799 }
2800
2801 /*
2802 * Probe neighbor from the kernel.
2803 */
2804 static int zevpn_neigh_probe(zebra_evpn_t *zevpn, zebra_neigh_t *n)
2805 {
2806 struct zebra_if *zif;
2807 struct zebra_l2info_vxlan *vxl;
2808 struct interface *vlan_if;
2809
2810 zif = zevpn->vxlan_if->info;
2811 if (!zif)
2812 return -1;
2813 vxl = &zif->l2info.vxl;
2814
2815 vlan_if = zevpn_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2816 if (!vlan_if)
2817 return -1;
2818
2819 dplane_rem_neigh_update(vlan_if, &n->ip, &n->emac);
2820
2821 return 0;
2822 }
2823
2824 /*
2825 * Install neighbor hash entry - called upon access VLAN change.
2826 */
2827 static void zevpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt)
2828 {
2829 zebra_neigh_t *n;
2830 struct neigh_walk_ctx *wctx = ctxt;
2831
2832 n = (zebra_neigh_t *)bucket->data;
2833
2834 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2835 zevpn_rem_neigh_install(wctx->zevpn, n, false /*was_static*/);
2836 }
2837
2838 /* Get the VRR interface for SVI if any */
2839 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
2840 {
2841 struct zebra_vrf *zvrf = NULL;
2842 struct interface *tmp_if = NULL;
2843 struct zebra_if *zif = NULL;
2844
2845 zvrf = vrf_info_lookup(ifp->vrf_id);
2846 assert(zvrf);
2847
2848 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
2849 zif = tmp_if->info;
2850 if (!zif)
2851 continue;
2852
2853 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
2854 continue;
2855
2856 if (zif->link == ifp)
2857 return tmp_if;
2858 }
2859
2860 return NULL;
2861 }
2862
2863 static int zevpn_del_macip_for_intf(struct interface *ifp, zebra_evpn_t *zevpn)
2864 {
2865 struct listnode *cnode = NULL, *cnnode = NULL;
2866 struct connected *c = NULL;
2867 struct ethaddr macaddr;
2868
2869 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2870
2871 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2872 struct ipaddr ip;
2873
2874 memset(&ip, 0, sizeof(struct ipaddr));
2875 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2876 continue;
2877
2878 if (c->address->family == AF_INET) {
2879 ip.ipa_type = IPADDR_V4;
2880 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2881 sizeof(struct in_addr));
2882 } else if (c->address->family == AF_INET6) {
2883 ip.ipa_type = IPADDR_V6;
2884 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2885 sizeof(struct in6_addr));
2886 } else {
2887 continue;
2888 }
2889
2890 zevpn_gw_macip_del(ifp, zevpn, &ip);
2891 }
2892
2893 return 0;
2894 }
2895
2896 static int zevpn_add_macip_for_intf(struct interface *ifp, zebra_evpn_t *zevpn)
2897 {
2898 struct listnode *cnode = NULL, *cnnode = NULL;
2899 struct connected *c = NULL;
2900 struct ethaddr macaddr;
2901
2902 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2903
2904 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2905 struct ipaddr ip;
2906
2907 memset(&ip, 0, sizeof(struct ipaddr));
2908 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
2909 continue;
2910
2911 if (c->address->family == AF_INET) {
2912 ip.ipa_type = IPADDR_V4;
2913 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
2914 sizeof(struct in_addr));
2915 } else if (c->address->family == AF_INET6) {
2916 ip.ipa_type = IPADDR_V6;
2917 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
2918 sizeof(struct in6_addr));
2919 } else {
2920 continue;
2921 }
2922
2923 zevpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
2924 }
2925 return 0;
2926 }
2927
2928
2929 static int zevpn_advertise_subnet(zebra_evpn_t *zevpn, struct interface *ifp,
2930 int advertise)
2931 {
2932 struct listnode *cnode = NULL, *cnnode = NULL;
2933 struct connected *c = NULL;
2934 struct ethaddr macaddr;
2935
2936 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
2937
2938 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
2939 struct prefix p;
2940
2941 memcpy(&p, c->address, sizeof(struct prefix));
2942
2943 /* skip link local address */
2944 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
2945 continue;
2946
2947 apply_mask(&p);
2948 if (advertise)
2949 ip_prefix_send_to_client(ifp->vrf_id, &p,
2950 ZEBRA_IP_PREFIX_ROUTE_ADD);
2951 else
2952 ip_prefix_send_to_client(ifp->vrf_id, &p,
2953 ZEBRA_IP_PREFIX_ROUTE_DEL);
2954 }
2955 return 0;
2956 }
2957
2958 /*
2959 * zevpn_gw_macip_add_to_client
2960 */
2961 static int zevpn_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
2962 struct ethaddr *macaddr, struct ipaddr *ip)
2963 {
2964 char buf[ETHER_ADDR_STRLEN];
2965 char buf2[INET6_ADDRSTRLEN];
2966 zebra_neigh_t *n = NULL;
2967 zebra_mac_t *mac = NULL;
2968 struct zebra_if *zif = NULL;
2969 struct zebra_l2info_vxlan *vxl = NULL;
2970
2971 zif = zevpn->vxlan_if->info;
2972 if (!zif)
2973 return -1;
2974
2975 vxl = &zif->l2info.vxl;
2976
2977 mac = zevpn_mac_lookup(zevpn, macaddr);
2978 if (!mac) {
2979 mac = zevpn_mac_add(zevpn, macaddr);
2980 if (!mac) {
2981 flog_err(EC_ZEBRA_MAC_ADD_FAILED,
2982 "Failed to add MAC %s intf %s(%u) VID %u",
2983 prefix_mac2str(macaddr, buf, sizeof(buf)),
2984 ifp->name, ifp->ifindex, vxl->access_vlan);
2985 return -1;
2986 }
2987 }
2988
2989 /* Set "local" forwarding info. */
2990 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2991 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2992 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
2993 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2994 mac->fwd_info.local.ifindex = ifp->ifindex;
2995 mac->fwd_info.local.vid = vxl->access_vlan;
2996
2997 n = zevpn_neigh_lookup(zevpn, ip);
2998 if (!n) {
2999 n = zevpn_neigh_add(zevpn, ip, macaddr, mac, 0);
3000 if (!n) {
3001 flog_err(
3002 EC_ZEBRA_MAC_ADD_FAILED,
3003 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
3004 ipaddr2str(ip, buf2, sizeof(buf2)),
3005 prefix_mac2str(macaddr, buf, sizeof(buf)),
3006 ifp->name, ifp->ifindex, zevpn->vni);
3007 return -1;
3008 }
3009 }
3010
3011 /* Set "local" forwarding info. */
3012 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3013 ZEBRA_NEIGH_SET_ACTIVE(n);
3014 memcpy(&n->emac, macaddr, ETH_ALEN);
3015 n->ifindex = ifp->ifindex;
3016
3017 /* Only advertise in BGP if the knob is enabled */
3018 if (advertise_gw_macip_enabled(zevpn)) {
3019
3020 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
3021 SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
3022 /* Set Router flag (R-bit) */
3023 if (ip->ipa_type == IPADDR_V6)
3024 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
3025
3026 if (IS_ZEBRA_DEBUG_VXLAN)
3027 zlog_debug(
3028 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
3029 ifp->name, ifp->ifindex, zevpn->vni,
3030 prefix_mac2str(macaddr, buf, sizeof(buf)),
3031 ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
3032
3033 zevpn_neigh_send_add_to_client(zevpn->vni, ip, &n->emac, n->mac,
3034 n->flags, n->loc_seq);
3035 } else if (advertise_svi_macip_enabled(zevpn)) {
3036
3037 SET_FLAG(n->flags, ZEBRA_NEIGH_SVI_IP);
3038 if (IS_ZEBRA_DEBUG_VXLAN)
3039 zlog_debug(
3040 "SVI %s(%u) L2-VNI %u, sending SVI MAC %s IP %s add to BGP with flags 0x%x",
3041 ifp->name, ifp->ifindex, zevpn->vni,
3042 prefix_mac2str(macaddr, buf, sizeof(buf)),
3043 ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
3044
3045 zevpn_neigh_send_add_to_client(zevpn->vni, ip, &n->emac, n->mac,
3046 n->flags, n->loc_seq);
3047 }
3048
3049 return 0;
3050 }
3051
3052 /*
3053 * zevpn_gw_macip_del_from_client
3054 */
3055 static int zevpn_gw_macip_del(struct interface *ifp, zebra_evpn_t *zevpn,
3056 struct ipaddr *ip)
3057 {
3058 char buf1[ETHER_ADDR_STRLEN];
3059 char buf2[INET6_ADDRSTRLEN];
3060 zebra_neigh_t *n = NULL;
3061 zebra_mac_t *mac = NULL;
3062
3063 /* If the neigh entry is not present nothing to do*/
3064 n = zevpn_neigh_lookup(zevpn, ip);
3065 if (!n)
3066 return 0;
3067
3068 /* mac entry should be present */
3069 mac = zevpn_mac_lookup(zevpn, &n->emac);
3070 if (!mac) {
3071 if (IS_ZEBRA_DEBUG_VXLAN)
3072 zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u",
3073 prefix_mac2str(&n->emac,
3074 buf1, sizeof(buf1)),
3075 ipaddr2str(ip, buf2, sizeof(buf2)),
3076 zevpn->vni);
3077 return -1;
3078 }
3079
3080 /* If the entry is not local nothing to do*/
3081 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
3082 return -1;
3083
3084 /* only need to delete the entry from bgp if we sent it before */
3085 if (IS_ZEBRA_DEBUG_VXLAN)
3086 zlog_debug(
3087 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
3088 ifp->vrf_id, ifp->name, ifp->ifindex, zevpn->vni,
3089 prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
3090 ipaddr2str(ip, buf2, sizeof(buf2)));
3091
3092 /* Remove neighbor from BGP. */
3093 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
3094 n->flags, ZEBRA_NEIGH_ACTIVE,
3095 false /*force*/);
3096
3097 /* Delete this neighbor entry. */
3098 zevpn_neigh_del(zevpn, n);
3099
3100 /* see if the mac needs to be deleted as well*/
3101 if (mac)
3102 zevpn_deref_ip2mac(zevpn, mac);
3103
3104 return 0;
3105 }
3106
3107 static void zevpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
3108 void *ctxt)
3109 {
3110 zebra_evpn_t *zevpn = NULL;
3111 struct zebra_if *zif = NULL;
3112 struct zebra_l2info_vxlan zl2_info;
3113 struct interface *vlan_if = NULL;
3114 struct interface *vrr_if = NULL;
3115 struct interface *ifp;
3116
3117 /* Add primary SVI MAC*/
3118 zevpn = (zebra_evpn_t *)bucket->data;
3119
3120 /* Global (Zvrf) advertise-default-gw is disabled,
3121 * but zevpn advertise-default-gw is enabled
3122 */
3123 if (zevpn->advertise_gw_macip) {
3124 if (IS_ZEBRA_DEBUG_VXLAN)
3125 zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
3126 zevpn->vni);
3127 return;
3128 }
3129
3130 ifp = zevpn->vxlan_if;
3131 if (!ifp)
3132 return;
3133 zif = ifp->info;
3134
3135 /* If down or not mapped to a bridge, we're done. */
3136 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3137 return;
3138
3139 zl2_info = zif->l2info.vxl;
3140
3141 vlan_if =
3142 zevpn_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
3143 if (!vlan_if)
3144 return;
3145
3146 /* Del primary MAC-IP */
3147 zevpn_del_macip_for_intf(vlan_if, zevpn);
3148
3149 /* Del VRR MAC-IP - if any*/
3150 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
3151 if (vrr_if)
3152 zevpn_del_macip_for_intf(vrr_if, zevpn);
3153
3154 return;
3155 }
3156
3157 static void zevpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket,
3158 void *ctxt)
3159 {
3160 zebra_evpn_t *zevpn = NULL;
3161 struct zebra_if *zif = NULL;
3162 struct zebra_l2info_vxlan zl2_info;
3163 struct interface *vlan_if = NULL;
3164 struct interface *vrr_if = NULL;
3165 struct interface *ifp = NULL;
3166
3167 zevpn = (zebra_evpn_t *)bucket->data;
3168
3169 ifp = zevpn->vxlan_if;
3170 if (!ifp)
3171 return;
3172 zif = ifp->info;
3173
3174 /* If down or not mapped to a bridge, we're done. */
3175 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3176 return;
3177 zl2_info = zif->l2info.vxl;
3178
3179 vlan_if =
3180 zevpn_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
3181 if (!vlan_if)
3182 return;
3183
3184 /* Add primary SVI MAC-IP */
3185 zevpn_add_macip_for_intf(vlan_if, zevpn);
3186
3187 if (advertise_gw_macip_enabled(zevpn)) {
3188 /* Add VRR MAC-IP - if any*/
3189 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
3190 if (vrr_if)
3191 zevpn_add_macip_for_intf(vrr_if, zevpn);
3192 }
3193
3194 return;
3195 }
3196
3197 static void zevpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
3198 void *ctxt)
3199 {
3200 zebra_evpn_t *zevpn = NULL;
3201 struct zebra_if *zif = NULL;
3202 struct zebra_l2info_vxlan zl2_info;
3203 struct interface *vlan_if = NULL;
3204 struct interface *ifp;
3205
3206 /* Add primary SVI MAC*/
3207 zevpn = (zebra_evpn_t *)bucket->data;
3208 if (!zevpn)
3209 return;
3210
3211 /* Global(vrf) advertise-svi-ip disabled, but zevpn advertise-svi-ip
3212 * enabled
3213 */
3214 if (zevpn->advertise_svi_macip) {
3215 if (IS_ZEBRA_DEBUG_VXLAN)
3216 zlog_debug("VNI: %u SVI-MACIP enabled, retain svi-macip",
3217 zevpn->vni);
3218 return;
3219 }
3220
3221 ifp = zevpn->vxlan_if;
3222 if (!ifp)
3223 return;
3224 zif = ifp->info;
3225
3226 /* If down or not mapped to a bridge, we're done. */
3227 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3228 return;
3229
3230 zl2_info = zif->l2info.vxl;
3231
3232 vlan_if = zevpn_map_to_svi(zl2_info.access_vlan,
3233 zif->brslave_info.br_if);
3234 if (!vlan_if)
3235 return;
3236
3237 /* Del primary MAC-IP */
3238 zevpn_del_macip_for_intf(vlan_if, zevpn);
3239
3240 return;
3241 }
3242
3243 static inline void zevpn_local_neigh_update_log(const char *pfx,
3244 zebra_neigh_t *n, bool is_router, bool local_inactive,
3245 bool old_bgp_ready, bool new_bgp_ready,
3246 bool inform_dataplane, bool inform_bgp, const char *sfx)
3247 {
3248 char macbuf[ETHER_ADDR_STRLEN];
3249 char ipbuf[INET6_ADDRSTRLEN];
3250
3251 if (!IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
3252 return;
3253
3254 zlog_debug("%s neigh vni %u ip %s mac %s f 0x%x%s%s%s%s%s%s %s",
3255 pfx, n->zevpn->vni,
3256 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
3257 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
3258 n->flags, is_router ? " router" : "",
3259 local_inactive ? " local-inactive" : "",
3260 old_bgp_ready ? " old_bgp_ready" : "",
3261 new_bgp_ready ? " new_bgp_ready" : "",
3262 inform_dataplane ? " inform_dp" : "",
3263 inform_bgp ? " inform_bgp" : "",
3264 sfx);
3265 }
3266
3267 static int zevpn_local_neigh_update(zebra_evpn_t *zevpn,
3268 struct interface *ifp,
3269 struct ipaddr *ip,
3270 struct ethaddr *macaddr,
3271 bool is_router,
3272 bool local_inactive, bool dp_static)
3273 {
3274 char buf[ETHER_ADDR_STRLEN];
3275 char buf2[INET6_ADDRSTRLEN];
3276 struct zebra_vrf *zvrf;
3277 zebra_neigh_t *n = NULL;
3278 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
3279 uint32_t old_mac_seq = 0, mac_new_seq = 0;
3280 bool upd_mac_seq = false;
3281 bool neigh_mac_change = false;
3282 bool neigh_on_hold = false;
3283 bool neigh_was_remote = false;
3284 bool do_dad = false;
3285 struct in_addr vtep_ip = {.s_addr = 0};
3286 bool inform_dataplane = false;
3287 bool created = false;
3288 bool new_static = false;
3289 bool old_bgp_ready = false;
3290 bool new_bgp_ready;
3291
3292 /* Check if the MAC exists. */
3293 zmac = zevpn_mac_lookup(zevpn, macaddr);
3294 if (!zmac) {
3295 /* create a dummy MAC if the MAC is not already present */
3296 if (IS_ZEBRA_DEBUG_VXLAN)
3297 zlog_debug(
3298 "AUTO MAC %s created for neigh %s on VNI %u",
3299 prefix_mac2str(macaddr, buf, sizeof(buf)),
3300 ipaddr2str(ip, buf2, sizeof(buf2)), zevpn->vni);
3301
3302 zmac = zevpn_mac_add(zevpn, macaddr);
3303 if (!zmac) {
3304 zlog_debug("Failed to add MAC %s VNI %u",
3305 prefix_mac2str(macaddr, buf, sizeof(buf)),
3306 zevpn->vni);
3307 return -1;
3308 }
3309
3310 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
3311 memset(&zmac->flags, 0, sizeof(uint32_t));
3312 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
3313 } else {
3314 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
3315 /*
3316 * We don't change the MAC to local upon a neighbor
3317 * learn event, we wait for the explicit local MAC
3318 * learn. However, we have to compute its sequence
3319 * number in preparation for when it actually turns
3320 * local.
3321 */
3322 upd_mac_seq = true;
3323 }
3324 }
3325
3326 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
3327 if (!zvrf) {
3328 if (IS_ZEBRA_DEBUG_VXLAN)
3329 zlog_debug(" Unable to find vrf for: %d",
3330 zevpn->vxlan_if->vrf_id);
3331 return -1;
3332 }
3333
3334 /* Check if the neighbor exists. */
3335 n = zevpn_neigh_lookup(zevpn, ip);
3336 if (!n) {
3337 /* New neighbor - create */
3338 n = zevpn_neigh_add(zevpn, ip, macaddr, zmac, 0);
3339 if (!n) {
3340 flog_err(
3341 EC_ZEBRA_MAC_ADD_FAILED,
3342 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
3343 ipaddr2str(ip, buf2, sizeof(buf2)),
3344 prefix_mac2str(macaddr, buf, sizeof(buf)),
3345 ifp->name, ifp->ifindex, zevpn->vni);
3346 return -1;
3347 }
3348 /* Set "local" forwarding info. */
3349 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3350 n->ifindex = ifp->ifindex;
3351 created = true;
3352 } else {
3353 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
3354 bool mac_different;
3355 bool cur_is_router;
3356 bool old_local_inactive;
3357
3358 old_local_inactive = !!CHECK_FLAG(n->flags,
3359 ZEBRA_NEIGH_LOCAL_INACTIVE);
3360
3361 old_bgp_ready =
3362 zebra_vxlan_neigh_is_ready_for_bgp(n);
3363
3364 /* Note any changes and see if of interest to BGP. */
3365 mac_different = !!memcmp(&n->emac,
3366 macaddr, ETH_ALEN);
3367 cur_is_router = !!CHECK_FLAG(n->flags,
3368 ZEBRA_NEIGH_ROUTER_FLAG);
3369 new_static = zebra_vxlan_neigh_is_static(n);
3370 if (!mac_different && is_router == cur_is_router &&
3371 old_local_inactive == local_inactive &&
3372 dp_static != new_static) {
3373 if (IS_ZEBRA_DEBUG_VXLAN)
3374 zlog_debug(
3375 " Ignoring entry mac is the same and is_router == cur_is_router");
3376 n->ifindex = ifp->ifindex;
3377 return 0;
3378 }
3379
3380 old_zmac = n->mac;
3381 if (!mac_different) {
3382 /* XXX - cleanup this code duplication */
3383 bool is_neigh_freezed = false;
3384
3385 /* Only the router flag has changed. */
3386 if (is_router)
3387 SET_FLAG(n->flags,
3388 ZEBRA_NEIGH_ROUTER_FLAG);
3389 else
3390 UNSET_FLAG(n->flags,
3391 ZEBRA_NEIGH_ROUTER_FLAG);
3392
3393 if (local_inactive)
3394 SET_FLAG(n->flags,
3395 ZEBRA_NEIGH_LOCAL_INACTIVE);
3396 else
3397 UNSET_FLAG(n->flags,
3398 ZEBRA_NEIGH_LOCAL_INACTIVE);
3399 new_bgp_ready =
3400 zebra_vxlan_neigh_is_ready_for_bgp(n);
3401
3402 /* Neigh is in freeze state and freeze action
3403 * is enabled, do not send update to client.
3404 */
3405 is_neigh_freezed = (zvrf->dup_addr_detect &&
3406 zvrf->dad_freeze &&
3407 CHECK_FLAG(n->flags,
3408 ZEBRA_NEIGH_DUPLICATE));
3409
3410 zevpn_local_neigh_update_log("local", n,
3411 is_router, local_inactive,
3412 old_bgp_ready, new_bgp_ready,
3413 false, false, "flag-update");
3414
3415 /* if the neigh can no longer be advertised
3416 * remove it from bgp
3417 */
3418 if (!is_neigh_freezed) {
3419 zebra_vxlan_neigh_send_add_del_to_client(
3420 n, old_bgp_ready, new_bgp_ready);
3421 } else {
3422 if (IS_ZEBRA_DEBUG_VXLAN &&
3423 IS_ZEBRA_NEIGH_ACTIVE(n))
3424 zlog_debug(
3425 " Neighbor active and frozen");
3426 }
3427 return 0;
3428 }
3429
3430 /* The MAC has changed, need to issue a delete
3431 * first as this means a different MACIP route.
3432 * Also, need to do some unlinking/relinking.
3433 * We also need to update the MAC's sequence number
3434 * in different situations.
3435 */
3436 if (old_bgp_ready) {
3437 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip,
3438 &n->emac, n->flags, n->state,
3439 false /*force*/);
3440 old_bgp_ready = false;
3441 }
3442 if (old_zmac) {
3443 old_mac_seq = CHECK_FLAG(old_zmac->flags,
3444 ZEBRA_MAC_REMOTE) ?
3445 old_zmac->rem_seq : old_zmac->loc_seq;
3446 neigh_mac_change = upd_mac_seq = true;
3447 zebra_vxlan_local_neigh_deref_mac(n,
3448 true /* send_mac_update */);
3449 }
3450
3451 /* if mac changes abandon peer flags and tell
3452 * dataplane to clear the static flag
3453 */
3454 if (zebra_vxlan_neigh_clear_sync_info(n))
3455 inform_dataplane = true;
3456 /* Update the forwarding info. */
3457 n->ifindex = ifp->ifindex;
3458
3459 /* Link to new MAC */
3460 zebra_vxlan_local_neigh_ref_mac(n, macaddr, zmac,
3461 true /* send_mac_update */);
3462 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
3463 /*
3464 * Neighbor has moved from remote to local. Its
3465 * MAC could have also changed as part of the move.
3466 */
3467 if (memcmp(n->emac.octet, macaddr->octet,
3468 ETH_ALEN) != 0) {
3469 old_zmac = n->mac;
3470 if (old_zmac) {
3471 old_mac_seq = CHECK_FLAG(
3472 old_zmac->flags,
3473 ZEBRA_MAC_REMOTE) ?
3474 old_zmac->rem_seq :
3475 old_zmac->loc_seq;
3476 neigh_mac_change = upd_mac_seq = true;
3477 zebra_vxlan_local_neigh_deref_mac(n,
3478 true /* send_update */);
3479 }
3480
3481 /* Link to new MAC */
3482 zebra_vxlan_local_neigh_ref_mac(n, macaddr,
3483 zmac, true /*send_update*/);
3484 }
3485 /* Based on Mobility event Scenario-B from the
3486 * draft, neigh's previous state was remote treat this
3487 * event for DAD.
3488 */
3489 neigh_was_remote = true;
3490 vtep_ip = n->r_vtep_ip;
3491 /* Mark appropriately */
3492 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3493 n->r_vtep_ip.s_addr = INADDR_ANY;
3494 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3495 n->ifindex = ifp->ifindex;
3496 }
3497 }
3498
3499 /* If MAC was previously remote, or the neighbor had a different
3500 * MAC earlier, recompute the sequence number.
3501 */
3502 if (upd_mac_seq) {
3503 uint32_t seq1, seq2;
3504
3505 seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ?
3506 zmac->rem_seq + 1 : zmac->loc_seq;
3507 seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
3508 mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ?
3509 MAX(seq1, seq2) : zmac->loc_seq;
3510 }
3511
3512 if (local_inactive)
3513 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
3514 else
3515 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
3516
3517 /* Mark Router flag (R-bit) */
3518 if (is_router)
3519 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
3520 else
3521 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
3522
3523 /* if the dataplane thinks that this is a sync entry but
3524 * zebra doesn't we need to re-concile the diff
3525 * by re-installing the dataplane entry
3526 */
3527 if (dp_static) {
3528 new_static = zebra_vxlan_neigh_is_static(n);
3529 if (!new_static)
3530 inform_dataplane = true;
3531 }
3532
3533 /* Check old and/or new MAC detected as duplicate mark
3534 * the neigh as duplicate
3535 */
3536 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
3537 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
3538 "VNI %u: MAC %s IP %s detected as duplicate during local update, inherit duplicate from MAC",
3539 zevpn->vni,
3540 prefix_mac2str(macaddr, buf, sizeof(buf)),
3541 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
3542 }
3543
3544 /* For IP Duplicate Address Detection (DAD) is trigger,
3545 * when the event is extended mobility based on scenario-B
3546 * from the draft, IP/Neigh's MAC binding changed and
3547 * neigh's previous state was remote.
3548 */
3549 if (neigh_mac_change && neigh_was_remote)
3550 do_dad = true;
3551
3552 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
3553 &neigh_on_hold, true);
3554
3555 if (inform_dataplane)
3556 zebra_vxlan_sync_neigh_dp_install(n, false /* set_inactive */,
3557 false /* force_clear_static */, __func__);
3558
3559 /* Before we program this in BGP, we need to check if MAC is locally
3560 * learnt. If not, force neighbor to be inactive and reset its seq.
3561 */
3562 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
3563 zevpn_local_neigh_update_log("local",
3564 n, is_router, local_inactive,
3565 false, false, inform_dataplane, false,
3566 "auto-mac");
3567 ZEBRA_NEIGH_SET_INACTIVE(n);
3568 n->loc_seq = 0;
3569 zmac->loc_seq = mac_new_seq;
3570 return 0;
3571 }
3572
3573 zevpn_local_neigh_update_log("local",
3574 n, is_router, local_inactive, false, false, inform_dataplane,
3575 true, created ? "created" : "updated");
3576
3577 /* If the MAC's sequence number has changed, inform the MAC and all
3578 * neighbors associated with the MAC to BGP, else just inform this
3579 * neighbor.
3580 */
3581 if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
3582 if (IS_ZEBRA_DEBUG_VXLAN)
3583 zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
3584 prefix_mac2str(macaddr, buf, sizeof(buf)),
3585 zevpn->vni, zmac->loc_seq, mac_new_seq);
3586 zmac->loc_seq = mac_new_seq;
3587 if (zevpn_mac_send_add_to_client(zevpn->vni, macaddr,
3588 zmac->flags, zmac->loc_seq, zmac->es))
3589 return -1;
3590 zevpn_process_neigh_on_local_mac_change(zevpn, zmac, 1,
3591 0 /*es_change*/);
3592 return 0;
3593 }
3594
3595 n->loc_seq = zmac->loc_seq;
3596
3597 if (!neigh_on_hold) {
3598 ZEBRA_NEIGH_SET_ACTIVE(n);
3599 new_bgp_ready =
3600 zebra_vxlan_neigh_is_ready_for_bgp(n);
3601 zebra_vxlan_neigh_send_add_del_to_client(n,
3602 old_bgp_ready, new_bgp_ready);
3603 } else {
3604 if (IS_ZEBRA_DEBUG_VXLAN)
3605 zlog_debug(" Neighbor on hold not sending");
3606 }
3607 return 0;
3608 }
3609
3610 static int zevpn_remote_neigh_update(zebra_evpn_t *zevpn,
3611 struct interface *ifp,
3612 struct ipaddr *ip,
3613 struct ethaddr *macaddr,
3614 uint16_t state)
3615 {
3616 char buf[ETHER_ADDR_STRLEN];
3617 char buf2[INET6_ADDRSTRLEN];
3618 zebra_neigh_t *n = NULL;
3619 zebra_mac_t *zmac = NULL;
3620
3621 /* If the neighbor is unknown, there is no further action. */
3622 n = zevpn_neigh_lookup(zevpn, ip);
3623 if (!n)
3624 return 0;
3625
3626 /* If a remote entry, see if it needs to be refreshed */
3627 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
3628 #ifdef GNU_LINUX
3629 if (state & NUD_STALE)
3630 zevpn_rem_neigh_install(zevpn, n, false /*was_static*/);
3631 #endif
3632 } else {
3633 /* We got a "remote" neighbor notification for an entry
3634 * we think is local. This can happen in a multihoming
3635 * scenario - but only if the MAC is already "remote".
3636 * Just mark our entry as "remote".
3637 */
3638 zmac = zevpn_mac_lookup(zevpn, macaddr);
3639 if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
3640 zlog_debug(
3641 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
3642 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
3643 prefix_mac2str(macaddr, buf, sizeof(buf)),
3644 zevpn->vni);
3645 return -1;
3646 }
3647
3648 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
3649 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3650 ZEBRA_NEIGH_SET_ACTIVE(n);
3651 n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
3652 }
3653
3654 return 0;
3655 }
3656
3657 /*
3658 * Make hash key for MAC.
3659 */
3660 static unsigned int mac_hash_keymake(const void *p)
3661 {
3662 const zebra_mac_t *pmac = p;
3663 const void *pnt = (void *)pmac->macaddr.octet;
3664
3665 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
3666 }
3667
3668 /*
3669 * Compare two MAC addresses.
3670 */
3671 static bool mac_cmp(const void *p1, const void *p2)
3672 {
3673 const zebra_mac_t *pmac1 = p1;
3674 const zebra_mac_t *pmac2 = p2;
3675
3676 if (pmac1 == NULL && pmac2 == NULL)
3677 return true;
3678
3679 if (pmac1 == NULL || pmac2 == NULL)
3680 return false;
3681
3682 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN)
3683 == 0);
3684 }
3685
3686 /*
3687 * Callback to allocate MAC hash entry.
3688 */
3689 static void *zevpn_mac_alloc(void *p)
3690 {
3691 const zebra_mac_t *tmp_mac = p;
3692 zebra_mac_t *mac;
3693
3694 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
3695 *mac = *tmp_mac;
3696
3697 return ((void *)mac);
3698 }
3699
3700 /*
3701 * Add MAC entry.
3702 */
3703 static zebra_mac_t *zevpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr)
3704 {
3705 zebra_mac_t tmp_mac;
3706 zebra_mac_t *mac = NULL;
3707
3708 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
3709 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
3710 mac = hash_get(zevpn->mac_table, &tmp_mac, zevpn_mac_alloc);
3711 assert(mac);
3712
3713 mac->zevpn = zevpn;
3714 mac->dad_mac_auto_recovery_timer = NULL;
3715
3716 mac->neigh_list = list_new();
3717 mac->neigh_list->cmp = neigh_list_cmp;
3718
3719 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) {
3720 char buf[ETHER_ADDR_STRLEN];
3721
3722 zlog_debug("%s: MAC %s flags 0x%x",
3723 __func__,
3724 prefix_mac2str(&mac->macaddr,
3725 buf, sizeof(buf)),
3726 mac->flags);
3727 }
3728 return mac;
3729 }
3730
3731 /*
3732 * Delete MAC entry.
3733 */
3734 static int zevpn_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac)
3735 {
3736 zebra_mac_t *tmp_mac;
3737
3738 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) {
3739 char buf[ETHER_ADDR_STRLEN];
3740
3741 zlog_debug("%s: MAC %s flags 0x%x",
3742 __func__,
3743 prefix_mac2str(&mac->macaddr,
3744 buf, sizeof(buf)),
3745 mac->flags);
3746 }
3747
3748 /* force de-ref any ES entry linked to the MAC */
3749 zebra_evpn_es_mac_deref_entry(mac);
3750
3751 /* Cancel proxy hold timer */
3752 zebra_vxlan_mac_stop_hold_timer(mac);
3753
3754 /* Cancel auto recovery */
3755 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
3756
3757 list_delete(&mac->neigh_list);
3758
3759 /* Free the VNI hash entry and allocated memory. */
3760 tmp_mac = hash_release(zevpn->mac_table, mac);
3761 XFREE(MTYPE_MAC, tmp_mac);
3762
3763 return 0;
3764 }
3765
3766 static bool zevpn_check_mac_del_from_db(struct mac_walk_ctx *wctx,
3767 zebra_mac_t *mac)
3768 {
3769 if ((wctx->flags & DEL_LOCAL_MAC) &&
3770 (mac->flags & ZEBRA_MAC_LOCAL))
3771 return true;
3772 else if ((wctx->flags & DEL_REMOTE_MAC) &&
3773 (mac->flags & ZEBRA_MAC_REMOTE))
3774 return true;
3775 else if ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP) &&
3776 (mac->flags & ZEBRA_MAC_REMOTE) &&
3777 IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip))
3778 return true;
3779 else if ((wctx->flags & DEL_LOCAL_MAC) &&
3780 (mac->flags & ZEBRA_MAC_AUTO) &&
3781 !listcount(mac->neigh_list)) {
3782 if (IS_ZEBRA_DEBUG_VXLAN) {
3783 char buf[ETHER_ADDR_STRLEN];
3784
3785 zlog_debug(
3786 "%s: Del MAC %s flags 0x%x", __func__,
3787 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
3788 mac->flags);
3789 }
3790 wctx->uninstall = 0;
3791
3792 return true;
3793 }
3794
3795 return false;
3796 }
3797
3798 /*
3799 * Free MAC hash entry (callback)
3800 */
3801 static void zevpn_mac_del_hash_entry(struct hash_bucket *bucket, void *arg)
3802 {
3803 struct mac_walk_ctx *wctx = arg;
3804 zebra_mac_t *mac = bucket->data;
3805
3806 if (zevpn_check_mac_del_from_db(wctx, mac)) {
3807 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
3808 zevpn_mac_send_del_to_client(wctx->zevpn->vni,
3809 &mac->macaddr, mac->flags, false);
3810 }
3811 if (wctx->uninstall) {
3812 if (zebra_vxlan_mac_is_static(mac))
3813 zebra_vxlan_sync_mac_dp_install(mac,
3814 false /* set_inactive */,
3815 true /* force_clear_static */,
3816 __func__);
3817
3818 if (mac->flags & ZEBRA_MAC_REMOTE)
3819 zevpn_rem_mac_uninstall(wctx->zevpn, mac);
3820 }
3821
3822 zevpn_mac_del(wctx->zevpn, mac);
3823 }
3824
3825 return;
3826 }
3827
3828 /*
3829 * Delete all MAC entries for this EVPN.
3830 */
3831 static void zevpn_mac_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client,
3832 uint32_t flags)
3833 {
3834 struct mac_walk_ctx wctx;
3835
3836 if (!zevpn->mac_table)
3837 return;
3838
3839 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
3840 wctx.zevpn = zevpn;
3841 wctx.uninstall = uninstall;
3842 wctx.upd_client = upd_client;
3843 wctx.flags = flags;
3844
3845 hash_iterate(zevpn->mac_table, zevpn_mac_del_hash_entry, &wctx);
3846 }
3847
3848 /*
3849 * Look up MAC hash entry.
3850 */
3851 static zebra_mac_t *zevpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *mac)
3852 {
3853 zebra_mac_t tmp;
3854 zebra_mac_t *pmac;
3855
3856 memset(&tmp, 0, sizeof(tmp));
3857 memcpy(&tmp.macaddr, mac, ETH_ALEN);
3858 pmac = hash_lookup(zevpn->mac_table, &tmp);
3859
3860 return pmac;
3861 }
3862
3863 /*
3864 * Inform BGP about local MAC addition.
3865 */
3866 static int zevpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
3867 uint32_t mac_flags, uint32_t seq, struct zebra_evpn_es *es)
3868 {
3869 uint8_t flags = 0;
3870
3871 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_LOCAL_INACTIVE)) {
3872 /* host reachability has not been verified locally */
3873
3874 /* if no ES peer is claiming reachability we can't advertise the
3875 * entry
3876 */
3877 if (!CHECK_FLAG(mac_flags, ZEBRA_MAC_ES_PEER_ACTIVE))
3878 return 0;
3879
3880 /* ES peers are claiming reachability; we will
3881 * advertise the entry but with a proxy flag
3882 */
3883 SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT);
3884 }
3885
3886 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
3887 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
3888 if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
3889 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
3890
3891 return zevpn_macip_send_msg_to_client(vni, macaddr, NULL, flags,
3892 seq, ZEBRA_NEIGH_ACTIVE, es,
3893 ZEBRA_MACIP_ADD);
3894 }
3895
3896 /*
3897 * Inform BGP about local MAC deletion.
3898 */
3899 static int zevpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
3900 uint32_t flags, bool force)
3901 {
3902 if (!force) {
3903 if (CHECK_FLAG(flags, ZEBRA_MAC_LOCAL_INACTIVE) &&
3904 !CHECK_FLAG(flags, ZEBRA_MAC_ES_PEER_ACTIVE))
3905 /* the host was not advertised - nothing to delete */
3906 return 0;
3907 }
3908
3909 return zevpn_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
3910 0 /* seq */, ZEBRA_NEIGH_ACTIVE, NULL,
3911 ZEBRA_MACIP_DEL);
3912 }
3913
3914 /*
3915 * Map port or (port, VLAN) to an EVPN. This is invoked upon getting MAC
3916 * notifications, to see if they are of interest.
3917 */
3918 static zebra_evpn_t *zevpn_map_vlan(struct interface *ifp,
3919 struct interface *br_if, vlanid_t vid)
3920 {
3921 struct zebra_ns *zns;
3922 struct route_node *rn;
3923 struct interface *tmp_if = NULL;
3924 struct zebra_if *zif;
3925 struct zebra_l2info_bridge *br;
3926 struct zebra_l2info_vxlan *vxl = NULL;
3927 uint8_t bridge_vlan_aware;
3928 zebra_evpn_t *zevpn;
3929 int found = 0;
3930
3931 /* Determine if bridge is VLAN-aware or not */
3932 zif = br_if->info;
3933 assert(zif);
3934 br = &zif->l2info.br;
3935 bridge_vlan_aware = br->vlan_aware;
3936
3937 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3938 /* TODO: Optimize with a hash. */
3939 zns = zebra_ns_lookup(NS_DEFAULT);
3940 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3941 tmp_if = (struct interface *)rn->info;
3942 if (!tmp_if)
3943 continue;
3944 zif = tmp_if->info;
3945 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3946 continue;
3947 if (!if_is_operative(tmp_if))
3948 continue;
3949 vxl = &zif->l2info.vxl;
3950
3951 if (zif->brslave_info.br_if != br_if)
3952 continue;
3953
3954 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3955 found = 1;
3956 break;
3957 }
3958 }
3959
3960 if (!found)
3961 return NULL;
3962
3963 zevpn = zevpn_lookup(vxl->vni);
3964 return zevpn;
3965 }
3966
3967 /*
3968 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3969 * neighbor notifications, to see if they are of interest.
3970 */
3971 static zebra_evpn_t *zevpn_from_svi(struct interface *ifp,
3972 struct interface *br_if)
3973 {
3974 struct zebra_ns *zns;
3975 struct route_node *rn;
3976 struct interface *tmp_if = NULL;
3977 struct zebra_if *zif;
3978 struct zebra_l2info_bridge *br;
3979 struct zebra_l2info_vxlan *vxl = NULL;
3980 uint8_t bridge_vlan_aware;
3981 vlanid_t vid = 0;
3982 zebra_evpn_t *zevpn;
3983 int found = 0;
3984
3985 if (!br_if)
3986 return NULL;
3987
3988 /* Make sure the linked interface is a bridge. */
3989 if (!IS_ZEBRA_IF_BRIDGE(br_if))
3990 return NULL;
3991
3992 /* Determine if bridge is VLAN-aware or not */
3993 zif = br_if->info;
3994 assert(zif);
3995 br = &zif->l2info.br;
3996 bridge_vlan_aware = br->vlan_aware;
3997 if (bridge_vlan_aware) {
3998 struct zebra_l2info_vlan *vl;
3999
4000 if (!IS_ZEBRA_IF_VLAN(ifp))
4001 return NULL;
4002
4003 zif = ifp->info;
4004 assert(zif);
4005 vl = &zif->l2info.vl;
4006 vid = vl->vid;
4007 }
4008
4009 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
4010 /* TODO: Optimize with a hash. */
4011 zns = zebra_ns_lookup(NS_DEFAULT);
4012 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4013 tmp_if = (struct interface *)rn->info;
4014 if (!tmp_if)
4015 continue;
4016 zif = tmp_if->info;
4017 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4018 continue;
4019 if (!if_is_operative(tmp_if))
4020 continue;
4021 vxl = &zif->l2info.vxl;
4022
4023 if (zif->brslave_info.br_if != br_if)
4024 continue;
4025
4026 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
4027 found = 1;
4028 break;
4029 }
4030 }
4031
4032 if (!found)
4033 return NULL;
4034
4035 zevpn = zevpn_lookup(vxl->vni);
4036 return zevpn;
4037 }
4038
4039 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
4040 * of two cases:
4041 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
4042 * linked to the bridge
4043 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge interface
4044 * itself
4045 */
4046 static struct interface *zevpn_map_to_svi(vlanid_t vid, struct interface *br_if)
4047 {
4048 struct zebra_ns *zns;
4049 struct route_node *rn;
4050 struct interface *tmp_if = NULL;
4051 struct zebra_if *zif;
4052 struct zebra_l2info_bridge *br;
4053 struct zebra_l2info_vlan *vl;
4054 uint8_t bridge_vlan_aware;
4055 int found = 0;
4056
4057 /* Defensive check, caller expected to invoke only with valid bridge. */
4058 if (!br_if)
4059 return NULL;
4060
4061 /* Determine if bridge is VLAN-aware or not */
4062 zif = br_if->info;
4063 assert(zif);
4064 br = &zif->l2info.br;
4065 bridge_vlan_aware = br->vlan_aware;
4066
4067 /* Check oper status of the SVI. */
4068 if (!bridge_vlan_aware)
4069 return if_is_operative(br_if) ? br_if : NULL;
4070
4071 /* Identify corresponding VLAN interface. */
4072 /* TODO: Optimize with a hash. */
4073 zns = zebra_ns_lookup(NS_DEFAULT);
4074 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4075 tmp_if = (struct interface *)rn->info;
4076 /* Check oper status of the SVI. */
4077 if (!tmp_if || !if_is_operative(tmp_if))
4078 continue;
4079 zif = tmp_if->info;
4080 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
4081 || zif->link != br_if)
4082 continue;
4083 vl = &zif->l2info.vl;
4084
4085 if (vl->vid == vid) {
4086 found = 1;
4087 break;
4088 }
4089 }
4090
4091 return found ? tmp_if : NULL;
4092 }
4093
4094 /* Map to MAC-VLAN interface corresponding to specified SVI interface.
4095 */
4096 static struct interface *zevpn_map_to_macvlan(struct interface *br_if,
4097 struct interface *svi_if)
4098 {
4099 struct zebra_ns *zns;
4100 struct route_node *rn;
4101 struct interface *tmp_if = NULL;
4102 struct zebra_if *zif;
4103 int found = 0;
4104
4105 /* Defensive check, caller expected to invoke only with valid bridge. */
4106 if (!br_if)
4107 return NULL;
4108
4109 if (!svi_if) {
4110 zlog_debug("svi_if is not passed.");
4111 return NULL;
4112 }
4113
4114 /* Determine if bridge is VLAN-aware or not */
4115 zif = br_if->info;
4116 assert(zif);
4117
4118 /* Identify corresponding VLAN interface. */
4119 zns = zebra_ns_lookup(NS_DEFAULT);
4120 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4121 tmp_if = (struct interface *)rn->info;
4122 /* Check oper status of the SVI. */
4123 if (!tmp_if || !if_is_operative(tmp_if))
4124 continue;
4125 zif = tmp_if->info;
4126
4127 if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN)
4128 continue;
4129
4130 if (zif->link == svi_if) {
4131 found = 1;
4132 break;
4133 }
4134 }
4135
4136 return found ? tmp_if : NULL;
4137 }
4138
4139
4140 /*
4141 * Install remote MAC into the forwarding plane.
4142 */
4143 static int zevpn_rem_mac_install(zebra_evpn_t *zevpn, zebra_mac_t *mac,
4144 bool was_static)
4145 {
4146 const struct zebra_if *zif, *br_zif;
4147 const struct zebra_l2info_vxlan *vxl;
4148 bool sticky;
4149 enum zebra_dplane_result res;
4150 const struct interface *br_ifp;
4151 vlanid_t vid;
4152 uint32_t nhg_id;
4153 struct in_addr vtep_ip;
4154
4155 if (!(mac->flags & ZEBRA_MAC_REMOTE))
4156 return 0;
4157
4158 zif = zevpn->vxlan_if->info;
4159 if (!zif)
4160 return -1;
4161
4162 br_ifp = zif->brslave_info.br_if;
4163 if (br_ifp == NULL)
4164 return -1;
4165
4166 vxl = &zif->l2info.vxl;
4167
4168 sticky = !!CHECK_FLAG(mac->flags,
4169 (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
4170
4171 /* If nexthop group for the FDB entry is inactive (not programmed in
4172 * the dataplane) the MAC entry cannot be installed
4173 */
4174 if (mac->es) {
4175 if (!(mac->es->flags & ZEBRA_EVPNES_NHG_ACTIVE))
4176 return -1;
4177 nhg_id = mac->es->nhg_id;
4178 vtep_ip.s_addr = 0;
4179 } else {
4180 nhg_id = 0;
4181 vtep_ip = mac->fwd_info.r_vtep_ip;
4182 }
4183
4184 br_zif = (const struct zebra_if *)(br_ifp->info);
4185
4186 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
4187 vid = vxl->access_vlan;
4188 else
4189 vid = 0;
4190
4191 res = dplane_rem_mac_add(zevpn->vxlan_if, br_ifp, vid,
4192 &mac->macaddr, vtep_ip, sticky,
4193 nhg_id, was_static);
4194 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
4195 return 0;
4196 else
4197 return -1;
4198 }
4199
4200 /*
4201 * Uninstall remote MAC from the forwarding plane.
4202 */
4203 static int zevpn_rem_mac_uninstall(zebra_evpn_t *zevpn, zebra_mac_t *mac)
4204 {
4205 const struct zebra_if *zif, *br_zif;
4206 const struct zebra_l2info_vxlan *vxl;
4207 struct in_addr vtep_ip;
4208 const struct interface *ifp, *br_ifp;
4209 vlanid_t vid;
4210 enum zebra_dplane_result res;
4211
4212 if (!(mac->flags & ZEBRA_MAC_REMOTE))
4213 return 0;
4214
4215 if (!zevpn->vxlan_if) {
4216 if (IS_ZEBRA_DEBUG_VXLAN)
4217 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
4218 zevpn->vni, zevpn);
4219 return -1;
4220 }
4221
4222 zif = zevpn->vxlan_if->info;
4223 if (!zif)
4224 return -1;
4225
4226 br_ifp = zif->brslave_info.br_if;
4227 if (br_ifp == NULL)
4228 return -1;
4229
4230 vxl = &zif->l2info.vxl;
4231
4232 br_zif = (const struct zebra_if *)br_ifp->info;
4233
4234 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
4235 vid = vxl->access_vlan;
4236 else
4237 vid = 0;
4238
4239 ifp = zevpn->vxlan_if;
4240 vtep_ip = mac->fwd_info.r_vtep_ip;
4241
4242 res = dplane_rem_mac_del(ifp, br_ifp, vid, &mac->macaddr, vtep_ip);
4243 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
4244 return 0;
4245 else
4246 return -1;
4247 }
4248
4249 /*
4250 * Install MAC hash entry - called upon access VLAN change.
4251 */
4252 static void zevpn_install_mac_hash(struct hash_bucket *bucket, void *ctxt)
4253 {
4254 zebra_mac_t *mac;
4255 struct mac_walk_ctx *wctx = ctxt;
4256
4257 mac = (zebra_mac_t *)bucket->data;
4258
4259 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
4260 zevpn_rem_mac_install(wctx->zevpn, mac, false);
4261 }
4262
4263 /*
4264 * Count of remote neighbors referencing this MAC.
4265 */
4266 static int remote_neigh_count(zebra_mac_t *zmac)
4267 {
4268 zebra_neigh_t *n = NULL;
4269 struct listnode *node = NULL;
4270 int count = 0;
4271
4272 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
4273 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
4274 count++;
4275 }
4276
4277 return count;
4278 }
4279
4280 /*
4281 * Decrement neighbor refcount of MAC; uninstall and free it if
4282 * appropriate.
4283 */
4284 static void zevpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac)
4285 {
4286 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
4287 return;
4288
4289 /* If all remote neighbors referencing a remote MAC go away,
4290 * we need to uninstall the MAC.
4291 */
4292 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
4293 remote_neigh_count(mac) == 0) {
4294 zevpn_rem_mac_uninstall(zevpn, mac);
4295 zebra_evpn_es_mac_deref_entry(mac);
4296 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
4297 }
4298
4299 /* If no neighbors, delete the MAC. */
4300 if (list_isempty(mac->neigh_list))
4301 zevpn_mac_del(zevpn, mac);
4302 }
4303
4304 /*
4305 * Read and populate local MACs and neighbors corresponding to this EVPN.
4306 */
4307 static void zevpn_read_mac_neigh(zebra_evpn_t *zevpn, struct interface *ifp)
4308 {
4309 struct zebra_ns *zns;
4310 struct zebra_if *zif;
4311 struct interface *vlan_if;
4312 struct zebra_l2info_vxlan *vxl;
4313 struct interface *vrr_if;
4314
4315 zif = ifp->info;
4316 vxl = &zif->l2info.vxl;
4317 zns = zebra_ns_lookup(NS_DEFAULT);
4318
4319 if (IS_ZEBRA_DEBUG_VXLAN)
4320 zlog_debug(
4321 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
4322 ifp->name, ifp->ifindex, zevpn->vni,
4323 zif->brslave_info.bridge_ifindex);
4324
4325 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
4326 vlan_if = zevpn_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
4327 if (vlan_if) {
4328
4329 /* Add SVI MAC-IP */
4330 zevpn_add_macip_for_intf(vlan_if, zevpn);
4331
4332 /* Add VRR MAC-IP - if any*/
4333 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
4334 if (vrr_if)
4335 zevpn_add_macip_for_intf(vrr_if, zevpn);
4336
4337 neigh_read_for_vlan(zns, vlan_if);
4338 }
4339 }
4340
4341 /*
4342 * Hash function for VNI.
4343 */
4344 static unsigned int evpn_hash_keymake(const void *p)
4345 {
4346 const zebra_evpn_t *zevpn = p;
4347
4348 return (jhash_1word(zevpn->vni, 0));
4349 }
4350
4351 /*
4352 * Compare 2 VNI hash entries.
4353 */
4354 static bool vni_hash_cmp(const void *p1, const void *p2)
4355 {
4356 const zebra_evpn_t *zevpn1 = p1;
4357 const zebra_evpn_t *zevpn2 = p2;
4358
4359 return (zevpn1->vni == zevpn2->vni);
4360 }
4361
4362 int vni_list_cmp(void *p1, void *p2)
4363 {
4364 const zebra_evpn_t *zevpn1 = p1;
4365 const zebra_evpn_t *zevpn2 = p2;
4366
4367 if (zevpn1->vni == zevpn2->vni)
4368 return 0;
4369 return (zevpn1->vni < zevpn2->vni) ? -1 : 1;
4370 }
4371
4372 /*
4373 * Callback to allocate VNI hash entry.
4374 */
4375 static void *zevpn_alloc(void *p)
4376 {
4377 const zebra_evpn_t *tmp_vni = p;
4378 zebra_evpn_t *zevpn;
4379
4380 zevpn = XCALLOC(MTYPE_ZEVPN, sizeof(zebra_evpn_t));
4381 zevpn->vni = tmp_vni->vni;
4382 return ((void *)zevpn);
4383 }
4384
4385 /*
4386 * Look up EVPN hash entry.
4387 */
4388 zebra_evpn_t *zevpn_lookup(vni_t vni)
4389 {
4390 struct zebra_vrf *zvrf;
4391 zebra_evpn_t tmp_vni;
4392 zebra_evpn_t *zevpn = NULL;
4393
4394 zvrf = zebra_vrf_get_evpn();
4395 assert(zvrf);
4396 memset(&tmp_vni, 0, sizeof(zebra_evpn_t));
4397 tmp_vni.vni = vni;
4398 zevpn = hash_lookup(zvrf->evpn_table, &tmp_vni);
4399
4400 return zevpn;
4401 }
4402
4403 /*
4404 * Add EVPN hash entry.
4405 */
4406 static zebra_evpn_t *zevpn_add(vni_t vni)
4407 {
4408 struct zebra_vrf *zvrf;
4409 zebra_evpn_t tmp_zevpn;
4410 zebra_evpn_t *zevpn = NULL;
4411
4412 zvrf = zebra_vrf_get_evpn();
4413 assert(zvrf);
4414 memset(&tmp_zevpn, 0, sizeof(zebra_evpn_t));
4415 tmp_zevpn.vni = vni;
4416 zevpn = hash_get(zvrf->evpn_table, &tmp_zevpn, zevpn_alloc);
4417 assert(zevpn);
4418
4419 zebra_evpn_evpn_es_init(zevpn);
4420
4421 /* Create hash table for MAC */
4422 zevpn->mac_table =
4423 hash_create(mac_hash_keymake, mac_cmp, "Zebra EVPN MAC Table");
4424
4425 /* Create hash table for neighbors */
4426 zevpn->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
4427 "Zebra EVPN Neighbor Table");
4428
4429 return zevpn;
4430 }
4431
4432 /* EVPN<=>vxlan_zif association */
4433 static void zevpn_vxlan_if_set(zebra_evpn_t *zevpn, struct interface *ifp,
4434 bool set)
4435 {
4436 struct zebra_if *zif;
4437
4438 if (set) {
4439 if (zevpn->vxlan_if == ifp)
4440 return;
4441 zevpn->vxlan_if = ifp;
4442 } else {
4443 if (!zevpn->vxlan_if)
4444 return;
4445 zevpn->vxlan_if = NULL;
4446 }
4447
4448 if (ifp)
4449 zif = ifp->info;
4450 else
4451 zif = NULL;
4452
4453 zebra_evpn_vxl_evpn_set(zif, zevpn, set);
4454 }
4455
4456 /*
4457 * Delete EVPN hash entry.
4458 */
4459 static int zevpn_del(zebra_evpn_t *zevpn)
4460 {
4461 struct zebra_vrf *zvrf;
4462 zebra_evpn_t *tmp_zevpn;
4463
4464 zvrf = zebra_vrf_get_evpn();
4465 assert(zvrf);
4466
4467 zevpn_vxlan_if_set(zevpn, zevpn->vxlan_if, false /* set */);
4468
4469 /* Remove references to the BUM mcast grp */
4470 zebra_vxlan_sg_deref(zevpn->local_vtep_ip, zevpn->mcast_grp);
4471
4472 /* Free the neighbor hash table. */
4473 hash_free(zevpn->neigh_table);
4474 zevpn->neigh_table = NULL;
4475
4476 /* Free the MAC hash table. */
4477 hash_free(zevpn->mac_table);
4478 zevpn->mac_table = NULL;
4479
4480 zebra_evpn_evpn_es_cleanup(zevpn);
4481
4482 /* Free the EVPN hash entry and allocated memory. */
4483 tmp_zevpn = hash_release(zvrf->evpn_table, zevpn);
4484 XFREE(MTYPE_ZEVPN, tmp_zevpn);
4485
4486 return 0;
4487 }
4488
4489 /*
4490 * Inform BGP about local EVPN addition.
4491 */
4492 static int zevpn_send_add_to_client(zebra_evpn_t *zevpn)
4493 {
4494 struct zserv *client;
4495 struct stream *s;
4496 int rc;
4497
4498 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4499 /* BGP may not be running. */
4500 if (!client)
4501 return 0;
4502
4503 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4504
4505 zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
4506 stream_putl(s, zevpn->vni);
4507 stream_put_in_addr(s, &zevpn->local_vtep_ip);
4508 stream_put(s, &zevpn->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
4509 stream_put_in_addr(s, &zevpn->mcast_grp);
4510
4511 /* Write packet size. */
4512 stream_putw_at(s, 0, stream_get_endp(s));
4513
4514 if (IS_ZEBRA_DEBUG_VXLAN)
4515 zlog_debug("Send EVPN_ADD %u %s tenant vrf %s to %s", zevpn->vni,
4516 inet_ntoa(zevpn->local_vtep_ip),
4517 vrf_id_to_name(zevpn->vrf_id),
4518 zebra_route_string(client->proto));
4519
4520 client->vniadd_cnt++;
4521 rc = zserv_send_message(client, s);
4522
4523 if (!(zevpn->flags & ZEVPN_READY_FOR_BGP)) {
4524 zevpn->flags |= ZEVPN_READY_FOR_BGP;
4525 /* once the EVPN is sent the ES-EVIs can also be replayed
4526 * to BGP
4527 */
4528 zebra_evpn_update_all_es(zevpn);
4529 }
4530 return rc;
4531 }
4532
4533 /*
4534 * Inform BGP about local EVPN deletion.
4535 */
4536 static int zevpn_send_del_to_client(zebra_evpn_t *zevpn)
4537 {
4538 struct zserv *client;
4539 struct stream *s;
4540
4541 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
4542 /* BGP may not be running. */
4543 if (!client)
4544 return 0;
4545
4546 if (zevpn->flags & ZEVPN_READY_FOR_BGP) {
4547 zevpn->flags &= ~ZEVPN_READY_FOR_BGP;
4548 /* the ES-EVIs must be removed from BGP before the EVPN is */
4549 zebra_evpn_update_all_es(zevpn);
4550 }
4551
4552 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
4553 stream_reset(s);
4554
4555 zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
4556 stream_putl(s, zevpn->vni);
4557
4558 /* Write packet size. */
4559 stream_putw_at(s, 0, stream_get_endp(s));
4560
4561 if (IS_ZEBRA_DEBUG_VXLAN)
4562 zlog_debug("Send EVPN_DEL %u to %s", zevpn->vni,
4563 zebra_route_string(client->proto));
4564
4565 client->vnidel_cnt++;
4566 return zserv_send_message(client, s);
4567 }
4568
4569 /*
4570 * Build the VNI hash table by going over the VxLAN interfaces. This
4571 * is called when EVPN (advertise-all-vni) is enabled.
4572 */
4573 static void zevpn_build_hash_table(void)
4574 {
4575 struct zebra_ns *zns;
4576 struct route_node *rn;
4577 struct interface *ifp;
4578
4579 /* Walk VxLAN interfaces and create EVPN hash. */
4580 zns = zebra_ns_lookup(NS_DEFAULT);
4581 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
4582 vni_t vni;
4583 zebra_evpn_t *zevpn = NULL;
4584 zebra_l3vni_t *zl3vni = NULL;
4585 struct zebra_if *zif;
4586 struct zebra_l2info_vxlan *vxl;
4587
4588 ifp = (struct interface *)rn->info;
4589 if (!ifp)
4590 continue;
4591 zif = ifp->info;
4592 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
4593 continue;
4594
4595 vxl = &zif->l2info.vxl;
4596 vni = vxl->vni;
4597
4598 /* L3-VNI and L2-VNI are handled seperately */
4599 zl3vni = zl3vni_lookup(vni);
4600 if (zl3vni) {
4601
4602 if (IS_ZEBRA_DEBUG_VXLAN)
4603 zlog_debug(
4604 "create L3-VNI hash for Intf %s(%u) L3-VNI %u",
4605 ifp->name, ifp->ifindex, vni);
4606
4607 /* associate with vxlan_if */
4608 zl3vni->local_vtep_ip = vxl->vtep_ip;
4609 zl3vni->vxlan_if = ifp;
4610
4611 /*
4612 * we need to associate with SVI.
4613 * we can associate with svi-if only after association
4614 * with vxlan-intf is complete
4615 */
4616 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
4617
4618 /* Associate l3vni to mac-vlan and extract VRR MAC */
4619 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
4620
4621 if (IS_ZEBRA_DEBUG_VXLAN)
4622 zlog_debug("create l3vni %u svi_if %s mac_vlan_if %s",
4623 vni, zl3vni->svi_if ? zl3vni->svi_if->name
4624 : "NIL",
4625 zl3vni->mac_vlan_if ?
4626 zl3vni->mac_vlan_if->name : "NIL");
4627
4628 if (is_l3vni_oper_up(zl3vni))
4629 zebra_vxlan_process_l3vni_oper_up(zl3vni);
4630
4631 } else {
4632 struct interface *vlan_if = NULL;
4633
4634 if (IS_ZEBRA_DEBUG_VXLAN)
4635 zlog_debug(
4636 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
4637 ifp->name, ifp->ifindex, vni,
4638 inet_ntoa(vxl->vtep_ip));
4639
4640 /* EVPN hash entry is expected to exist, if the BGP process is killed */
4641 zevpn = zevpn_lookup(vni);
4642 if (zevpn) {
4643 zlog_debug(
4644 "EVPN hash already present for IF %s(%u) L2-VNI %u",
4645 ifp->name, ifp->ifindex, vni);
4646
4647 /*
4648 * Inform BGP if intf is up and mapped to
4649 * bridge.
4650 */
4651 if (if_is_operative(ifp) &&
4652 zif->brslave_info.br_if)
4653 zevpn_send_add_to_client(zevpn);
4654
4655 /* Send Local MAC-entries to client */
4656 zevpn_send_mac_to_client(zevpn);
4657
4658 /* Send Loval Neighbor entries to client */
4659 zevpn_send_neigh_to_client(zevpn);
4660 } else {
4661 zevpn = zevpn_add(vni);
4662 if (!zevpn) {
4663 zlog_debug(
4664 "Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
4665 ifp->name, ifp->ifindex, vni);
4666 return;
4667 }
4668
4669 if (zevpn->local_vtep_ip.s_addr !=
4670 vxl->vtep_ip.s_addr ||
4671 zevpn->mcast_grp.s_addr !=
4672 vxl->mcast_grp.s_addr) {
4673 zebra_vxlan_sg_deref(
4674 zevpn->local_vtep_ip,
4675 zevpn->mcast_grp);
4676 zebra_vxlan_sg_ref(vxl->vtep_ip,
4677 vxl->mcast_grp);
4678 zevpn->local_vtep_ip = vxl->vtep_ip;
4679 zevpn->mcast_grp = vxl->mcast_grp;
4680 /* on local vtep-ip check if ES
4681 * orig-ip needs to be updated
4682 */
4683 zebra_evpn_es_set_base_evpn(zevpn);
4684 }
4685 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
4686 vlan_if = zevpn_map_to_svi(vxl->access_vlan,
4687 zif->brslave_info.br_if);
4688 if (vlan_if) {
4689 zevpn->vrf_id = vlan_if->vrf_id;
4690 zl3vni = zl3vni_from_vrf(
4691 vlan_if->vrf_id);
4692 if (zl3vni)
4693 listnode_add_sort(
4694 zl3vni->l2vnis, zevpn);
4695 }
4696
4697 /*
4698 * Inform BGP if intf is up and mapped to
4699 * bridge.
4700 */
4701 if (if_is_operative(ifp) &&
4702 zif->brslave_info.br_if)
4703 zevpn_send_add_to_client(zevpn);
4704 }
4705 }
4706 }
4707 }
4708
4709 /*
4710 * See if remote VTEP matches with prefix.
4711 */
4712 static int zevpn_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
4713 {
4714 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
4715 }
4716
4717 /*
4718 * Locate remote VTEP in EVPN hash table.
4719 */
4720 static zebra_vtep_t *zevpn_vtep_find(zebra_evpn_t *zevpn, struct in_addr *vtep_ip)
4721 {
4722 zebra_vtep_t *zvtep;
4723
4724 if (!zevpn)
4725 return NULL;
4726
4727 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
4728 if (zevpn_vtep_match(vtep_ip, zvtep))
4729 break;
4730 }
4731
4732 return zvtep;
4733 }
4734
4735 /*
4736 * Add remote VTEP to EVPN hash table.
4737 */
4738 static zebra_vtep_t *zevpn_vtep_add(zebra_evpn_t *zevpn, struct in_addr *vtep_ip,
4739 int flood_control)
4740
4741 {
4742 zebra_vtep_t *zvtep;
4743
4744 zvtep = XCALLOC(MTYPE_ZEVPN_VTEP, sizeof(zebra_vtep_t));
4745
4746 zvtep->vtep_ip = *vtep_ip;
4747 zvtep->flood_control = flood_control;
4748
4749 if (zevpn->vteps)
4750 zevpn->vteps->prev = zvtep;
4751 zvtep->next = zevpn->vteps;
4752 zevpn->vteps = zvtep;
4753
4754 return zvtep;
4755 }
4756
4757 /*
4758 * Remove remote VTEP from EVPN hash table.
4759 */
4760 static int zevpn_vtep_del(zebra_evpn_t *zevpn, zebra_vtep_t *zvtep)
4761 {
4762 if (zvtep->next)
4763 zvtep->next->prev = zvtep->prev;
4764 if (zvtep->prev)
4765 zvtep->prev->next = zvtep->next;
4766 else
4767 zevpn->vteps = zvtep->next;
4768
4769 zvtep->prev = zvtep->next = NULL;
4770 XFREE(MTYPE_ZEVPN_VTEP, zvtep);
4771
4772 return 0;
4773 }
4774
4775 /*
4776 * Delete all remote VTEPs for this EVPN (upon VNI delete). Also
4777 * uninstall from kernel if asked to.
4778 */
4779 static int zevpn_vtep_del_all(zebra_evpn_t *zevpn, int uninstall)
4780 {
4781 zebra_vtep_t *zvtep, *zvtep_next;
4782
4783 if (!zevpn)
4784 return -1;
4785
4786 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep_next) {
4787 zvtep_next = zvtep->next;
4788 if (uninstall)
4789 zevpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
4790 zevpn_vtep_del(zevpn, zvtep);
4791 }
4792
4793 return 0;
4794 }
4795
4796 /*
4797 * Install remote VTEP into the kernel if the remote VTEP has asked
4798 * for head-end-replication.
4799 */
4800 static int zevpn_vtep_install(zebra_evpn_t *zevpn, zebra_vtep_t *zvtep)
4801 {
4802 if (is_vxlan_flooding_head_end() &&
4803 (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL)) {
4804 if (ZEBRA_DPLANE_REQUEST_FAILURE ==
4805 dplane_vtep_add(zevpn->vxlan_if,
4806 &zvtep->vtep_ip, zevpn->vni))
4807 return -1;
4808 }
4809
4810 return 0;
4811 }
4812
4813 /*
4814 * Uninstall remote VTEP from the kernel.
4815 */
4816 static int zevpn_vtep_uninstall(zebra_evpn_t *zevpn, struct in_addr *vtep_ip)
4817 {
4818 if (!zevpn->vxlan_if) {
4819 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
4820 zevpn->vni, zevpn);
4821 return -1;
4822 }
4823
4824 if (ZEBRA_DPLANE_REQUEST_FAILURE ==
4825 dplane_vtep_delete(zevpn->vxlan_if, vtep_ip, zevpn->vni))
4826 return -1;
4827
4828 return 0;
4829 }
4830
4831 /*
4832 * Install or uninstall flood entries in the kernel corresponding to
4833 * remote VTEPs. This is invoked upon change to BUM handling.
4834 */
4835 static void zevpn_handle_flooding_remote_vteps(struct hash_bucket *bucket,
4836 void *zvrf)
4837 {
4838 zebra_evpn_t *zevpn;
4839 zebra_vtep_t *zvtep;
4840
4841 zevpn = (zebra_evpn_t *)bucket->data;
4842 if (!zevpn)
4843 return;
4844
4845 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
4846 if (is_vxlan_flooding_head_end())
4847 zevpn_vtep_install(zevpn, zvtep);
4848 else
4849 zevpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
4850 }
4851 }
4852
4853 /*
4854 * Cleanup EVPN/VTEP and update kernel
4855 */
4856 static void zevpn_cleanup_all(struct hash_bucket *bucket, void *arg)
4857 {
4858 zebra_evpn_t *zevpn = NULL;
4859 zebra_l3vni_t *zl3vni = NULL;
4860 struct zebra_vrf *zvrf = (struct zebra_vrf *)arg;
4861
4862 zevpn = (zebra_evpn_t *)bucket->data;
4863
4864 /* remove from l3-vni list */
4865 if (zvrf->l3vni)
4866 zl3vni = zl3vni_lookup(zvrf->l3vni);
4867 if (zl3vni)
4868 listnode_delete(zl3vni->l2vnis, zevpn);
4869
4870 /* Free up all neighbors and MACs, if any. */
4871 zevpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
4872 zevpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
4873
4874 /* Free up all remote VTEPs, if any. */
4875 zevpn_vtep_del_all(zevpn, 1);
4876
4877 /* Delete the hash entry. */
4878 zevpn_del(zevpn);
4879 }
4880
4881 /* cleanup L3VNI */
4882 static void zl3vni_cleanup_all(struct hash_bucket *bucket, void *args)
4883 {
4884 zebra_l3vni_t *zl3vni = NULL;
4885
4886 zl3vni = (zebra_l3vni_t *)bucket->data;
4887
4888 zebra_vxlan_process_l3vni_oper_down(zl3vni);
4889 }
4890
4891 static void rb_find_or_add_host(struct host_rb_tree_entry *hrbe,
4892 const struct prefix *host)
4893 {
4894 struct host_rb_entry lookup;
4895 struct host_rb_entry *hle;
4896
4897 memset(&lookup, 0, sizeof(lookup));
4898 memcpy(&lookup.p, host, sizeof(*host));
4899
4900 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
4901 if (hle)
4902 return;
4903
4904 hle = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct host_rb_entry));
4905 memcpy(hle, &lookup, sizeof(lookup));
4906
4907 RB_INSERT(host_rb_tree_entry, hrbe, hle);
4908 }
4909
4910 static void rb_delete_host(struct host_rb_tree_entry *hrbe, struct prefix *host)
4911 {
4912 struct host_rb_entry lookup;
4913 struct host_rb_entry *hle;
4914
4915 memset(&lookup, 0, sizeof(lookup));
4916 memcpy(&lookup.p, host, sizeof(*host));
4917
4918 hle = RB_FIND(host_rb_tree_entry, hrbe, &lookup);
4919 if (hle) {
4920 RB_REMOVE(host_rb_tree_entry, hrbe, hle);
4921 XFREE(MTYPE_HOST_PREFIX, hle);
4922 }
4923
4924 return;
4925 }
4926
4927 /*
4928 * Look up MAC hash entry.
4929 */
4930 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
4931 const struct ethaddr *rmac)
4932 {
4933 zebra_mac_t tmp;
4934 zebra_mac_t *pmac;
4935
4936 memset(&tmp, 0, sizeof(tmp));
4937 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
4938 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
4939
4940 return pmac;
4941 }
4942
4943 /*
4944 * Callback to allocate RMAC hash entry.
4945 */
4946 static void *zl3vni_rmac_alloc(void *p)
4947 {
4948 const zebra_mac_t *tmp_rmac = p;
4949 zebra_mac_t *zrmac;
4950
4951 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
4952 *zrmac = *tmp_rmac;
4953
4954 return ((void *)zrmac);
4955 }
4956
4957 /*
4958 * Add RMAC entry to l3-vni
4959 */
4960 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
4961 const struct ethaddr *rmac)
4962 {
4963 zebra_mac_t tmp_rmac;
4964 zebra_mac_t *zrmac = NULL;
4965
4966 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
4967 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
4968 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
4969 assert(zrmac);
4970
4971 RB_INIT(host_rb_tree_entry, &zrmac->host_rb);
4972
4973 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
4974 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
4975
4976 return zrmac;
4977 }
4978
4979 /*
4980 * Delete MAC entry.
4981 */
4982 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
4983 {
4984 zebra_mac_t *tmp_rmac;
4985 struct host_rb_entry *hle;
4986
4987 while (!RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
4988 hle = RB_ROOT(host_rb_tree_entry, &zrmac->host_rb);
4989
4990 RB_REMOVE(host_rb_tree_entry, &zrmac->host_rb, hle);
4991 XFREE(MTYPE_HOST_PREFIX, hle);
4992 }
4993
4994 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
4995 XFREE(MTYPE_MAC, tmp_rmac);
4996
4997 return 0;
4998 }
4999
5000 /*
5001 * Install remote RMAC into the forwarding plane.
5002 */
5003 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
5004 {
5005 const struct zebra_if *zif = NULL, *br_zif = NULL;
5006 const struct zebra_l2info_vxlan *vxl = NULL;
5007 const struct interface *br_ifp;
5008 enum zebra_dplane_result res;
5009 vlanid_t vid;
5010
5011 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
5012 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
5013 return 0;
5014
5015 zif = zl3vni->vxlan_if->info;
5016 if (!zif)
5017 return -1;
5018
5019 br_ifp = zif->brslave_info.br_if;
5020 if (br_ifp == NULL)
5021 return -1;
5022
5023 vxl = &zif->l2info.vxl;
5024
5025 br_zif = (const struct zebra_if *)br_ifp->info;
5026
5027 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
5028 vid = vxl->access_vlan;
5029 else
5030 vid = 0;
5031
5032 res = dplane_rem_mac_add(zl3vni->vxlan_if, br_ifp, vid,
5033 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0, 0,
5034 false /*was_static*/);
5035 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
5036 return 0;
5037 else
5038 return -1;
5039 }
5040
5041 /*
5042 * Uninstall remote RMAC from the forwarding plane.
5043 */
5044 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
5045 {
5046 char buf[ETHER_ADDR_STRLEN];
5047 const struct zebra_if *zif = NULL, *br_zif;
5048 const struct zebra_l2info_vxlan *vxl = NULL;
5049 const struct interface *br_ifp;
5050 vlanid_t vid;
5051 enum zebra_dplane_result res;
5052
5053 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
5054 || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
5055 return 0;
5056
5057 if (!zl3vni->vxlan_if) {
5058 if (IS_ZEBRA_DEBUG_VXLAN)
5059 zlog_debug(
5060 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
5061 prefix_mac2str(&zrmac->macaddr,
5062 buf, sizeof(buf)),
5063 zl3vni->vni, zl3vni);
5064 return -1;
5065 }
5066
5067 zif = zl3vni->vxlan_if->info;
5068 if (!zif)
5069 return -1;
5070
5071 br_ifp = zif->brslave_info.br_if;
5072 if (br_ifp == NULL)
5073 return -1;
5074
5075 vxl = &zif->l2info.vxl;
5076
5077 br_zif = (const struct zebra_if *)br_ifp->info;
5078 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
5079 vid = vxl->access_vlan;
5080 else
5081 vid = 0;
5082
5083 res = dplane_rem_mac_del(zl3vni->vxlan_if, br_ifp, vid,
5084 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
5085 if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
5086 return 0;
5087 else
5088 return -1;
5089 }
5090
5091 /* handle rmac add */
5092 static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
5093 const struct ethaddr *rmac,
5094 const struct ipaddr *vtep_ip,
5095 const struct prefix *host_prefix)
5096 {
5097 char buf[ETHER_ADDR_STRLEN];
5098 char buf1[INET6_ADDRSTRLEN];
5099 char buf2[PREFIX_STRLEN];
5100 zebra_mac_t *zrmac = NULL;
5101
5102 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
5103 if (!zrmac) {
5104
5105 /* Create the RMAC entry, or update its vtep, if necessary. */
5106 zrmac = zl3vni_rmac_add(zl3vni, rmac);
5107 if (!zrmac) {
5108 zlog_debug(
5109 "Failed to add RMAC %s L3VNI %u Remote VTEP %s, prefix %s",
5110 prefix_mac2str(rmac, buf, sizeof(buf)),
5111 zl3vni->vni,
5112 ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
5113 prefix2str(host_prefix, buf2, sizeof(buf2)));
5114 return -1;
5115 }
5116 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
5117 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
5118
5119 /* Send RMAC for FPM processing */
5120 hook_call(zebra_rmac_update, zrmac, zl3vni, false,
5121 "new RMAC added");
5122
5123 /* install rmac in kernel */
5124 zl3vni_rmac_install(zl3vni, zrmac);
5125 } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
5126 &vtep_ip->ipaddr_v4)) {
5127 if (IS_ZEBRA_DEBUG_VXLAN)
5128 zlog_debug(
5129 "L3VNI %u Remote VTEP change(%s -> %s) for RMAC %s, prefix %s",
5130 zl3vni->vni,
5131 inet_ntoa(zrmac->fwd_info.r_vtep_ip),
5132 ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
5133 prefix_mac2str(rmac, buf, sizeof(buf)),
5134 prefix2str(host_prefix, buf2, sizeof(buf2)));
5135
5136 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
5137
5138 /* install rmac in kernel */
5139 zl3vni_rmac_install(zl3vni, zrmac);
5140 }
5141
5142 rb_find_or_add_host(&zrmac->host_rb, host_prefix);
5143
5144 return 0;
5145 }
5146
5147
5148 /* handle rmac delete */
5149 static void zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac,
5150 struct prefix *host_prefix)
5151 {
5152 rb_delete_host(&zrmac->host_rb, host_prefix);
5153
5154 if (RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) {
5155 /* uninstall from kernel */
5156 zl3vni_rmac_uninstall(zl3vni, zrmac);
5157
5158 /* Send RMAC for FPM processing */
5159 hook_call(zebra_rmac_update, zrmac, zl3vni, true,
5160 "RMAC deleted");
5161
5162 /* del the rmac entry */
5163 zl3vni_rmac_del(zl3vni, zrmac);
5164 }
5165 }
5166
5167 /*
5168 * Look up nh hash entry on a l3-vni.
5169 */
5170 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
5171 const struct ipaddr *ip)
5172 {
5173 zebra_neigh_t tmp;
5174 zebra_neigh_t *n;
5175
5176 memset(&tmp, 0, sizeof(tmp));
5177 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
5178 n = hash_lookup(zl3vni->nh_table, &tmp);
5179
5180 return n;
5181 }
5182
5183
5184 /*
5185 * Callback to allocate NH hash entry on L3-VNI.
5186 */
5187 static void *zl3vni_nh_alloc(void *p)
5188 {
5189 const zebra_neigh_t *tmp_n = p;
5190 zebra_neigh_t *n;
5191
5192 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
5193 *n = *tmp_n;
5194
5195 return ((void *)n);
5196 }
5197
5198 /*
5199 * Add neighbor entry.
5200 */
5201 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
5202 const struct ipaddr *ip,
5203 const struct ethaddr *mac)
5204 {
5205 zebra_neigh_t tmp_n;
5206 zebra_neigh_t *n = NULL;
5207
5208 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
5209 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
5210 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
5211 assert(n);
5212
5213 RB_INIT(host_rb_tree_entry, &n->host_rb);
5214
5215 memcpy(&n->emac, mac, ETH_ALEN);
5216 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
5217 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
5218
5219 return n;
5220 }
5221
5222 /*
5223 * Delete neighbor entry.
5224 */
5225 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
5226 {
5227 zebra_neigh_t *tmp_n;
5228 struct host_rb_entry *hle;
5229
5230 while (!RB_EMPTY(host_rb_tree_entry, &n->host_rb)) {
5231 hle = RB_ROOT(host_rb_tree_entry, &n->host_rb);
5232
5233 RB_REMOVE(host_rb_tree_entry, &n->host_rb, hle);
5234 XFREE(MTYPE_HOST_PREFIX, hle);
5235 }
5236
5237 tmp_n = hash_release(zl3vni->nh_table, n);
5238 XFREE(MTYPE_NEIGH, tmp_n);
5239
5240 return 0;
5241 }
5242
5243 /*
5244 * Install remote nh as neigh into the kernel.
5245 */
5246 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
5247 {
5248 uint8_t flags;
5249 int ret = 0;
5250
5251 if (!is_l3vni_oper_up(zl3vni))
5252 return -1;
5253
5254 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
5255 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
5256 return 0;
5257
5258 flags = DPLANE_NTF_EXT_LEARNED;
5259 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
5260 flags |= DPLANE_NTF_ROUTER;
5261
5262 dplane_rem_neigh_add(zl3vni->svi_if, &n->ip, &n->emac, flags,
5263 false /*was_static*/);
5264
5265 return ret;
5266 }
5267
5268 /*
5269 * Uninstall remote nh from the kernel.
5270 */
5271 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
5272 {
5273 if (!(n->flags & ZEBRA_NEIGH_REMOTE)
5274 || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
5275 return 0;
5276
5277 if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
5278 return 0;
5279
5280 dplane_rem_neigh_delete(zl3vni->svi_if, &n->ip);
5281
5282 return 0;
5283 }
5284
5285 /* add remote vtep as a neigh entry */
5286 static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
5287 const struct ipaddr *vtep_ip,
5288 const struct ethaddr *rmac,
5289 const struct prefix *host_prefix)
5290 {
5291 char buf[ETHER_ADDR_STRLEN];
5292 char buf1[ETHER_ADDR_STRLEN];
5293 char buf2[INET6_ADDRSTRLEN];
5294 char buf3[PREFIX_STRLEN];
5295 zebra_neigh_t *nh = NULL;
5296
5297 /* Create the next hop entry, or update its mac, if necessary. */
5298 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
5299 if (!nh) {
5300 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
5301 if (!nh) {
5302 zlog_debug(
5303 "Failed to add NH %s as Neigh (RMAC %s L3-VNI %u prefix %s)",
5304 ipaddr2str(vtep_ip, buf1, sizeof(buf2)),
5305 prefix_mac2str(rmac, buf, sizeof(buf)),
5306 zl3vni->vni,
5307 prefix2str(host_prefix, buf2, sizeof(buf2)));
5308 return -1;
5309 }
5310
5311 /* install the nh neigh in kernel */
5312 zl3vni_nh_install(zl3vni, nh);
5313 } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
5314 if (IS_ZEBRA_DEBUG_VXLAN)
5315 zlog_debug("L3VNI %u RMAC change(%s --> %s) for nexthop %s, prefix %s",
5316 zl3vni->vni,
5317 prefix_mac2str(&nh->emac, buf, sizeof(buf)),
5318 prefix_mac2str(rmac, buf1, sizeof(buf1)),
5319 ipaddr2str(vtep_ip, buf2, sizeof(buf2)),
5320 prefix2str(host_prefix, buf3, sizeof(buf3)));
5321
5322 memcpy(&nh->emac, rmac, ETH_ALEN);
5323 /* install (update) the nh neigh in kernel */
5324 zl3vni_nh_install(zl3vni, nh);
5325 }
5326
5327 rb_find_or_add_host(&nh->host_rb, host_prefix);
5328
5329 return 0;
5330 }
5331
5332 /* handle nh neigh delete */
5333 static void zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *nh,
5334 struct prefix *host_prefix)
5335 {
5336 rb_delete_host(&nh->host_rb, host_prefix);
5337
5338 if (RB_EMPTY(host_rb_tree_entry, &nh->host_rb)) {
5339 /* uninstall from kernel */
5340 zl3vni_nh_uninstall(zl3vni, nh);
5341
5342 /* delete the nh entry */
5343 zl3vni_nh_del(zl3vni, nh);
5344 }
5345 }
5346
5347 /* handle neigh update from kernel - the only thing of interest is to
5348 * readd stale entries.
5349 */
5350 static int zl3vni_local_nh_add_update(zebra_l3vni_t *zl3vni, struct ipaddr *ip,
5351 uint16_t state)
5352 {
5353 #ifdef GNU_LINUX
5354 zebra_neigh_t *n = NULL;
5355
5356 n = zl3vni_nh_lookup(zl3vni, ip);
5357 if (!n)
5358 return 0;
5359
5360 /* all next hop neigh are remote and installed by frr.
5361 * If the kernel has aged this entry, re-install.
5362 */
5363 if (state & NUD_STALE)
5364 zl3vni_nh_install(zl3vni, n);
5365 #endif
5366 return 0;
5367 }
5368
5369 /* handle neigh delete from kernel */
5370 static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
5371 {
5372 zebra_neigh_t *n = NULL;
5373
5374 n = zl3vni_nh_lookup(zl3vni, ip);
5375 if (!n)
5376 return 0;
5377
5378 /* all next hop neigh are remote and installed by frr.
5379 * If we get an age out notification for these neigh entries, we have to
5380 * install it back
5381 */
5382 zl3vni_nh_install(zl3vni, n);
5383
5384 return 0;
5385 }
5386
5387 /*
5388 * Hash function for L3 VNI.
5389 */
5390 static unsigned int l3vni_hash_keymake(const void *p)
5391 {
5392 const zebra_l3vni_t *zl3vni = p;
5393
5394 return jhash_1word(zl3vni->vni, 0);
5395 }
5396
5397 /*
5398 * Compare 2 L3 VNI hash entries.
5399 */
5400 static bool l3vni_hash_cmp(const void *p1, const void *p2)
5401 {
5402 const zebra_l3vni_t *zl3vni1 = p1;
5403 const zebra_l3vni_t *zl3vni2 = p2;
5404
5405 return (zl3vni1->vni == zl3vni2->vni);
5406 }
5407
5408 /*
5409 * Callback to allocate L3 VNI hash entry.
5410 */
5411 static void *zl3vni_alloc(void *p)
5412 {
5413 zebra_l3vni_t *zl3vni = NULL;
5414 const zebra_l3vni_t *tmp_l3vni = p;
5415
5416 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(zebra_l3vni_t));
5417 zl3vni->vni = tmp_l3vni->vni;
5418 return ((void *)zl3vni);
5419 }
5420
5421 /*
5422 * Look up L3 VNI hash entry.
5423 */
5424 zebra_l3vni_t *zl3vni_lookup(vni_t vni)
5425 {
5426 zebra_l3vni_t tmp_l3vni;
5427 zebra_l3vni_t *zl3vni = NULL;
5428
5429 memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t));
5430 tmp_l3vni.vni = vni;
5431 zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni);
5432
5433 return zl3vni;
5434 }
5435
5436 /*
5437 * Add L3 VNI hash entry.
5438 */
5439 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
5440 {
5441 zebra_l3vni_t tmp_zl3vni;
5442 zebra_l3vni_t *zl3vni = NULL;
5443
5444 memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t));
5445 tmp_zl3vni.vni = vni;
5446
5447 zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc);
5448 assert(zl3vni);
5449
5450 zl3vni->vrf_id = vrf_id;
5451 zl3vni->svi_if = NULL;
5452 zl3vni->vxlan_if = NULL;
5453 zl3vni->l2vnis = list_new();
5454 zl3vni->l2vnis->cmp = vni_list_cmp;
5455
5456 /* Create hash table for remote RMAC */
5457 zl3vni->rmac_table = hash_create(mac_hash_keymake, mac_cmp,
5458 "Zebra L3-VNI RMAC-Table");
5459
5460 /* Create hash table for neighbors */
5461 zl3vni->nh_table = hash_create(neigh_hash_keymake, neigh_cmp,
5462 "Zebra L3-VNI next-hop table");
5463
5464 return zl3vni;
5465 }
5466
5467 /*
5468 * Delete L3 VNI hash entry.
5469 */
5470 static int zl3vni_del(zebra_l3vni_t *zl3vni)
5471 {
5472 zebra_l3vni_t *tmp_zl3vni;
5473
5474 /* free the list of l2vnis */
5475 list_delete(&zl3vni->l2vnis);
5476 zl3vni->l2vnis = NULL;
5477
5478 /* Free the rmac table */
5479 hash_free(zl3vni->rmac_table);
5480 zl3vni->rmac_table = NULL;
5481
5482 /* Free the nh table */
5483 hash_free(zl3vni->nh_table);
5484 zl3vni->nh_table = NULL;
5485
5486 /* Free the VNI hash entry and allocated memory. */
5487 tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
5488 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
5489
5490 return 0;
5491 }
5492
5493 struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
5494 {
5495 struct zebra_ns *zns = NULL;
5496 struct route_node *rn = NULL;
5497 struct interface *ifp = NULL;
5498
5499 /* loop through all vxlan-interface */
5500 zns = zebra_ns_lookup(NS_DEFAULT);
5501 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
5502
5503 struct zebra_if *zif = NULL;
5504 struct zebra_l2info_vxlan *vxl = NULL;
5505
5506 ifp = (struct interface *)rn->info;
5507 if (!ifp)
5508 continue;
5509
5510 zif = ifp->info;
5511 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
5512 continue;
5513
5514 vxl = &zif->l2info.vxl;
5515 if (vxl->vni == zl3vni->vni) {
5516 zl3vni->local_vtep_ip = vxl->vtep_ip;
5517 return ifp;
5518 }
5519 }
5520
5521 return NULL;
5522 }
5523
5524 struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
5525 {
5526 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
5527 struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
5528
5529 if (!zl3vni)
5530 return NULL;
5531
5532 if (!zl3vni->vxlan_if)
5533 return NULL;
5534
5535 zif = zl3vni->vxlan_if->info;
5536 if (!zif)
5537 return NULL;
5538
5539 vxl = &zif->l2info.vxl;
5540
5541 return zevpn_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
5542 }
5543
5544 struct interface *zl3vni_map_to_mac_vlan_if(zebra_l3vni_t *zl3vni)
5545 {
5546 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
5547
5548 if (!zl3vni)
5549 return NULL;
5550
5551 if (!zl3vni->vxlan_if)
5552 return NULL;
5553
5554 zif = zl3vni->vxlan_if->info;
5555 if (!zif)
5556 return NULL;
5557
5558 return zevpn_map_to_macvlan(zif->brslave_info.br_if, zl3vni->svi_if);
5559 }
5560
5561
5562 zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id)
5563 {
5564 struct zebra_vrf *zvrf = NULL;
5565
5566 zvrf = zebra_vrf_lookup_by_id(vrf_id);
5567 if (!zvrf)
5568 return NULL;
5569
5570 return zl3vni_lookup(zvrf->l3vni);
5571 }
5572
5573 /*
5574 * Map SVI and associated bridge to a VNI. This is invoked upon getting
5575 * neighbor notifications, to see if they are of interest.
5576 */
5577 static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp,
5578 struct interface *br_if)
5579 {
5580 int found = 0;
5581 vlanid_t vid = 0;
5582 uint8_t bridge_vlan_aware = 0;
5583 zebra_l3vni_t *zl3vni = NULL;
5584 struct zebra_ns *zns = NULL;
5585 struct route_node *rn = NULL;
5586 struct zebra_if *zif = NULL;
5587 struct interface *tmp_if = NULL;
5588 struct zebra_l2info_bridge *br = NULL;
5589 struct zebra_l2info_vxlan *vxl = NULL;
5590
5591 if (!br_if)
5592 return NULL;
5593
5594 /* Make sure the linked interface is a bridge. */
5595 if (!IS_ZEBRA_IF_BRIDGE(br_if))
5596 return NULL;
5597
5598 /* Determine if bridge is VLAN-aware or not */
5599 zif = br_if->info;
5600 assert(zif);
5601 br = &zif->l2info.br;
5602 bridge_vlan_aware = br->vlan_aware;
5603 if (bridge_vlan_aware) {
5604 struct zebra_l2info_vlan *vl;
5605
5606 if (!IS_ZEBRA_IF_VLAN(ifp))
5607 return NULL;
5608
5609 zif = ifp->info;
5610 assert(zif);
5611 vl = &zif->l2info.vl;
5612 vid = vl->vid;
5613 }
5614
5615 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
5616 /* TODO: Optimize with a hash. */
5617 zns = zebra_ns_lookup(NS_DEFAULT);
5618 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
5619 tmp_if = (struct interface *)rn->info;
5620 if (!tmp_if)
5621 continue;
5622 zif = tmp_if->info;
5623 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
5624 continue;
5625 if (!if_is_operative(tmp_if))
5626 continue;
5627 vxl = &zif->l2info.vxl;
5628
5629 if (zif->brslave_info.br_if != br_if)
5630 continue;
5631
5632 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
5633 found = 1;
5634 break;
5635 }
5636 }
5637
5638 if (!found)
5639 return NULL;
5640
5641 zl3vni = zl3vni_lookup(vxl->vni);
5642 return zl3vni;
5643 }
5644
5645 static inline void zl3vni_get_vrr_rmac(zebra_l3vni_t *zl3vni,
5646 struct ethaddr *rmac)
5647 {
5648 if (!zl3vni)
5649 return;
5650
5651 if (!is_l3vni_oper_up(zl3vni))
5652 return;
5653
5654 if (zl3vni->mac_vlan_if && if_is_operative(zl3vni->mac_vlan_if))
5655 memcpy(rmac->octet, zl3vni->mac_vlan_if->hw_addr, ETH_ALEN);
5656 }
5657
5658 /*
5659 * Inform BGP about l3-vni.
5660 */
5661 static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
5662 {
5663 struct stream *s = NULL;
5664 struct zserv *client = NULL;
5665 struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
5666 struct zebra_vrf *zvrf;
5667 char buf[ETHER_ADDR_STRLEN];
5668 char buf1[ETHER_ADDR_STRLEN];
5669 bool is_anycast_mac = true;
5670
5671 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
5672 /* BGP may not be running. */
5673 if (!client)
5674 return 0;
5675
5676 zvrf = zebra_vrf_lookup_by_id(zl3vni->vrf_id);
5677 assert(zvrf);
5678
5679 /* get the svi and vrr rmac values */
5680 memset(&svi_rmac, 0, sizeof(struct ethaddr));
5681 zl3vni_get_svi_rmac(zl3vni, &svi_rmac);
5682 zl3vni_get_vrr_rmac(zl3vni, &vrr_rmac);
5683
5684 /* In absence of vrr mac use svi mac as anycast MAC value */
5685 if (is_zero_mac(&vrr_rmac)) {
5686 memcpy(&vrr_rmac, &svi_rmac, ETH_ALEN);
5687 is_anycast_mac = false;
5688 }
5689
5690 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5691
5692 /* The message is used for both vni add and/or update like
5693 * vrr mac is added for l3vni SVI.
5694 */
5695 zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
5696 stream_putl(s, zl3vni->vni);
5697 stream_put(s, &svi_rmac, sizeof(struct ethaddr));
5698 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
5699 stream_put(s, &zl3vni->filter, sizeof(int));
5700 stream_putl(s, zl3vni->svi_if->ifindex);
5701 stream_put(s, &vrr_rmac, sizeof(struct ethaddr));
5702 stream_putl(s, is_anycast_mac);
5703
5704 /* Write packet size. */
5705 stream_putw_at(s, 0, stream_get_endp(s));
5706
5707 if (IS_ZEBRA_DEBUG_VXLAN)
5708 zlog_debug(
5709 "Send L3_VNI_ADD %u VRF %s RMAC %s VRR %s local-ip %s filter %s to %s",
5710 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
5711 prefix_mac2str(&svi_rmac, buf, sizeof(buf)),
5712 prefix_mac2str(&vrr_rmac, buf1, sizeof(buf1)),
5713 inet_ntoa(zl3vni->local_vtep_ip),
5714 CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
5715 ? "prefix-routes-only"
5716 : "none",
5717 zebra_route_string(client->proto));
5718
5719 client->l3vniadd_cnt++;
5720 return zserv_send_message(client, s);
5721 }
5722
5723 /*
5724 * Inform BGP about local l3-VNI deletion.
5725 */
5726 static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
5727 {
5728 struct stream *s = NULL;
5729 struct zserv *client = NULL;
5730
5731 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
5732 /* BGP may not be running. */
5733 if (!client)
5734 return 0;
5735
5736 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5737
5738 zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
5739 stream_putl(s, zl3vni->vni);
5740
5741 /* Write packet size. */
5742 stream_putw_at(s, 0, stream_get_endp(s));
5743
5744 if (IS_ZEBRA_DEBUG_VXLAN)
5745 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s", zl3vni->vni,
5746 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
5747 zebra_route_string(client->proto));
5748
5749 client->l3vnidel_cnt++;
5750 return zserv_send_message(client, s);
5751 }
5752
5753 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
5754 {
5755 if (!zl3vni)
5756 return;
5757
5758 /* send l3vni add to BGP */
5759 zl3vni_send_add_to_client(zl3vni);
5760 }
5761
5762 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
5763 {
5764 if (!zl3vni)
5765 return;
5766
5767 /* send l3-vni del to BGP*/
5768 zl3vni_send_del_to_client(zl3vni);
5769 }
5770
5771 static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
5772 {
5773 zebra_evpn_t *zevpn = (zebra_evpn_t *)bucket->data;
5774 zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)ctxt;
5775
5776 if (zevpn->vrf_id == zl3vni_vrf_id(zl3vni))
5777 listnode_add_sort(zl3vni->l2vnis, zevpn);
5778 }
5779
5780 /*
5781 * handle transition of vni from l2 to l3 and vice versa
5782 */
5783 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
5784 int add)
5785 {
5786 zebra_evpn_t *zevpn = NULL;
5787
5788 /* There is a possibility that VNI notification was already received
5789 * from kernel and we programmed it as L2-VNI
5790 * In such a case we need to delete this L2-VNI first, so
5791 * that it can be reprogrammed as L3-VNI in the system. It is also
5792 * possible that the vrf-vni mapping is removed from FRR while the vxlan
5793 * interface is still present in kernel. In this case to keep it
5794 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
5795 */
5796 if (add) {
5797 /* Locate hash entry */
5798 zevpn = zevpn_lookup(vni);
5799 if (!zevpn)
5800 return 0;
5801
5802 if (IS_ZEBRA_DEBUG_VXLAN)
5803 zlog_debug("Del L2-VNI %u - transition to L3-VNI", vni);
5804
5805 /* Delete EVPN from BGP. */
5806 zevpn_send_del_to_client(zevpn);
5807
5808 /* Free up all neighbors and MAC, if any. */
5809 zevpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
5810 zevpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
5811
5812 /* Free up all remote VTEPs, if any. */
5813 zevpn_vtep_del_all(zevpn, 0);
5814
5815 /* Delete the hash entry. */
5816 if (zevpn_del(zevpn)) {
5817 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
5818 "Failed to del EVPN hash %p, VNI %u", zevpn,
5819 zevpn->vni);
5820 return -1;
5821 }
5822 } else {
5823 /* TODO_MITESH: This needs to be thought through. We don't have
5824 * enough information at this point to reprogram the vni as
5825 * l2-vni. One way is to store the required info in l3-vni and
5826 * used it solely for this purpose
5827 */
5828 }
5829
5830 return 0;
5831 }
5832
5833 /* delete and uninstall rmac hash entry */
5834 static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx)
5835 {
5836 zebra_mac_t *zrmac = NULL;
5837 zebra_l3vni_t *zl3vni = NULL;
5838
5839 zrmac = (zebra_mac_t *)bucket->data;
5840 zl3vni = (zebra_l3vni_t *)ctx;
5841 zl3vni_rmac_uninstall(zl3vni, zrmac);
5842
5843 /* Send RMAC for FPM processing */
5844 hook_call(zebra_rmac_update, zrmac, zl3vni, true, "RMAC deleted");
5845
5846 zl3vni_rmac_del(zl3vni, zrmac);
5847 }
5848
5849 /* delete and uninstall nh hash entry */
5850 static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx)
5851 {
5852 zebra_neigh_t *n = NULL;
5853 zebra_l3vni_t *zl3vni = NULL;
5854
5855 n = (zebra_neigh_t *)bucket->data;
5856 zl3vni = (zebra_l3vni_t *)ctx;
5857 zl3vni_nh_uninstall(zl3vni, n);
5858 zl3vni_nh_del(zl3vni, n);
5859 }
5860
5861 static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
5862 uint16_t cmd)
5863 {
5864 struct zserv *client = NULL;
5865 struct stream *s = NULL;
5866 char buf[PREFIX_STRLEN];
5867
5868 client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
5869 /* BGP may not be running. */
5870 if (!client)
5871 return 0;
5872
5873 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
5874
5875 zclient_create_header(s, cmd, vrf_id);
5876 stream_put(s, p, sizeof(struct prefix));
5877
5878 /* Write packet size. */
5879 stream_putw_at(s, 0, stream_get_endp(s));
5880
5881 if (IS_ZEBRA_DEBUG_VXLAN)
5882 zlog_debug("Send ip prefix %s %s on vrf %s",
5883 prefix2str(p, buf, sizeof(buf)),
5884 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
5885 vrf_id_to_name(vrf_id));
5886
5887 if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
5888 client->prefixadd_cnt++;
5889 else
5890 client->prefixdel_cnt++;
5891
5892 return zserv_send_message(client, s);
5893 }
5894
5895 /* re-add remote rmac if needed */
5896 static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
5897 struct ethaddr *rmac)
5898 {
5899 char buf[ETHER_ADDR_STRLEN];
5900 zebra_mac_t *zrmac = NULL;
5901
5902 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
5903 if (!zrmac)
5904 return 0;
5905
5906 if (IS_ZEBRA_DEBUG_VXLAN)
5907 zlog_debug("Del remote RMAC %s L3VNI %u - readd",
5908 prefix_mac2str(rmac, buf, sizeof(buf)), zl3vni->vni);
5909
5910 zl3vni_rmac_install(zl3vni, zrmac);
5911 return 0;
5912 }
5913
5914 /**************************** SYNC MAC handling *****************************/
5915 /* if the mac has been added of a mac-route from the peer
5916 * or if it is being referenced by a neigh added by the
5917 * peer we cannot let it age out i.e. we set the static bit
5918 * in the dataplane
5919 */
5920 static inline bool zebra_vxlan_mac_is_static(zebra_mac_t *mac)
5921 {
5922 return ((mac->flags & ZEBRA_MAC_ALL_PEER_FLAGS) ||
5923 mac->sync_neigh_cnt);
5924 }
5925
5926 /* mac needs to be locally active or active on an ES peer */
5927 static inline bool zebra_vxlan_mac_is_ready_for_bgp(uint32_t flags)
5928 {
5929 return (flags & ZEBRA_MAC_LOCAL) &&
5930 (!(flags & ZEBRA_MAC_LOCAL_INACTIVE) ||
5931 (flags & ZEBRA_MAC_ES_PEER_ACTIVE));
5932 }
5933
5934 /* program sync mac flags in the dataplane */
5935 void zebra_vxlan_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive,
5936 bool force_clear_static, const char *caller)
5937 {
5938 char macbuf[ETHER_ADDR_STRLEN];
5939 struct interface *ifp;
5940 bool sticky;
5941 bool set_static;
5942 zebra_evpn_t *zevpn = mac->zevpn;
5943 vlanid_t vid;
5944 struct zebra_if *zif;
5945 struct interface *br_ifp;
5946
5947 /* get the access vlan from the vxlan_device */
5948 zebra_vxlan_mac_get_access_info(mac,
5949 &ifp, &vid);
5950
5951 if (!ifp) {
5952 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
5953 zlog_debug("%s: dp-install sync-mac vni %u mac %s es %s 0x%x %sskipped, no access-port",
5954 caller,
5955 zevpn->vni,
5956 prefix_mac2str(&mac->macaddr, macbuf,
5957 sizeof(macbuf)),
5958 mac->es ?
5959 mac->es->esi_str : "-",
5960 mac->flags,
5961 set_inactive ? "inactive " : "");
5962 return;
5963 }
5964
5965 zif = ifp->info;
5966 br_ifp = zif->brslave_info.br_if;
5967 if (!br_ifp) {
5968 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
5969 zlog_debug("%s: dp-install sync-mac vni %u mac %s es %s 0x%x %sskipped, no br",
5970 caller,
5971 zevpn->vni,
5972 prefix_mac2str(&mac->macaddr, macbuf,
5973 sizeof(macbuf)),
5974 mac->es ?
5975 mac->es->esi_str : "-",
5976 mac->flags,
5977 set_inactive ? "inactive " : "");
5978 return;
5979 }
5980
5981 sticky = !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5982 if (force_clear_static)
5983 set_static = false;
5984 else
5985 set_static = zebra_vxlan_mac_is_static(mac);
5986
5987 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
5988 zlog_debug("dp-install sync-mac vni %u mac %s es %s 0x%x %s%s",
5989 zevpn->vni,
5990 prefix_mac2str(&mac->macaddr, macbuf,
5991 sizeof(macbuf)),
5992 mac->es ?
5993 mac->es->esi_str : "-", mac->flags,
5994 set_static ? "static " : "",
5995 set_inactive ? "inactive " : "");
5996
5997 dplane_local_mac_add(ifp, br_ifp, vid, &mac->macaddr, sticky,
5998 set_static, set_inactive);
5999
6000 }
6001
6002 static void zebra_vxlan_mac_send_add_del_to_client(zebra_mac_t *mac,
6003 bool old_bgp_ready, bool new_bgp_ready)
6004 {
6005 if (new_bgp_ready)
6006 zevpn_mac_send_add_to_client(mac->zevpn->vni,
6007 &mac->macaddr, mac->flags,
6008 mac->loc_seq, mac->es);
6009 else if (old_bgp_ready)
6010 zevpn_mac_send_del_to_client(mac->zevpn->vni,
6011 &mac->macaddr, mac->flags,
6012 true /* force */);
6013 }
6014
6015 /* MAC hold timer is used to age out peer-active flag.
6016 *
6017 * During this wait time we expect the dataplane component or an
6018 * external neighmgr daemon to probe existing hosts to independently
6019 * establish their presence on the ES.
6020 */
6021 static int zebra_vxlan_mac_hold_exp_cb(struct thread *t)
6022 {
6023 zebra_mac_t *mac;
6024 bool old_bgp_ready;
6025 bool new_bgp_ready;
6026 bool old_static;
6027 bool new_static;
6028 char macbuf[ETHER_ADDR_STRLEN];
6029
6030 mac = THREAD_ARG(t);
6031 /* the purpose of the hold timer is to age out the peer-active
6032 * flag
6033 */
6034 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE))
6035 return 0;
6036
6037 old_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
6038 old_static = zebra_vxlan_mac_is_static(mac);
6039 UNSET_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE);
6040 new_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
6041 new_static = zebra_vxlan_mac_is_static(mac);
6042
6043 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6044 zlog_debug("sync-mac vni %u mac %s es %s 0x%x hold expired",
6045 mac->zevpn->vni,
6046 prefix_mac2str(&mac->macaddr, macbuf,
6047 sizeof(macbuf)),
6048 mac->es ?
6049 mac->es->esi_str : "-",
6050 mac->flags);
6051
6052 /* re-program the local mac in the dataplane if the mac is no
6053 * longer static
6054 */
6055 if (old_static != new_static)
6056 zebra_vxlan_sync_mac_dp_install(mac, false /* set_inactive */,
6057 false /* force_clear_static */, __func__);
6058
6059 /* inform bgp if needed */
6060 if (old_bgp_ready != new_bgp_ready)
6061 zebra_vxlan_mac_send_add_del_to_client(mac,
6062 old_bgp_ready, new_bgp_ready);
6063
6064 return 0;
6065 }
6066
6067 static inline void zebra_vxlan_mac_start_hold_timer(zebra_mac_t *mac)
6068 {
6069 char macbuf[ETHER_ADDR_STRLEN];
6070
6071 if (mac->hold_timer)
6072 return;
6073
6074 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6075 zlog_debug("sync-mac vni %u mac %s es %s 0x%x hold started",
6076 mac->zevpn->vni,
6077 prefix_mac2str(&mac->macaddr, macbuf,
6078 sizeof(macbuf)),
6079 mac->es ?
6080 mac->es->esi_str : "-",
6081 mac->flags);
6082 thread_add_timer(zrouter.master,
6083 zebra_vxlan_mac_hold_exp_cb,
6084 mac, zmh_info->mac_hold_time,
6085 &mac->hold_timer);
6086 }
6087
6088 static inline void zebra_vxlan_mac_stop_hold_timer(zebra_mac_t *mac)
6089 {
6090 char macbuf[ETHER_ADDR_STRLEN];
6091
6092 if (!mac->hold_timer)
6093 return;
6094
6095 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6096 zlog_debug("sync-mac vni %u mac %s es %s 0x%x hold stopped",
6097 mac->zevpn->vni,
6098 prefix_mac2str(&mac->macaddr, macbuf,
6099 sizeof(macbuf)),
6100 mac->es ?
6101 mac->es->esi_str : "-",
6102 mac->flags);
6103 THREAD_OFF(mac->hold_timer);
6104 }
6105
6106 static inline void zebra_vxlan_mac_clear_sync_info(zebra_mac_t *mac)
6107 {
6108 UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_PEER_FLAGS);
6109 zebra_vxlan_mac_stop_hold_timer(mac);
6110 }
6111
6112 static void zebra_vxlan_sync_mac_del(zebra_mac_t *mac)
6113 {
6114 char macbuf[ETHER_ADDR_STRLEN];
6115 bool old_static;
6116 bool new_static;
6117
6118 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6119 zlog_debug("sync-mac del vni %u mac %s es %s seq %d f 0x%x",
6120 mac->zevpn->vni,
6121 prefix_mac2str(&mac->macaddr,
6122 macbuf, sizeof(macbuf)),
6123 mac->es ? mac->es->esi_str : "-",
6124 mac->loc_seq,
6125 mac->flags);
6126 old_static = zebra_vxlan_mac_is_static(mac);
6127 UNSET_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY);
6128 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE))
6129 zebra_vxlan_mac_start_hold_timer(mac);
6130 new_static = zebra_vxlan_mac_is_static(mac);
6131
6132 if (old_static != new_static)
6133 /* program the local mac in the kernel */
6134 zebra_vxlan_sync_mac_dp_install(mac, false /* set_inactive */,
6135 false /* force_clear_static */, __func__);
6136 }
6137
6138 static inline bool zebra_vxlan_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
6139 zebra_mac_t *mac, uint32_t seq, uint16_t ipa_len,
6140 struct ipaddr *ipaddr)
6141 {
6142 char macbuf[ETHER_ADDR_STRLEN];
6143 char ipbuf[INET6_ADDRSTRLEN];
6144 uint32_t tmp_seq;
6145
6146 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
6147 tmp_seq = mac->loc_seq;
6148 else
6149 tmp_seq = mac->rem_seq;
6150
6151 if (seq < tmp_seq) {
6152 /* if the mac was never advertised to bgp we must accept
6153 * whatever sequence number bgp sends
6154 * XXX - check with Vivek
6155 */
6156 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) &&
6157 !zebra_vxlan_mac_is_ready_for_bgp(mac->flags)) {
6158 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6159 zlog_debug("sync-macip accept vni %u mac %s%s%s lower seq %u f 0x%x",
6160 zevpn->vni,
6161 prefix_mac2str(&mac->macaddr,
6162 macbuf, sizeof(macbuf)),
6163 ipa_len ? " IP " : "",
6164 ipa_len ?
6165 ipaddr2str(ipaddr,
6166 ipbuf, sizeof(ipbuf)) : "",
6167 tmp_seq, mac->flags);
6168 return true;
6169 }
6170
6171 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6172 zlog_debug("sync-macip ignore vni %u mac %s%s%s as existing has higher seq %u f 0x%x",
6173 zevpn->vni,
6174 prefix_mac2str(&mac->macaddr,
6175 macbuf, sizeof(macbuf)),
6176 ipa_len ? " IP " : "",
6177 ipa_len ?
6178 ipaddr2str(ipaddr,
6179 ipbuf, sizeof(ipbuf)) : "",
6180 tmp_seq, mac->flags);
6181 return false;
6182 }
6183
6184 return true;
6185 }
6186
6187 /* sync-path that is active on an ES peer */
6188 static zebra_mac_t *zebra_vxlan_proc_sync_mac_update(zebra_evpn_t *zevpn,
6189 struct ethaddr *macaddr, uint16_t ipa_len,
6190 struct ipaddr *ipaddr, uint8_t flags,
6191 uint32_t seq, esi_t *esi,
6192 struct sync_mac_ip_ctx *ctx)
6193 {
6194 zebra_mac_t *mac;
6195 bool inform_bgp = false;
6196 bool inform_dataplane = false;
6197 bool seq_change = false;
6198 bool es_change = false;
6199 uint32_t tmp_seq;
6200 char macbuf[ETHER_ADDR_STRLEN];
6201 char ipbuf[INET6_ADDRSTRLEN];
6202 bool old_local = false;
6203 bool old_bgp_ready;
6204 bool new_bgp_ready;
6205
6206 mac = zevpn_mac_lookup(zevpn, macaddr);
6207 if (!mac) {
6208 /* if it is a new local path we need to inform both
6209 * the control protocol and the data-plane
6210 */
6211 inform_bgp = true;
6212 inform_dataplane = true;
6213 ctx->mac_created = true;
6214 ctx->mac_inactive = true;
6215
6216 /* create the MAC and associate it with the dest ES */
6217 mac = zevpn_mac_add(zevpn, macaddr);
6218 zebra_evpn_es_mac_ref(mac, esi);
6219
6220 /* local mac activated by an ES peer */
6221 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
6222 /* if mac-only route setup peer flags */
6223 if (!ipa_len) {
6224 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
6225 SET_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY);
6226 else
6227 SET_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE);
6228 }
6229 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
6230 old_bgp_ready = false;
6231 new_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
6232 } else {
6233 uint32_t old_flags;
6234 uint32_t new_flags;
6235 bool old_static;
6236 bool new_static;
6237 bool sticky;
6238 bool remote_gw;
6239
6240 old_flags = mac->flags;
6241 sticky = !!CHECK_FLAG(old_flags, ZEBRA_MAC_STICKY);
6242 remote_gw = !!CHECK_FLAG(old_flags, ZEBRA_MAC_REMOTE_DEF_GW);
6243 if (sticky || remote_gw) {
6244 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6245 zlog_debug("Ignore sync-macip vni %u mac %s%s%s%s%s",
6246 zevpn->vni,
6247 prefix_mac2str(macaddr,
6248 macbuf, sizeof(macbuf)),
6249 ipa_len ? " IP " : "",
6250 ipa_len ?
6251 ipaddr2str(ipaddr, ipbuf,
6252 sizeof(ipbuf)) : "",
6253 sticky ? " sticky" : "",
6254 remote_gw ? " remote_gw" : "");
6255 ctx->ignore_macip = true;
6256 return NULL;
6257 }
6258 if (!zebra_vxlan_mac_is_bgp_seq_ok(zevpn, mac, seq,
6259 ipa_len, ipaddr)) {
6260 ctx->ignore_macip = true;
6261 return NULL;
6262 }
6263
6264 old_local = !!CHECK_FLAG(old_flags, ZEBRA_MAC_LOCAL);
6265 old_static = zebra_vxlan_mac_is_static(mac);
6266
6267 /* re-build the mac flags */
6268 new_flags = 0;
6269 SET_FLAG(new_flags, ZEBRA_MAC_LOCAL);
6270 /* retain old local activity flag */
6271 if (old_flags & ZEBRA_MAC_LOCAL) {
6272 new_flags |= (old_flags & ZEBRA_MAC_LOCAL_INACTIVE);
6273 } else {
6274 new_flags |= ZEBRA_MAC_LOCAL_INACTIVE;
6275 ctx->mac_inactive = true;
6276 }
6277 if (ipa_len) {
6278 /* if mac-ip route do NOT update the peer flags
6279 * i.e. retain only flags as is
6280 */
6281 new_flags |= (old_flags & ZEBRA_MAC_ALL_PEER_FLAGS);
6282 } else {
6283 /* if mac-only route update peer flags */
6284 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
6285 SET_FLAG(new_flags, ZEBRA_MAC_ES_PEER_PROXY);
6286 /* if the mac was peer-active previously we
6287 * need to keep the flag and start the
6288 * holdtimer on it. the peer-active flag is
6289 * cleared on holdtimer expiry.
6290 */
6291 if (CHECK_FLAG(old_flags,
6292 ZEBRA_MAC_ES_PEER_ACTIVE)) {
6293 SET_FLAG(new_flags,
6294 ZEBRA_MAC_ES_PEER_ACTIVE);
6295 zebra_vxlan_mac_start_hold_timer(mac);
6296 }
6297 } else {
6298 SET_FLAG(new_flags, ZEBRA_MAC_ES_PEER_ACTIVE);
6299 /* stop hold timer if a peer has verified
6300 * reachability
6301 */
6302 zebra_vxlan_mac_stop_hold_timer(mac);
6303 }
6304 }
6305 mac->rem_seq = 0;
6306 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
6307 mac->flags = new_flags;
6308
6309 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC &&
6310 (old_flags != new_flags))
6311 zlog_debug("sync-mac vni %u mac %s old_f 0x%x new_f 0x%x",
6312 zevpn->vni,
6313 prefix_mac2str(macaddr,
6314 macbuf, sizeof(macbuf)),
6315 old_flags, mac->flags);
6316
6317 /* update es */
6318 es_change = zebra_evpn_es_mac_ref(mac, esi);
6319 /* if mac dest change - inform both sides */
6320 if (es_change) {
6321 inform_bgp = true;
6322 inform_dataplane = true;
6323 ctx->mac_inactive = true;
6324 }
6325 /* if peer-flag is being set notify dataplane that the
6326 * entry must not be expired because of local inactivity
6327 */
6328 new_static = zebra_vxlan_mac_is_static(mac);
6329 if (old_static != new_static)
6330 inform_dataplane = true;
6331
6332 old_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(old_flags);
6333 new_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
6334 if (old_bgp_ready != new_bgp_ready)
6335 inform_bgp = true;
6336 }
6337
6338
6339 /* update sequence number; if that results in a new local sequence
6340 * inform bgp
6341 */
6342 tmp_seq = MAX(mac->loc_seq, seq);
6343 if (tmp_seq != mac->loc_seq) {
6344 mac->loc_seq = tmp_seq;
6345 seq_change = true;
6346 inform_bgp = true;
6347 }
6348
6349 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
6350 zlog_debug("sync-mac %s vni %u mac %s es %s seq %d f 0x%x%s%s",
6351 ctx->mac_created ?
6352 "created" : "updated",
6353 zevpn->vni,
6354 prefix_mac2str(macaddr,
6355 macbuf, sizeof(macbuf)),
6356 mac->es ? mac->es->esi_str : "-",
6357 mac->loc_seq, mac->flags,
6358 inform_bgp ? " inform_bgp" : "",
6359 inform_dataplane ? " inform_dp" : "");
6360
6361 if (inform_bgp)
6362 zebra_vxlan_mac_send_add_del_to_client(mac,
6363 old_bgp_ready, new_bgp_ready);
6364
6365 /* neighs using the mac may need to be re-sent to
6366 * bgp with updated info
6367 */
6368 if (seq_change || es_change || !old_local)
6369 zevpn_process_neigh_on_local_mac_change(zevpn, mac,
6370 seq_change, es_change);
6371
6372 if (inform_dataplane) {
6373 if (ipa_len)
6374 /* if the mac is being created as a part of MAC-IP
6375 * route wait for the neigh to be updated or
6376 * created before programming the mac
6377 */
6378 ctx->mac_dp_update_deferred = true;
6379 else
6380 /* program the local mac in the kernel. when the ES
6381 * change we need to force the dataplane to reset
6382 * the activity as we are yet to establish activity
6383 * locally
6384 */
6385 zebra_vxlan_sync_mac_dp_install(mac,
6386 ctx->mac_inactive,
6387 false /* force_clear_static */,
6388 __func__);
6389 }
6390
6391 return mac;
6392 }
6393
6394 /**************************** SYNC neigh handling **************************/
6395 static inline bool zebra_vxlan_neigh_is_static(zebra_neigh_t *neigh)
6396 {
6397 return !!(neigh->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS);
6398 }
6399
6400 static inline bool zebra_vxlan_neigh_is_ready_for_bgp(zebra_neigh_t *n)
6401 {
6402 bool mac_ready;
6403 bool neigh_ready;
6404
6405 mac_ready = !!(n->mac->flags & ZEBRA_MAC_LOCAL);
6406 neigh_ready = ((n->flags & ZEBRA_NEIGH_LOCAL) &&
6407 IS_ZEBRA_NEIGH_ACTIVE(n) &&
6408 (!(n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) ||
6409 (n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE))) ?
6410 true : false;
6411
6412 return mac_ready && neigh_ready;
6413 }
6414
6415 static void zebra_vxlan_sync_neigh_dp_install(zebra_neigh_t *n,
6416 bool set_inactive, bool force_clear_static, const char *caller)
6417 {
6418 char macbuf[ETHER_ADDR_STRLEN];
6419 char ipbuf[INET6_ADDRSTRLEN];
6420 struct zebra_ns *zns;
6421 struct interface *ifp;
6422 bool set_static;
6423 bool set_router;
6424
6425 zns = zebra_ns_lookup(NS_DEFAULT);
6426 ifp = if_lookup_by_index_per_ns(zns, n->ifindex);
6427 if (!ifp) {
6428 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6429 zlog_debug("%s: dp-install sync-neigh vni %u ip %s mac %s if %d f 0x%x skipped",
6430 caller, n->zevpn->vni,
6431 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6432 prefix_mac2str(&n->emac, macbuf,
6433 sizeof(macbuf)),
6434 n->ifindex, n->flags);
6435 return;
6436 }
6437
6438 if (force_clear_static)
6439 set_static = false;
6440 else
6441 set_static = zebra_vxlan_neigh_is_static(n);
6442
6443 set_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
6444
6445 /* XXX - this will change post integration with the new kernel */
6446 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
6447 set_inactive = true;
6448
6449 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6450 zlog_debug("%s: dp-install sync-neigh vni %u ip %s mac %s if %s(%d) f 0x%x%s%s%s",
6451 caller, n->zevpn->vni,
6452 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6453 prefix_mac2str(&n->emac, macbuf,
6454 sizeof(macbuf)),
6455 ifp->name, n->ifindex, n->flags,
6456 set_router ? " router":"",
6457 set_static ? " static":"",
6458 set_inactive ? " inactive":"");
6459 dplane_local_neigh_add(ifp, &n->ip,
6460 &n->emac, set_router, set_static, set_inactive);
6461 }
6462
6463 static void zebra_vxlan_neigh_send_add_del_to_client(zebra_neigh_t *n,
6464 bool old_bgp_ready, bool new_bgp_ready)
6465 {
6466 if (new_bgp_ready)
6467 zevpn_neigh_send_add_to_client(n->zevpn->vni, &n->ip,
6468 &n->emac, n->mac, n->flags, n->loc_seq);
6469 else if (old_bgp_ready)
6470 zevpn_neigh_send_del_to_client(n->zevpn->vni, &n->ip,
6471 &n->emac, n->flags, n->state, true /*force*/);
6472 }
6473
6474 /* if the static flag associated with the neigh changes we need
6475 * to update the sync-neigh references against the MAC
6476 * and inform the dataplane about the static flag changes.
6477 */
6478 static void zebra_vxlan_sync_neigh_static_chg(zebra_neigh_t *n,
6479 bool old_n_static, bool new_n_static,
6480 bool defer_n_dp, bool defer_mac_dp,
6481 const char *caller)
6482 {
6483 zebra_mac_t *mac = n->mac;
6484 bool old_mac_static;
6485 bool new_mac_static;
6486 char macbuf[ETHER_ADDR_STRLEN];
6487 char ipbuf[INET6_ADDRSTRLEN];
6488
6489 if (old_n_static == new_n_static)
6490 return;
6491
6492 /* update the neigh sync references in the dataplane. if
6493 * the neigh is in the middle of updates the caller can
6494 * request for a defer
6495 */
6496 if (!defer_n_dp)
6497 zebra_vxlan_sync_neigh_dp_install(n, false /* set_inactive */,
6498 false /* force_clear_static */, __func__);
6499
6500 if (!mac)
6501 return;
6502
6503 /* update the mac sync ref cnt */
6504 old_mac_static = zebra_vxlan_mac_is_static(mac);
6505 if (new_n_static) {
6506 ++mac->sync_neigh_cnt;
6507 } else if (old_n_static) {
6508 if (mac->sync_neigh_cnt)
6509 --mac->sync_neigh_cnt;
6510 }
6511 new_mac_static = zebra_vxlan_mac_is_static(mac);
6512
6513 /* update the mac sync references in the dataplane */
6514 if ((old_mac_static != new_mac_static) && !defer_mac_dp)
6515 zebra_vxlan_sync_mac_dp_install(mac,
6516 false /* set_inactive */,
6517 false /* force_clear_static */,
6518 __func__);
6519
6520 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6521 zlog_debug("sync-neigh ref-chg vni %u ip %s mac %s f 0x%x %d%s%s%s%s by %s",
6522 n->zevpn->vni,
6523 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6524 prefix_mac2str(&n->emac, macbuf,
6525 sizeof(macbuf)),
6526 n->flags, mac->sync_neigh_cnt,
6527 old_n_static ? " old_n_static" : "",
6528 new_n_static ? " new_n_static" : "",
6529 old_mac_static ? " old_mac_static" : "",
6530 new_mac_static ? " new_mac_static" : "",
6531 caller);
6532 }
6533
6534 /* Neigh hold timer is used to age out peer-active flag.
6535 *
6536 * During this wait time we expect the dataplane component or an
6537 * external neighmgr daemon to probe existing hosts to independently
6538 * establish their presence on the ES.
6539 */
6540 static int zebra_vxlan_neigh_hold_exp_cb(struct thread *t)
6541 {
6542 zebra_neigh_t *n;
6543 bool old_bgp_ready;
6544 bool new_bgp_ready;
6545 bool old_n_static;
6546 bool new_n_static;
6547 char macbuf[ETHER_ADDR_STRLEN];
6548 char ipbuf[INET6_ADDRSTRLEN];
6549
6550 n = THREAD_ARG(t);
6551 /* the purpose of the hold timer is to age out the peer-active
6552 * flag
6553 */
6554 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
6555 return 0;
6556
6557 old_bgp_ready = zebra_vxlan_neigh_is_ready_for_bgp(n);
6558 old_n_static = zebra_vxlan_neigh_is_static(n);
6559 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
6560 new_bgp_ready = zebra_vxlan_neigh_is_ready_for_bgp(n);
6561 new_n_static = zebra_vxlan_neigh_is_static(n);
6562
6563 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6564 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x hold expired",
6565 n->zevpn->vni,
6566 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6567 prefix_mac2str(&n->emac, macbuf,
6568 sizeof(macbuf)),
6569 n->flags);
6570
6571 /* re-program the local neigh in the dataplane if the neigh is no
6572 * longer static
6573 */
6574 if (old_n_static != new_n_static)
6575 zebra_vxlan_sync_neigh_static_chg(n, old_n_static,
6576 new_n_static, false /*defer_n_dp*/,
6577 false /*defer_mac_dp*/, __func__);
6578
6579 /* inform bgp if needed */
6580 if (old_bgp_ready != new_bgp_ready)
6581 zebra_vxlan_neigh_send_add_del_to_client(n,
6582 old_bgp_ready, new_bgp_ready);
6583
6584 return 0;
6585 }
6586
6587 static inline void zebra_vxlan_neigh_start_hold_timer(zebra_neigh_t *n)
6588 {
6589 char macbuf[ETHER_ADDR_STRLEN];
6590 char ipbuf[INET6_ADDRSTRLEN];
6591
6592 if (n->hold_timer)
6593 return;
6594
6595 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6596 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x hold start",
6597 n->zevpn->vni,
6598 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6599 prefix_mac2str(&n->emac, macbuf,
6600 sizeof(macbuf)),
6601 n->flags);
6602 thread_add_timer(zrouter.master,
6603 zebra_vxlan_neigh_hold_exp_cb,
6604 n, zmh_info->neigh_hold_time,
6605 &n->hold_timer);
6606 }
6607
6608 static inline void zebra_vxlan_neigh_stop_hold_timer(zebra_neigh_t *n)
6609 {
6610 char macbuf[ETHER_ADDR_STRLEN];
6611 char ipbuf[INET6_ADDRSTRLEN];
6612
6613 if (!n->hold_timer)
6614 return;
6615
6616 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6617 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x hold stop",
6618 n->zevpn->vni,
6619 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6620 prefix_mac2str(&n->emac, macbuf,
6621 sizeof(macbuf)),
6622 n->flags);
6623 THREAD_OFF(n->hold_timer);
6624 }
6625
6626 static inline bool zebra_vxlan_neigh_clear_sync_info(zebra_neigh_t *n)
6627 {
6628 char macbuf[ETHER_ADDR_STRLEN];
6629 char ipbuf[INET6_ADDRSTRLEN];
6630 bool old_n_static = false;
6631 bool new_n_static = false;
6632
6633 if (n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) {
6634 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6635 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x clear",
6636 n->zevpn->vni,
6637 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6638 prefix_mac2str(&n->emac, macbuf,
6639 sizeof(macbuf)),
6640 n->flags);
6641
6642 old_n_static = zebra_vxlan_neigh_is_static(n);
6643 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_PEER_FLAGS);
6644 new_n_static = zebra_vxlan_neigh_is_static(n);
6645 if (old_n_static != new_n_static)
6646 zebra_vxlan_sync_neigh_static_chg(n, old_n_static,
6647 new_n_static, true /*defer_dp)*/,
6648 false/*defer_mac_dp*/, __func__);
6649 }
6650 zebra_vxlan_neigh_stop_hold_timer(n);
6651
6652 /* if the neigh static flag changed inform that a dp
6653 * re-install maybe needed
6654 */
6655 return old_n_static != new_n_static;
6656 }
6657
6658 static void zebra_vxlan_local_neigh_deref_mac(zebra_neigh_t *n,
6659 bool send_mac_update)
6660 {
6661 zebra_mac_t *mac = n->mac;
6662 zebra_evpn_t *zevpn = n->zevpn;
6663 char macbuf[ETHER_ADDR_STRLEN];
6664 char ipbuf[INET6_ADDRSTRLEN];
6665 bool old_static;
6666 bool new_static;
6667
6668 n->mac = NULL;
6669 if (!mac)
6670 return;
6671
6672 if ((n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) &&
6673 mac->sync_neigh_cnt){
6674 old_static = zebra_vxlan_mac_is_static(mac);
6675 --mac->sync_neigh_cnt;
6676 new_static = zebra_vxlan_mac_is_static(mac);
6677 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6678 zlog_debug("sync-neigh deref mac vni %u ip %s mac %s ref %d",
6679 n->zevpn->vni,
6680 ipaddr2str(&n->ip, ipbuf,
6681 sizeof(ipbuf)),
6682 prefix_mac2str(&n->emac, macbuf,
6683 sizeof(macbuf)),
6684 mac->sync_neigh_cnt);
6685 if ((old_static != new_static) && send_mac_update)
6686 /* program the local mac in the kernel */
6687 zebra_vxlan_sync_mac_dp_install(mac,
6688 false /* set_inactive */,
6689 false /* force_clear_static */,
6690 __func__);
6691 }
6692
6693 listnode_delete(mac->neigh_list, n);
6694 zevpn_deref_ip2mac(zevpn, mac);
6695 }
6696
6697 static void zebra_vxlan_local_neigh_ref_mac(zebra_neigh_t *n,
6698 struct ethaddr *macaddr, zebra_mac_t *mac,
6699 bool send_mac_update)
6700 {
6701 char macbuf[ETHER_ADDR_STRLEN];
6702 char ipbuf[INET6_ADDRSTRLEN];
6703 bool old_static;
6704 bool new_static;
6705
6706 memcpy(&n->emac, macaddr, ETH_ALEN);
6707 n->mac = mac;
6708
6709 /* Link to new MAC */
6710 if (!mac)
6711 return;
6712
6713 listnode_add_sort(mac->neigh_list, n);
6714 if (n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) {
6715 old_static = zebra_vxlan_mac_is_static(mac);
6716 ++mac->sync_neigh_cnt;
6717 new_static = zebra_vxlan_mac_is_static(mac);
6718 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6719 zlog_debug("sync-neigh ref mac vni %u ip %s mac %s ref %d",
6720 n->zevpn->vni,
6721 ipaddr2str(&n->ip, ipbuf,
6722 sizeof(ipbuf)),
6723 prefix_mac2str(&n->emac, macbuf,
6724 sizeof(macbuf)),
6725 mac->sync_neigh_cnt);
6726 if ((old_static != new_static) && send_mac_update)
6727 /* program the local mac in the kernel */
6728 zebra_vxlan_sync_mac_dp_install(mac,
6729 false /*set_inactive*/,
6730 false /*force_clear_static*/,
6731 __func__);
6732 }
6733 }
6734
6735 static inline bool zebra_vxlan_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn,
6736 zebra_neigh_t *n, struct ethaddr *macaddr, uint32_t seq)
6737 {
6738 char macbuf[ETHER_ADDR_STRLEN];
6739 char ipbuf[INET6_ADDRSTRLEN];
6740 uint32_t tmp_seq;
6741
6742 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
6743 tmp_seq = n->loc_seq;
6744 else
6745 tmp_seq = n->rem_seq;
6746
6747 if (seq < tmp_seq) {
6748 /* if the neigh was never advertised to bgp we must accept
6749 * whatever sequence number bgp sends
6750 * XXX - check with Vivek
6751 */
6752 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) &&
6753 !zebra_vxlan_neigh_is_ready_for_bgp(n)) {
6754 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6755 zlog_debug("sync-macip accept vni %u mac %s IP %s lower seq %u f 0x%x",
6756 zevpn->vni,
6757 prefix_mac2str(macaddr,
6758 macbuf, sizeof(macbuf)),
6759 ipaddr2str(&n->ip,
6760 ipbuf, sizeof(ipbuf)),
6761 tmp_seq, n->flags);
6762 return true;
6763 }
6764
6765 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6766 zlog_debug("sync-macip ignore vni %u mac %s IP %s as existing has higher seq %u f 0x%x",
6767 zevpn->vni,
6768 prefix_mac2str(macaddr,
6769 macbuf, sizeof(macbuf)),
6770 ipaddr2str(&n->ip,
6771 ipbuf, sizeof(ipbuf)),
6772 tmp_seq, n->flags);
6773 return false;
6774 }
6775
6776 return true;
6777 }
6778
6779 static void zebra_vxlan_sync_neigh_del(zebra_neigh_t *n)
6780 {
6781 bool old_n_static;
6782 bool new_n_static;
6783 char macbuf[ETHER_ADDR_STRLEN];
6784 char ipbuf[INET6_ADDRSTRLEN];
6785
6786 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
6787 zlog_debug("sync-neigh del vni %u ip %s mac %s f 0x%x",
6788 n->zevpn->vni,
6789 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6790 prefix_mac2str(&n->emac, macbuf,
6791 sizeof(macbuf)),
6792 n->flags);
6793
6794 old_n_static = zebra_vxlan_neigh_is_static(n);
6795 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
6796 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
6797 zebra_vxlan_neigh_start_hold_timer(n);
6798 new_n_static = zebra_vxlan_neigh_is_static(n);
6799
6800 if (old_n_static != new_n_static)
6801 zebra_vxlan_sync_neigh_static_chg(n, old_n_static,
6802 new_n_static, false /*defer-dp*/,
6803 false /*defer_mac_dp*/, __func__);
6804 }
6805
6806 static zebra_neigh_t *zebra_vxlan_proc_sync_neigh_update(zebra_evpn_t *zevpn,
6807 zebra_neigh_t *n, uint16_t ipa_len,
6808 struct ipaddr *ipaddr, uint8_t flags, uint32_t seq,
6809 esi_t *esi, struct sync_mac_ip_ctx *ctx)
6810 {
6811 struct interface *ifp = NULL;
6812 bool is_router;
6813 zebra_mac_t *mac = ctx->mac;
6814 uint32_t tmp_seq;
6815 bool old_router = false;
6816 bool old_bgp_ready = false;
6817 bool new_bgp_ready;
6818 bool inform_dataplane = false;
6819 bool inform_bgp = false;
6820 bool old_mac_static;
6821 bool new_mac_static;
6822 bool set_dp_inactive = false;
6823 struct zebra_if *zif;
6824 char macbuf[ETHER_ADDR_STRLEN];
6825 char ipbuf[INET6_ADDRSTRLEN];
6826 bool created;
6827 ifindex_t ifindex = 0;
6828
6829 /* locate l3-svi */
6830 zif = zevpn->vxlan_if->info;
6831 if (zif) {
6832 struct zebra_l2info_vxlan *vxl;
6833
6834 vxl = &zif->l2info.vxl;
6835 ifp = zevpn_map_to_svi(vxl->access_vlan,
6836 zif->brslave_info.br_if);
6837 if (ifp)
6838 ifindex = ifp->ifindex;
6839 }
6840
6841 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
6842 old_mac_static = zebra_vxlan_mac_is_static(mac);
6843
6844 if (!n) {
6845 uint32_t n_flags = 0;
6846
6847 /* New neighbor - create */
6848 SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL);
6849 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
6850 SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_PROXY);
6851 else
6852 SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
6853 SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
6854
6855 n = zevpn_neigh_add(zevpn, ipaddr, &mac->macaddr, mac,
6856 n_flags);
6857 n->ifindex = ifindex;
6858 ZEBRA_NEIGH_SET_ACTIVE(n);
6859
6860 created = true;
6861 inform_dataplane = true;
6862 inform_bgp = true;
6863 set_dp_inactive = true;
6864 } else {
6865 bool mac_change;
6866 uint32_t old_flags = n->flags;
6867 bool old_n_static;
6868 bool new_n_static;
6869
6870 created = false;
6871 old_n_static = zebra_vxlan_neigh_is_static(n);
6872 old_bgp_ready = zebra_vxlan_neigh_is_ready_for_bgp(n);
6873 old_router = !!CHECK_FLAG(n->flags,
6874 ZEBRA_NEIGH_ROUTER_FLAG);
6875
6876 mac_change = !!memcmp(&n->emac, &mac->macaddr, ETH_ALEN);
6877
6878 /* deref and clear old info */
6879 if (mac_change) {
6880 if (old_bgp_ready) {
6881 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip,
6882 &n->emac, n->flags, n->state,
6883 false /*force*/);
6884 old_bgp_ready = false;
6885 }
6886 if (n->mac)
6887 zebra_vxlan_local_neigh_deref_mac(n,
6888 false /*send_mac_update*/);
6889 }
6890 /* clear old fwd info */
6891 n->rem_seq = 0;
6892 n->r_vtep_ip.s_addr = 0;
6893
6894 /* setup new flags */
6895 n->flags = 0;
6896 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
6897 /* retain activity flag if the neigh was
6898 * previously local
6899 */
6900 if (old_flags & ZEBRA_NEIGH_LOCAL) {
6901 n->flags |= (old_flags & ZEBRA_NEIGH_LOCAL_INACTIVE);
6902 } else {
6903 inform_dataplane = true;
6904 set_dp_inactive = true;
6905 n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
6906 }
6907
6908 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
6909 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
6910 else
6911 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
6912
6913 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
6914 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
6915 /* if the neigh was peer-active previously we
6916 * need to keep the flag and start the
6917 * holdtimer on it. the peer-active flag is
6918 * cleared on holdtimer expiry.
6919 */
6920 if (CHECK_FLAG(old_flags,
6921 ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
6922 SET_FLAG(n->flags,
6923 ZEBRA_NEIGH_ES_PEER_ACTIVE);
6924 zebra_vxlan_neigh_start_hold_timer(n);
6925 }
6926 } else {
6927 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
6928 /* stop hold timer if a peer has verified
6929 * reachability
6930 */
6931 zebra_vxlan_neigh_stop_hold_timer(n);
6932 }
6933 ZEBRA_NEIGH_SET_ACTIVE(n);
6934
6935 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH &&
6936 (old_flags != n->flags))
6937 zlog_debug("sync-neigh vni %u ip %s mac %s old_f 0x%x new_f 0x%x",
6938 n->zevpn->vni,
6939 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
6940 prefix_mac2str(&n->emac, macbuf,
6941 sizeof(macbuf)),
6942 old_flags, n->flags);
6943
6944 new_n_static = zebra_vxlan_neigh_is_static(n);
6945 if (mac_change) {
6946 set_dp_inactive = true;
6947 n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
6948 inform_dataplane = true;
6949 zebra_vxlan_local_neigh_ref_mac(n, &mac->macaddr,
6950 mac, false /*send_mac_update*/);
6951 } else if (old_n_static != new_n_static) {
6952 inform_dataplane = true;
6953 /* if static flags have changed without a mac change
6954 * we need to create the correct sync-refs against
6955 * the existing mac
6956 */
6957 zebra_vxlan_sync_neigh_static_chg(n,
6958 old_n_static, new_n_static,
6959 true /*defer_dp*/, true /*defer_mac_dp*/,
6960 __func__);
6961 }
6962
6963 /* Update the forwarding info. */
6964 if (n->ifindex != ifindex) {
6965 n->ifindex = ifindex;
6966 inform_dataplane = true;
6967 }
6968 }
6969
6970 /* update the neigh seq. we don't bother with the mac seq as
6971 * sync_mac_update already took care of that
6972 */
6973 tmp_seq = MAX(n->loc_seq, seq);
6974 if (tmp_seq != n->loc_seq) {
6975 n->loc_seq = tmp_seq;
6976 inform_bgp = true;
6977 }
6978
6979 /* Mark Router flag (R-bit) */
6980 if (is_router)
6981 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
6982 else
6983 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
6984
6985 if (old_router != is_router)
6986 inform_dataplane = true;
6987
6988 new_bgp_ready = zebra_vxlan_neigh_is_ready_for_bgp(n);
6989 if (old_bgp_ready != new_bgp_ready)
6990 inform_bgp = true;
6991
6992 new_mac_static = zebra_vxlan_mac_is_static(mac);
6993 if ((old_mac_static != new_mac_static) ||
6994 ctx->mac_dp_update_deferred)
6995 zebra_vxlan_sync_mac_dp_install(mac,
6996 ctx->mac_inactive,
6997 false /* force_clear_static */,
6998 __func__);
6999
7000 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
7001 zlog_debug("sync-neigh %s vni %u ip %s mac %s if %s(%d) seq %d f 0x%x%s%s",
7002 created ?
7003 "created" : "updated",
7004 n->zevpn->vni,
7005 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
7006 prefix_mac2str(&n->emac, macbuf,
7007 sizeof(macbuf)),
7008 ifp ? ifp->name : "", ifindex,
7009 n->loc_seq, n->flags,
7010 inform_bgp ? " inform_bgp" : "",
7011 inform_dataplane ? " inform_dp" : "");
7012
7013 if (inform_dataplane)
7014 zebra_vxlan_sync_neigh_dp_install(n, set_dp_inactive,
7015 false /* force_clear_static */, __func__);
7016
7017 if (inform_bgp)
7018 zebra_vxlan_neigh_send_add_del_to_client(n,
7019 old_bgp_ready, new_bgp_ready);
7020
7021 return n;
7022 }
7023
7024 static void zebra_vxlan_process_sync_macip_add(zebra_evpn_t *zevpn,
7025 struct ethaddr *macaddr,
7026 uint16_t ipa_len,
7027 struct ipaddr *ipaddr,
7028 uint8_t flags,
7029 uint32_t seq,
7030 esi_t *esi)
7031 {
7032 struct sync_mac_ip_ctx ctx;
7033 char macbuf[ETHER_ADDR_STRLEN];
7034 char ipbuf[INET6_ADDRSTRLEN];
7035 bool sticky;
7036 bool remote_gw;
7037 zebra_neigh_t *n = NULL;
7038
7039 sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
7040 remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
7041 /* if sticky or remote-gw ignore updates from the peer */
7042 if (sticky || remote_gw) {
7043 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH ||
7044 IS_ZEBRA_DEBUG_EVPN_MH_MAC)
7045 zlog_debug("Ignore sync-macip vni %u mac %s%s%s%s%s",
7046 zevpn->vni,
7047 prefix_mac2str(macaddr, macbuf, sizeof(macbuf)),
7048 ipa_len ? " IP " : "",
7049 ipa_len ?
7050 ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "",
7051 sticky ? " sticky" : "",
7052 remote_gw ? " remote_gw" : "");
7053 return;
7054 }
7055
7056 if (ipa_len) {
7057 n = zevpn_neigh_lookup(zevpn, ipaddr);
7058 if (n &&
7059 !zebra_vxlan_neigh_is_bgp_seq_ok(zevpn,
7060 n, macaddr, seq))
7061 return;
7062 }
7063
7064 memset(&ctx, 0, sizeof(ctx));
7065 ctx.mac = zebra_vxlan_proc_sync_mac_update(zevpn, macaddr, ipa_len,
7066 ipaddr, flags, seq, esi, &ctx);
7067 if (ctx.ignore_macip || !ctx.mac || !ipa_len)
7068 return;
7069
7070 zebra_vxlan_proc_sync_neigh_update(zevpn, n, ipa_len,
7071 ipaddr, flags, seq, esi, &ctx);
7072 }
7073
7074 /************************** remote mac-ip handling **************************/
7075 /* Process a remote MACIP add from BGP. */
7076 static void process_remote_macip_add(vni_t vni,
7077 struct ethaddr *macaddr,
7078 uint16_t ipa_len,
7079 struct ipaddr *ipaddr,
7080 uint8_t flags,
7081 uint32_t seq,
7082 struct in_addr vtep_ip,
7083 esi_t *esi)
7084 {
7085 zebra_evpn_t *zevpn;
7086 zebra_vtep_t *zvtep;
7087 zebra_mac_t *mac = NULL, *old_mac = NULL;
7088 zebra_neigh_t *n = NULL;
7089 int update_mac = 0, update_neigh = 0;
7090 char buf[ETHER_ADDR_STRLEN];
7091 char buf1[INET6_ADDRSTRLEN];
7092 struct interface *ifp = NULL;
7093 struct zebra_if *zif = NULL;
7094 struct zebra_vrf *zvrf;
7095 uint32_t tmp_seq;
7096 bool sticky;
7097 bool remote_gw;
7098 bool is_router;
7099 bool do_dad = false;
7100 bool is_dup_detect = false;
7101 esi_t *old_esi;
7102 bool old_static = false;
7103
7104 /* Locate EVPN hash entry - expected to exist. */
7105 zevpn = zevpn_lookup(vni);
7106 if (!zevpn) {
7107 zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni);
7108 return;
7109 }
7110
7111 ifp = zevpn->vxlan_if;
7112 if (ifp)
7113 zif = ifp->info;
7114 if (!ifp ||
7115 !if_is_operative(ifp) ||
7116 !zif ||
7117 !zif->brslave_info.br_if) {
7118 zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
7119 vni);
7120 return;
7121 }
7122
7123 /* Type-2 routes from another PE can be interpreted as remote or
7124 * SYNC based on the destination ES -
7125 * SYNC - if ES is local
7126 * REMOTE - if ES is not local
7127 */
7128 if (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) {
7129 zebra_vxlan_process_sync_macip_add(zevpn, macaddr, ipa_len,
7130 ipaddr, flags, seq, esi);
7131 return;
7132 }
7133
7134 /* The remote VTEP specified should normally exist, but it is
7135 * possible that when peering comes up, peer may advertise MACIP
7136 * routes before advertising type-3 routes.
7137 */
7138 if (vtep_ip.s_addr) {
7139 zvtep = zevpn_vtep_find(zevpn, &vtep_ip);
7140 if (!zvtep) {
7141 zvtep = zevpn_vtep_add(zevpn, &vtep_ip,
7142 VXLAN_FLOOD_DISABLED);
7143 if (!zvtep) {
7144 flog_err(
7145 EC_ZEBRA_VTEP_ADD_FAILED,
7146 "Failed to add remote VTEP, VNI %u zevpn %p upon remote MACIP ADD",
7147 vni, zevpn);
7148 return;
7149 }
7150
7151 zevpn_vtep_install(zevpn, zvtep);
7152 }
7153 }
7154
7155 sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
7156 remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
7157 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
7158
7159 mac = zevpn_mac_lookup(zevpn, macaddr);
7160
7161 /* Ignore if the mac is already present as a gateway mac */
7162 if (mac &&
7163 CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
7164 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
7165 if (IS_ZEBRA_DEBUG_VXLAN)
7166 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
7167 vni,
7168 prefix_mac2str(macaddr, buf, sizeof(buf)),
7169 ipa_len ? " IP " : "",
7170 ipa_len ?
7171 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
7172 return;
7173 }
7174
7175 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
7176 if (!zvrf)
7177 return;
7178
7179 old_esi = (mac && mac->es) ? &mac->es->esi : zero_esi;
7180
7181 /* check if the remote MAC is unknown or has a change.
7182 * If so, that needs to be updated first. Note that client could
7183 * install MAC and MACIP separately or just install the latter.
7184 */
7185 if (!mac
7186 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
7187 || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
7188 || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
7189 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
7190 || memcmp(old_esi, esi, sizeof(esi_t))
7191 || seq != mac->rem_seq)
7192 update_mac = 1;
7193
7194 if (update_mac) {
7195 if (!mac) {
7196 mac = zevpn_mac_add(zevpn, macaddr);
7197 if (!mac) {
7198 zlog_warn(
7199 "Failed to add MAC %s VNI %u Remote VTEP %s",
7200 prefix_mac2str(macaddr, buf,
7201 sizeof(buf)),
7202 vni, inet_ntoa(vtep_ip));
7203 return;
7204 }
7205
7206 zebra_evpn_es_mac_ref(mac, esi);
7207
7208 /* Is this MAC created for a MACIP? */
7209 if (ipa_len)
7210 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7211 } else {
7212 zebra_evpn_es_mac_ref(mac, esi);
7213
7214 /* When host moves but changes its (MAC,IP)
7215 * binding, BGP may install a MACIP entry that
7216 * corresponds to "older" location of the host
7217 * in transient situations (because {IP1,M1}
7218 * is a different route from {IP1,M2}). Check
7219 * the sequence number and ignore this update
7220 * if appropriate.
7221 */
7222 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
7223 tmp_seq = mac->loc_seq;
7224 else
7225 tmp_seq = mac->rem_seq;
7226
7227 if (seq < tmp_seq) {
7228 if (IS_ZEBRA_DEBUG_VXLAN)
7229 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing MAC has higher seq %u flags 0x%x",
7230 vni,
7231 prefix_mac2str(macaddr,
7232 buf, sizeof(buf)),
7233 ipa_len ? " IP " : "",
7234 ipa_len ?
7235 ipaddr2str(ipaddr,
7236 buf1, sizeof(buf1)) : "",
7237 tmp_seq, mac->flags);
7238 return;
7239 }
7240 }
7241
7242 /* Check MAC's curent state is local (this is the case
7243 * where MAC has moved from L->R) and check previous
7244 * detection started via local learning.
7245 * RFC-7432: A PE/VTEP that detects a MAC mobility
7246 * event via local learning starts an M-second timer.
7247 *
7248 * VTEP-IP or seq. change alone is not considered
7249 * for dup. detection.
7250 *
7251 * MAC is already marked duplicate set dad, then
7252 * is_dup_detect will be set to not install the entry.
7253 */
7254 if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
7255 mac->dad_count) ||
7256 CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
7257 do_dad = true;
7258
7259 /* Remove local MAC from BGP. */
7260 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
7261 /* force drop the sync flags */
7262 old_static = zebra_vxlan_mac_is_static(mac);
7263 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
7264 zlog_debug("sync-mac->remote vni %u mac %s es %s seq %d f 0x%x",
7265 zevpn->vni,
7266 prefix_mac2str(macaddr,
7267 buf, sizeof(buf)),
7268 mac->es ?
7269 mac->es->esi_str : "-",
7270 mac->loc_seq,
7271 mac->flags);
7272 zebra_vxlan_mac_clear_sync_info(mac);
7273 zevpn_mac_send_del_to_client(zevpn->vni, macaddr,
7274 mac->flags, false /* force */);
7275 }
7276
7277 /* Set "auto" and "remote" forwarding info. */
7278 UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
7279 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
7280 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
7281 mac->fwd_info.r_vtep_ip = vtep_ip;
7282
7283 if (sticky)
7284 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7285 else
7286 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
7287
7288 if (remote_gw)
7289 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
7290 else
7291 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
7292
7293 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac,
7294 mac->fwd_info.r_vtep_ip,
7295 do_dad, &is_dup_detect,
7296 false);
7297
7298 if (!is_dup_detect) {
7299 zevpn_process_neigh_on_remote_mac_add(zevpn, mac);
7300 /* Install the entry. */
7301 zevpn_rem_mac_install(zevpn, mac, old_static);
7302 }
7303 }
7304
7305 /* Update seq number. */
7306 mac->rem_seq = seq;
7307
7308 /* If there is no IP, return after clearing AUTO flag of MAC. */
7309 if (!ipa_len) {
7310 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7311 return;
7312 }
7313
7314 /* Reset flag */
7315 do_dad = false;
7316 old_static = false;
7317
7318 /* Check if the remote neighbor itself is unknown or has a
7319 * change. If so, create or update and then install the entry.
7320 */
7321 n = zevpn_neigh_lookup(zevpn, ipaddr);
7322 if (!n
7323 || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
7324 || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
7325 || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0)
7326 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)
7327 || seq != n->rem_seq)
7328 update_neigh = 1;
7329
7330 if (update_neigh) {
7331 if (!n) {
7332 n = zevpn_neigh_add(zevpn, ipaddr, macaddr, mac, 0);
7333 if (!n) {
7334 zlog_warn(
7335 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
7336 ipaddr2str(ipaddr, buf1,
7337 sizeof(buf1)),
7338 prefix_mac2str(macaddr, buf,
7339 sizeof(buf)),
7340 vni, inet_ntoa(vtep_ip));
7341 return;
7342 }
7343
7344 } else {
7345 const char *n_type;
7346
7347 /* When host moves but changes its (MAC,IP)
7348 * binding, BGP may install a MACIP entry that
7349 * corresponds to "older" location of the host
7350 * in transient situations (because {IP1,M1}
7351 * is a different route from {IP1,M2}). Check
7352 * the sequence number and ignore this update
7353 * if appropriate.
7354 */
7355 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
7356 tmp_seq = n->loc_seq;
7357 n_type = "local";
7358 } else {
7359 tmp_seq = n->rem_seq;
7360 n_type = "remote";
7361 }
7362 if (seq < tmp_seq) {
7363 if (IS_ZEBRA_DEBUG_VXLAN)
7364 zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
7365 vni,
7366 prefix_mac2str(macaddr,
7367 buf, sizeof(buf)),
7368 " IP ",
7369 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
7370 n_type,
7371 tmp_seq);
7372 return;
7373 }
7374 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
7375 old_static = zebra_vxlan_neigh_is_static(n);
7376 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
7377 zlog_debug("sync->remote neigh vni %u ip %s mac %s seq %d f0x%x",
7378 n->zevpn->vni,
7379 ipaddr2str(&n->ip, buf1,
7380 sizeof(buf1)),
7381 prefix_mac2str(&n->emac, buf,
7382 sizeof(buf)),
7383 seq, n->flags);
7384 zebra_vxlan_neigh_clear_sync_info(n);
7385 if (IS_ZEBRA_NEIGH_ACTIVE(n))
7386 zevpn_mac_send_del_to_client(zevpn->vni,
7387 macaddr, mac->flags,
7388 false /*force*/);
7389 }
7390 if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) {
7391 /* update neigh list for macs */
7392 old_mac = zevpn_mac_lookup(zevpn, &n->emac);
7393 if (old_mac) {
7394 listnode_delete(old_mac->neigh_list, n);
7395 n->mac = NULL;
7396 zevpn_deref_ip2mac(zevpn, old_mac);
7397 }
7398 n->mac = mac;
7399 listnode_add_sort(mac->neigh_list, n);
7400 memcpy(&n->emac, macaddr, ETH_ALEN);
7401
7402 /* Check Neigh's curent state is local
7403 * (this is the case where neigh/host has moved
7404 * from L->R) and check previous detction
7405 * started via local learning.
7406 *
7407 * RFC-7432: A PE/VTEP that detects a MAC
7408 * mobilit event via local learning starts
7409 * an M-second timer.
7410 * VTEP-IP or seq. change along is not
7411 * considered for dup. detection.
7412 *
7413 * Mobilty event scenario-B IP-MAC binding
7414 * changed.
7415 */
7416 if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
7417 && n->dad_count)
7418 do_dad = true;
7419
7420 }
7421 }
7422
7423 /* Set "remote" forwarding info. */
7424 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
7425 n->r_vtep_ip = vtep_ip;
7426 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
7427
7428 /* Set router flag (R-bit) to this Neighbor entry */
7429 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
7430 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
7431 else
7432 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
7433
7434 /* Check old or new MAC detected as duplicate,
7435 * inherit duplicate flag to this neigh.
7436 */
7437 if (zebra_vxlan_ip_inherit_dad_from_mac(zvrf, old_mac,
7438 mac, n)) {
7439 flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
7440 "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
7441 zevpn->vni,
7442 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
7443 ipaddr2str(&n->ip, buf1, sizeof(buf1)));
7444 }
7445
7446 /* Check duplicate address detection for IP */
7447 zebra_vxlan_dup_addr_detect_for_neigh(zvrf, n,
7448 n->r_vtep_ip,
7449 do_dad,
7450 &is_dup_detect,
7451 false);
7452 /* Install the entry. */
7453 if (!is_dup_detect)
7454 zevpn_rem_neigh_install(zevpn, n, old_static);
7455 }
7456
7457 zevpn_probe_neigh_on_mac_add(zevpn, mac);
7458
7459 /* Update seq number. */
7460 n->rem_seq = seq;
7461 }
7462
7463 static void zebra_vxlan_rem_mac_del(zebra_evpn_t *zevpn,
7464 zebra_mac_t *mac)
7465 {
7466 zevpn_process_neigh_on_remote_mac_del(zevpn, mac);
7467 /* the remote sequence number in the auto mac entry
7468 * needs to be reset to 0 as the mac entry may have
7469 * been removed on all VTEPs (including
7470 * the originating one)
7471 */
7472 mac->rem_seq = 0;
7473
7474 /* If all remote neighbors referencing a remote MAC
7475 * go away, we need to uninstall the MAC.
7476 */
7477 if (remote_neigh_count(mac) == 0) {
7478 zevpn_rem_mac_uninstall(zevpn, mac);
7479 zebra_evpn_es_mac_deref_entry(mac);
7480 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
7481 }
7482
7483 if (list_isempty(mac->neigh_list))
7484 zevpn_mac_del(zevpn, mac);
7485 else
7486 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
7487 }
7488
7489 /* Process a remote MACIP delete from BGP. */
7490 static void process_remote_macip_del(vni_t vni,
7491 struct ethaddr *macaddr,
7492 uint16_t ipa_len,
7493 struct ipaddr *ipaddr,
7494 struct in_addr vtep_ip)
7495 {
7496 zebra_evpn_t *zevpn;
7497 zebra_mac_t *mac = NULL;
7498 zebra_neigh_t *n = NULL;
7499 struct interface *ifp = NULL;
7500 struct zebra_if *zif = NULL;
7501 struct zebra_ns *zns;
7502 struct zebra_l2info_vxlan *vxl;
7503 struct zebra_vrf *zvrf;
7504 char buf[ETHER_ADDR_STRLEN];
7505 char buf1[INET6_ADDRSTRLEN];
7506
7507 /* Locate EVPN hash entry - expected to exist. */
7508 zevpn = zevpn_lookup(vni);
7509 if (!zevpn) {
7510 if (IS_ZEBRA_DEBUG_VXLAN)
7511 zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
7512 return;
7513 }
7514
7515 ifp = zevpn->vxlan_if;
7516 if (ifp)
7517 zif = ifp->info;
7518 if (!ifp ||
7519 !if_is_operative(ifp) ||
7520 !zif ||
7521 !zif->brslave_info.br_if) {
7522 if (IS_ZEBRA_DEBUG_VXLAN)
7523 zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
7524 vni);
7525 return;
7526 }
7527 zns = zebra_ns_lookup(NS_DEFAULT);
7528 vxl = &zif->l2info.vxl;
7529
7530 mac = zevpn_mac_lookup(zevpn, macaddr);
7531 if (ipa_len)
7532 n = zevpn_neigh_lookup(zevpn, ipaddr);
7533
7534 if (n && !mac) {
7535 zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
7536 prefix_mac2str(macaddr, buf, sizeof(buf)),
7537 ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni);
7538 return;
7539 }
7540
7541 /* If the remote mac or neighbor doesn't exist there is nothing
7542 * more to do. Otherwise, uninstall the entry and then remove it.
7543 */
7544 if (!mac && !n)
7545 return;
7546
7547 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
7548
7549 /* Ignore the delete if this mac is a gateway mac-ip */
7550 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
7551 && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
7552 zlog_warn(
7553 "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
7554 vni,
7555 prefix_mac2str(macaddr, buf, sizeof(buf)),
7556 ipa_len ? " IP " : "",
7557 ipa_len ?
7558 ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
7559 return;
7560 }
7561
7562 /* Uninstall remote neighbor or MAC. */
7563 if (n) {
7564 if (zvrf->dad_freeze &&
7565 CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE) &&
7566 CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) &&
7567 (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) {
7568 struct interface *vlan_if;
7569
7570 vlan_if = zevpn_map_to_svi(vxl->access_vlan,
7571 zif->brslave_info.br_if);
7572 if (IS_ZEBRA_DEBUG_VXLAN)
7573 zlog_debug(
7574 "%s: IP %s (flags 0x%x intf %s) is remote and duplicate, read kernel for local entry",
7575 __func__,
7576 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
7577 n->flags,
7578 vlan_if ? vlan_if->name : "Unknown");
7579 if (vlan_if)
7580 neigh_read_specific_ip(ipaddr, vlan_if);
7581 }
7582
7583 /* When the MAC changes for an IP, it is possible the
7584 * client may update the new MAC before trying to delete the
7585 * "old" neighbor (as these are two different MACIP routes).
7586 * Do the delete only if the MAC matches.
7587 */
7588 if (!memcmp(n->emac.octet, macaddr->octet, ETH_ALEN)) {
7589 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
7590 zebra_vxlan_sync_neigh_del(n);
7591 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
7592 zevpn_neigh_uninstall(zevpn, n);
7593 zevpn_neigh_del(zevpn, n);
7594 zevpn_deref_ip2mac(zevpn, mac);
7595 }
7596 }
7597 } else {
7598 /* DAD: when MAC is freeze state as remote learn event,
7599 * remote mac-ip delete event is received will result in freeze
7600 * entry removal, first fetch kernel for the same entry present
7601 * as LOCAL and reachable, avoid deleting this entry instead
7602 * use kerenel local entry to update during unfreeze time.
7603 */
7604 if (zvrf->dad_freeze &&
7605 CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE) &&
7606 CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
7607 if (IS_ZEBRA_DEBUG_VXLAN)
7608 zlog_debug(
7609 "%s: MAC %s (flags 0x%x) is remote and duplicate, read kernel for local entry",
7610 __func__,
7611 prefix_mac2str(macaddr, buf,
7612 sizeof(buf)),
7613 mac->flags);
7614 macfdb_read_specific_mac(zns, zif->brslave_info.br_if,
7615 macaddr, vxl->access_vlan);
7616 }
7617
7618 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
7619 if (!ipa_len)
7620 zebra_vxlan_sync_mac_del(mac);
7621 } else if (CHECK_FLAG(mac->flags, ZEBRA_NEIGH_REMOTE)) {
7622 zebra_vxlan_rem_mac_del(zevpn, mac);
7623 }
7624 }
7625 }
7626
7627
7628 /* Public functions */
7629
7630 int is_l3vni_for_prefix_routes_only(vni_t vni)
7631 {
7632 zebra_l3vni_t *zl3vni = NULL;
7633
7634 zl3vni = zl3vni_lookup(vni);
7635 if (!zl3vni)
7636 return 0;
7637
7638 return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
7639 }
7640
7641 /* handle evpn route in vrf table */
7642 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
7643 const struct ipaddr *vtep_ip,
7644 const struct prefix *host_prefix)
7645 {
7646 zebra_l3vni_t *zl3vni = NULL;
7647 struct ipaddr ipv4_vtep;
7648
7649 zl3vni = zl3vni_from_vrf(vrf_id);
7650 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
7651 return;
7652
7653 /*
7654 * add the next hop neighbor -
7655 * neigh to be installed is the ipv6 nexthop neigh
7656 */
7657 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
7658
7659 /*
7660 * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
7661 * address. Rmac is programmed against the ipv4 vtep because we only
7662 * support ipv4 tunnels in the h/w right now
7663 */
7664 memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
7665 ipv4_vtep.ipa_type = IPADDR_V4;
7666 if (vtep_ip->ipa_type == IPADDR_V6)
7667 ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
7668 &(ipv4_vtep.ipaddr_v4));
7669 else
7670 memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
7671 sizeof(struct in_addr));
7672
7673 /*
7674 * add the rmac - remote rmac to be installed is against the ipv4
7675 * nexthop address
7676 */
7677 zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
7678 }
7679
7680 /* handle evpn vrf route delete */
7681 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
7682 struct ipaddr *vtep_ip,
7683 struct prefix *host_prefix)
7684 {
7685 zebra_l3vni_t *zl3vni = NULL;
7686 zebra_neigh_t *nh = NULL;
7687 zebra_mac_t *zrmac = NULL;
7688
7689 zl3vni = zl3vni_from_vrf(vrf_id);
7690 if (!zl3vni)
7691 return;
7692
7693 /* find the next hop entry and rmac entry */
7694 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
7695 if (!nh)
7696 return;
7697 zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
7698
7699 /* delete the next hop entry */
7700 zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
7701
7702 /* delete the rmac entry */
7703 if (zrmac)
7704 zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix);
7705
7706 }
7707
7708 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
7709 struct ethaddr *rmac, bool use_json)
7710 {
7711 zebra_l3vni_t *zl3vni = NULL;
7712 zebra_mac_t *zrmac = NULL;
7713 json_object *json = NULL;
7714
7715 if (!is_evpn_enabled()) {
7716 if (use_json)
7717 vty_out(vty, "{}\n");
7718 return;
7719 }
7720
7721 if (use_json)
7722 json = json_object_new_object();
7723
7724 zl3vni = zl3vni_lookup(l3vni);
7725 if (!zl3vni) {
7726 if (use_json)
7727 vty_out(vty, "{}\n");
7728 else
7729 vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
7730 return;
7731 }
7732
7733 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
7734 if (!zrmac) {
7735 if (use_json)
7736 vty_out(vty, "{}\n");
7737 else
7738 vty_out(vty,
7739 "%% Requested RMAC doesn't exist in L3-VNI %u",
7740 l3vni);
7741 return;
7742 }
7743
7744 zl3vni_print_rmac(zrmac, vty, json);
7745
7746 if (use_json) {
7747 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7748 json, JSON_C_TO_STRING_PRETTY));
7749 json_object_free(json);
7750 }
7751 }
7752
7753 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
7754 {
7755 zebra_l3vni_t *zl3vni;
7756 uint32_t num_rmacs;
7757 struct rmac_walk_ctx wctx;
7758 json_object *json = NULL;
7759
7760 if (!is_evpn_enabled())
7761 return;
7762
7763 zl3vni = zl3vni_lookup(l3vni);
7764 if (!zl3vni) {
7765 if (use_json)
7766 vty_out(vty, "{}\n");
7767 else
7768 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
7769 return;
7770 }
7771 num_rmacs = hashcount(zl3vni->rmac_table);
7772 if (!num_rmacs)
7773 return;
7774
7775 if (use_json)
7776 json = json_object_new_object();
7777
7778 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
7779 wctx.vty = vty;
7780 wctx.json = json;
7781 if (!use_json) {
7782 vty_out(vty, "Number of Remote RMACs known for this VNI: %u\n",
7783 num_rmacs);
7784 vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
7785 } else
7786 json_object_int_add(json, "numRmacs", num_rmacs);
7787
7788 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
7789
7790 if (use_json) {
7791 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7792 json, JSON_C_TO_STRING_PRETTY));
7793 json_object_free(json);
7794 }
7795 }
7796
7797 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
7798 {
7799 json_object *json = NULL;
7800 void *args[2];
7801
7802 if (!is_evpn_enabled()) {
7803 if (use_json)
7804 vty_out(vty, "{}\n");
7805 return;
7806 }
7807
7808 if (use_json)
7809 json = json_object_new_object();
7810
7811 args[0] = vty;
7812 args[1] = json;
7813 hash_iterate(zrouter.l3vni_table,
7814 (void (*)(struct hash_bucket *,
7815 void *))zl3vni_print_rmac_hash_all_vni,
7816 args);
7817
7818 if (use_json) {
7819 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7820 json, JSON_C_TO_STRING_PRETTY));
7821 json_object_free(json);
7822 }
7823 }
7824
7825 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
7826 struct ipaddr *ip, bool use_json)
7827 {
7828 zebra_l3vni_t *zl3vni = NULL;
7829 zebra_neigh_t *n = NULL;
7830 json_object *json = NULL;
7831
7832 if (!is_evpn_enabled()) {
7833 if (use_json)
7834 vty_out(vty, "{}\n");
7835 return;
7836 }
7837
7838 if (use_json)
7839 json = json_object_new_object();
7840
7841 zl3vni = zl3vni_lookup(l3vni);
7842 if (!zl3vni) {
7843 if (use_json)
7844 vty_out(vty, "{}\n");
7845 else
7846 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
7847 return;
7848 }
7849
7850 n = zl3vni_nh_lookup(zl3vni, ip);
7851 if (!n) {
7852 if (use_json)
7853 vty_out(vty, "{}\n");
7854 else
7855 vty_out(vty,
7856 "%% Requested next-hop not present for L3-VNI %u",
7857 l3vni);
7858 return;
7859 }
7860
7861 zl3vni_print_nh(n, vty, json);
7862
7863 if (use_json) {
7864 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7865 json, JSON_C_TO_STRING_PRETTY));
7866 json_object_free(json);
7867 }
7868 }
7869
7870 void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
7871 {
7872 uint32_t num_nh;
7873 struct nh_walk_ctx wctx;
7874 json_object *json = NULL;
7875 zebra_l3vni_t *zl3vni = NULL;
7876
7877 if (!is_evpn_enabled())
7878 return;
7879
7880 zl3vni = zl3vni_lookup(l3vni);
7881 if (!zl3vni) {
7882 if (use_json)
7883 vty_out(vty, "{}\n");
7884 else
7885 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
7886 return;
7887 }
7888
7889 num_nh = hashcount(zl3vni->nh_table);
7890 if (!num_nh)
7891 return;
7892
7893 if (use_json)
7894 json = json_object_new_object();
7895
7896 wctx.vty = vty;
7897 wctx.json = json;
7898 if (!use_json) {
7899 vty_out(vty, "Number of NH Neighbors known for this VNI: %u\n",
7900 num_nh);
7901 vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
7902 } else
7903 json_object_int_add(json, "numNextHops", num_nh);
7904
7905 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
7906
7907 if (use_json) {
7908 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7909 json, JSON_C_TO_STRING_PRETTY));
7910 json_object_free(json);
7911 }
7912 }
7913
7914 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
7915 {
7916 json_object *json = NULL;
7917 void *args[2];
7918
7919 if (!is_evpn_enabled()) {
7920 if (use_json)
7921 vty_out(vty, "{}\n");
7922 return;
7923 }
7924
7925 if (use_json)
7926 json = json_object_new_object();
7927
7928 args[0] = vty;
7929 args[1] = json;
7930 hash_iterate(zrouter.l3vni_table,
7931 (void (*)(struct hash_bucket *,
7932 void *))zl3vni_print_nh_hash_all_vni,
7933 args);
7934
7935 if (use_json) {
7936 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7937 json, JSON_C_TO_STRING_PRETTY));
7938 json_object_free(json);
7939 }
7940 }
7941
7942 /*
7943 * Display L3 VNI information (VTY command handler).
7944 */
7945 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
7946 {
7947 void *args[2];
7948 json_object *json = NULL;
7949 zebra_l3vni_t *zl3vni = NULL;
7950
7951 if (!is_evpn_enabled()) {
7952 if (use_json)
7953 vty_out(vty, "{}\n");
7954 return;
7955 }
7956
7957 zl3vni = zl3vni_lookup(vni);
7958 if (!zl3vni) {
7959 if (use_json)
7960 vty_out(vty, "{}\n");
7961 else
7962 vty_out(vty, "%% VNI %u does not exist\n", vni);
7963 return;
7964 }
7965
7966 if (use_json)
7967 json = json_object_new_object();
7968
7969 args[0] = vty;
7970 args[1] = json;
7971 zl3vni_print(zl3vni, (void *)args);
7972
7973 if (use_json) {
7974 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7975 json, JSON_C_TO_STRING_PRETTY));
7976 json_object_free(json);
7977 }
7978 }
7979
7980 void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
7981 json_object *json_vrfs)
7982 {
7983 char buf[ETHER_ADDR_STRLEN];
7984 zebra_l3vni_t *zl3vni = NULL;
7985
7986 zl3vni = zl3vni_lookup(zvrf->l3vni);
7987 if (!zl3vni)
7988 return;
7989
7990 if (!json_vrfs) {
7991 vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
7992 zvrf_name(zvrf), zl3vni->vni,
7993 zl3vni_vxlan_if_name(zl3vni),
7994 zl3vni_svi_if_name(zl3vni), zl3vni_state2str(zl3vni),
7995 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
7996 } else {
7997 json_object *json_vrf = NULL;
7998
7999 json_vrf = json_object_new_object();
8000 json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
8001 json_object_int_add(json_vrf, "vni", zl3vni->vni);
8002 json_object_string_add(json_vrf, "vxlanIntf",
8003 zl3vni_vxlan_if_name(zl3vni));
8004 json_object_string_add(json_vrf, "sviIntf",
8005 zl3vni_svi_if_name(zl3vni));
8006 json_object_string_add(json_vrf, "state",
8007 zl3vni_state2str(zl3vni));
8008 json_object_string_add(
8009 json_vrf, "routerMac",
8010 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
8011 json_object_array_add(json_vrfs, json_vrf);
8012 }
8013 }
8014
8015 /*
8016 * Display Neighbors for a VNI (VTY command handler).
8017 */
8018 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
8019 vni_t vni, bool use_json)
8020 {
8021 zebra_evpn_t *zevpn;
8022 uint32_t num_neigh;
8023 struct neigh_walk_ctx wctx;
8024 json_object *json = NULL;
8025
8026 if (!is_evpn_enabled())
8027 return;
8028 zevpn = zevpn_lookup(vni);
8029 if (!zevpn) {
8030 if (use_json)
8031 vty_out(vty, "{}\n");
8032 else
8033 vty_out(vty, "%% VNI %u does not exist\n", vni);
8034 return;
8035 }
8036 num_neigh = hashcount(zevpn->neigh_table);
8037 if (!num_neigh)
8038 return;
8039
8040 if (use_json)
8041 json = json_object_new_object();
8042
8043 /* Since we have IPv6 addresses to deal with which can vary widely in
8044 * size, we try to be a bit more elegant in display by first computing
8045 * the maximum width.
8046 */
8047 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
8048 wctx.zevpn = zevpn;
8049 wctx.vty = vty;
8050 wctx.addr_width = 15;
8051 wctx.json = json;
8052 hash_iterate(zevpn->neigh_table, zevpn_find_neigh_addr_width, &wctx);
8053
8054 if (!use_json) {
8055 vty_out(vty,
8056 "Number of ARPs (local and remote) known for this VNI: %u\n",
8057 num_neigh);
8058 zevpn_print_neigh_hdr(vty, &wctx);
8059 } else
8060 json_object_int_add(json, "numArpNd", num_neigh);
8061
8062 hash_iterate(zevpn->neigh_table, zevpn_print_neigh_hash, &wctx);
8063 if (use_json) {
8064 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8065 json, JSON_C_TO_STRING_PRETTY));
8066 json_object_free(json);
8067 }
8068 }
8069
8070 /*
8071 * Display neighbors across all VNIs (VTY command handler).
8072 */
8073 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
8074 bool print_dup, bool use_json)
8075 {
8076 json_object *json = NULL;
8077 void *args[3];
8078
8079 if (!is_evpn_enabled())
8080 return;
8081
8082 if (use_json)
8083 json = json_object_new_object();
8084
8085 args[0] = vty;
8086 args[1] = json;
8087 args[2] = (void *)(ptrdiff_t)print_dup;
8088
8089 hash_iterate(zvrf->evpn_table,
8090 (void (*)(struct hash_bucket *,
8091 void *))zevpn_print_neigh_hash_all_evpn,
8092 args);
8093 if (use_json) {
8094 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8095 json, JSON_C_TO_STRING_PRETTY));
8096 json_object_free(json);
8097 }
8098 }
8099
8100 /*
8101 * Display neighbors across all VNIs in detail(VTY command handler).
8102 */
8103 void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
8104 struct zebra_vrf *zvrf,
8105 bool print_dup, bool use_json)
8106 {
8107 json_object *json = NULL;
8108 void *args[3];
8109
8110 if (!is_evpn_enabled())
8111 return;
8112
8113 if (use_json)
8114 json = json_object_new_object();
8115
8116 args[0] = vty;
8117 args[1] = json;
8118 args[2] = (void *)(ptrdiff_t)print_dup;
8119
8120 hash_iterate(zvrf->evpn_table,
8121 (void (*)(struct hash_bucket *,
8122 void *))zevpn_print_neigh_hash_all_evpn_detail,
8123 args);
8124 if (use_json) {
8125 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8126 json, JSON_C_TO_STRING_PRETTY));
8127 json_object_free(json);
8128 }
8129 }
8130
8131 /*
8132 * Display specific neighbor for a VNI, if present (VTY command handler).
8133 */
8134 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
8135 struct zebra_vrf *zvrf, vni_t vni,
8136 struct ipaddr *ip, bool use_json)
8137 {
8138 zebra_evpn_t *zevpn;
8139 zebra_neigh_t *n;
8140 json_object *json = NULL;
8141
8142 if (!is_evpn_enabled())
8143 return;
8144 zevpn = zevpn_lookup(vni);
8145 if (!zevpn) {
8146 if (use_json)
8147 vty_out(vty, "{}\n");
8148 else
8149 vty_out(vty, "%% VNI %u does not exist\n", vni);
8150 return;
8151 }
8152 n = zevpn_neigh_lookup(zevpn, ip);
8153 if (!n) {
8154 if (!use_json)
8155 vty_out(vty,
8156 "%% Requested neighbor does not exist in VNI %u\n",
8157 vni);
8158 return;
8159 }
8160 if (use_json)
8161 json = json_object_new_object();
8162
8163 zevpn_print_neigh(n, vty, json);
8164
8165 if (use_json) {
8166 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8167 json, JSON_C_TO_STRING_PRETTY));
8168 json_object_free(json);
8169 }
8170 }
8171
8172 /*
8173 * Display neighbors for a VNI from specific VTEP (VTY command handler).
8174 * By definition, these are remote neighbors.
8175 */
8176 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
8177 vni_t vni, struct in_addr vtep_ip,
8178 bool use_json)
8179 {
8180 zebra_evpn_t *zevpn;
8181 uint32_t num_neigh;
8182 struct neigh_walk_ctx wctx;
8183 json_object *json = NULL;
8184
8185 if (!is_evpn_enabled())
8186 return;
8187 zevpn = zevpn_lookup(vni);
8188 if (!zevpn) {
8189 if (use_json)
8190 vty_out(vty, "{}\n");
8191 else
8192 vty_out(vty, "%% VNI %u does not exist\n", vni);
8193 return;
8194 }
8195 num_neigh = hashcount(zevpn->neigh_table);
8196 if (!num_neigh)
8197 return;
8198
8199 if (use_json)
8200 json = json_object_new_object();
8201
8202 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
8203 wctx.zevpn = zevpn;
8204 wctx.vty = vty;
8205 wctx.addr_width = 15;
8206 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
8207 wctx.r_vtep_ip = vtep_ip;
8208 wctx.json = json;
8209 hash_iterate(zevpn->neigh_table, zevpn_find_neigh_addr_width, &wctx);
8210 hash_iterate(zevpn->neigh_table, zevpn_print_neigh_hash, &wctx);
8211
8212 if (use_json) {
8213 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8214 json, JSON_C_TO_STRING_PRETTY));
8215 json_object_free(json);
8216 }
8217 }
8218
8219 /*
8220 * Display Duplicate detected Neighbors for a VNI
8221 * (VTY command handler).
8222 */
8223 void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
8224 struct zebra_vrf *zvrf,
8225 vni_t vni,
8226 bool use_json)
8227 {
8228 zebra_evpn_t *zevpn;
8229 uint32_t num_neigh;
8230 struct neigh_walk_ctx wctx;
8231 json_object *json = NULL;
8232
8233 if (!is_evpn_enabled())
8234 return;
8235
8236 zevpn = zevpn_lookup(vni);
8237 if (!zevpn) {
8238 vty_out(vty, "%% VNI %u does not exist\n", vni);
8239 return;
8240 }
8241
8242 num_neigh = hashcount(zevpn->neigh_table);
8243 if (!num_neigh)
8244 return;
8245
8246 num_neigh = num_dup_detected_neighs(zevpn);
8247 if (!num_neigh)
8248 return;
8249
8250 if (use_json)
8251 json = json_object_new_object();
8252
8253 /* Since we have IPv6 addresses to deal with which can vary widely in
8254 * size, we try to be a bit more elegant in display by first computing
8255 * the maximum width.
8256 */
8257 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
8258 wctx.zevpn = zevpn;
8259 wctx.vty = vty;
8260 wctx.addr_width = 15;
8261 wctx.json = json;
8262 hash_iterate(zevpn->neigh_table, zevpn_find_neigh_addr_width, &wctx);
8263
8264 if (!use_json) {
8265 vty_out(vty,
8266 "Number of ARPs (local and remote) known for this VNI: %u\n",
8267 num_neigh);
8268 vty_out(vty, "%*s %-6s %-8s %-17s %-30s\n",
8269 -wctx.addr_width, "IP", "Type",
8270 "State", "MAC", "Remote ES/VTEP");
8271 } else
8272 json_object_int_add(json, "numArpNd", num_neigh);
8273
8274 hash_iterate(zevpn->neigh_table, zevpn_print_dad_neigh_hash, &wctx);
8275
8276 if (use_json) {
8277 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8278 json, JSON_C_TO_STRING_PRETTY));
8279 json_object_free(json);
8280 }
8281 }
8282
8283 /*
8284 * Display MACs for a VNI (VTY command handler).
8285 */
8286 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
8287 vni_t vni, bool use_json)
8288 {
8289 zebra_evpn_t *zevpn;
8290 uint32_t num_macs;
8291 struct mac_walk_ctx wctx;
8292 json_object *json = NULL;
8293 json_object *json_mac = NULL;
8294
8295 if (!is_evpn_enabled())
8296 return;
8297 zevpn = zevpn_lookup(vni);
8298 if (!zevpn) {
8299 if (use_json)
8300 vty_out(vty, "{}\n");
8301 else
8302 vty_out(vty, "%% VNI %u does not exist\n", vni);
8303 return;
8304 }
8305 num_macs = num_valid_macs(zevpn);
8306 if (!num_macs)
8307 return;
8308
8309 if (use_json) {
8310 json = json_object_new_object();
8311 json_mac = json_object_new_object();
8312 }
8313
8314 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8315 wctx.zevpn = zevpn;
8316 wctx.vty = vty;
8317 wctx.json = json_mac;
8318
8319 if (!use_json) {
8320 vty_out(vty,
8321 "Number of MACs (local and remote) known for this VNI: %u\n",
8322 num_macs);
8323 vty_out(vty,
8324 "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n");
8325 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC",
8326 "Type", "Flags", "Intf/Remote ES/VTEP",
8327 "VLAN", "Seq #'s");
8328 } else
8329 json_object_int_add(json, "numMacs", num_macs);
8330
8331 hash_iterate(zevpn->mac_table, zevpn_print_mac_hash, &wctx);
8332
8333 if (use_json) {
8334 json_object_object_add(json, "macs", json_mac);
8335 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8336 json, JSON_C_TO_STRING_PRETTY));
8337 json_object_free(json);
8338 }
8339 }
8340
8341 /*
8342 * Display MACs for all VNIs (VTY command handler).
8343 */
8344 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
8345 bool print_dup, bool use_json)
8346 {
8347 struct mac_walk_ctx wctx;
8348 json_object *json = NULL;
8349
8350 if (!is_evpn_enabled()) {
8351 if (use_json)
8352 vty_out(vty, "{}\n");
8353 return;
8354 }
8355 if (use_json)
8356 json = json_object_new_object();
8357
8358 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8359 wctx.vty = vty;
8360 wctx.json = json;
8361 wctx.print_dup = print_dup;
8362 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
8363
8364 if (use_json) {
8365 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8366 json, JSON_C_TO_STRING_PRETTY));
8367 json_object_free(json);
8368 }
8369 }
8370
8371 /*
8372 * Display MACs in detail for all VNIs (VTY command handler).
8373 */
8374 void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
8375 struct zebra_vrf *zvrf,
8376 bool print_dup, bool use_json)
8377 {
8378 struct mac_walk_ctx wctx;
8379 json_object *json = NULL;
8380
8381 if (!is_evpn_enabled()) {
8382 if (use_json)
8383 vty_out(vty, "{}\n");
8384 return;
8385 }
8386 if (use_json)
8387 json = json_object_new_object();
8388
8389 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8390 wctx.vty = vty;
8391 wctx.json = json;
8392 wctx.print_dup = print_dup;
8393 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn_detail,
8394 &wctx);
8395
8396 if (use_json) {
8397 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8398 json, JSON_C_TO_STRING_PRETTY));
8399 json_object_free(json);
8400 }
8401 }
8402
8403 /*
8404 * Display MACs for all VNIs (VTY command handler).
8405 */
8406 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
8407 struct zebra_vrf *zvrf,
8408 struct in_addr vtep_ip, bool use_json)
8409 {
8410 struct mac_walk_ctx wctx;
8411 json_object *json = NULL;
8412
8413 if (!is_evpn_enabled())
8414 return;
8415
8416 if (use_json)
8417 json = json_object_new_object();
8418
8419 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8420 wctx.vty = vty;
8421 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
8422 wctx.r_vtep_ip = vtep_ip;
8423 wctx.json = json;
8424 hash_iterate(zvrf->evpn_table, zevpn_print_mac_hash_all_evpn, &wctx);
8425
8426 if (use_json) {
8427 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8428 json, JSON_C_TO_STRING_PRETTY));
8429 json_object_free(json);
8430 }
8431 }
8432
8433 /*
8434 * Display specific MAC for a VNI, if present (VTY command handler).
8435 */
8436 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
8437 vni_t vni, struct ethaddr *macaddr,
8438 bool use_json)
8439 {
8440 zebra_evpn_t *zevpn;
8441 zebra_mac_t *mac;
8442 json_object *json = NULL;
8443
8444 if (!is_evpn_enabled())
8445 return;
8446
8447 zevpn = zevpn_lookup(vni);
8448 if (!zevpn) {
8449 if (use_json)
8450 vty_out(vty, "{}\n");
8451 else
8452 vty_out(vty, "%% VNI %u does not exist\n", vni);
8453 return;
8454 }
8455 mac = zevpn_mac_lookup(zevpn, macaddr);
8456 if (!mac) {
8457 if (use_json)
8458 vty_out(vty, "{}\n");
8459 else
8460 vty_out(vty,
8461 "%% Requested MAC does not exist in VNI %u\n",
8462 vni);
8463 return;
8464 }
8465
8466 if (use_json)
8467 json = json_object_new_object();
8468
8469 zevpn_print_mac(mac, vty, json);
8470 if (use_json) {
8471 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8472 json, JSON_C_TO_STRING_PRETTY));
8473 json_object_free(json);
8474 }
8475 }
8476
8477 /* Print Duplicate MACs per VNI */
8478 void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
8479 struct zebra_vrf *zvrf,
8480 vni_t vni, bool use_json)
8481 {
8482 zebra_evpn_t *zevpn;
8483 struct mac_walk_ctx wctx;
8484 uint32_t num_macs;
8485 json_object *json = NULL;
8486 json_object *json_mac = NULL;
8487
8488 if (!is_evpn_enabled())
8489 return;
8490
8491 zevpn = zevpn_lookup(vni);
8492 if (!zevpn) {
8493 vty_out(vty, "%% VNI %u does not exist\n", vni);
8494 return;
8495 }
8496
8497 num_macs = num_valid_macs(zevpn);
8498 if (!num_macs)
8499 return;
8500
8501 num_macs = num_dup_detected_macs(zevpn);
8502 if (!num_macs)
8503 return;
8504
8505 if (use_json) {
8506 json = json_object_new_object();
8507 json_mac = json_object_new_object();
8508 }
8509
8510 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8511 wctx.zevpn = zevpn;
8512 wctx.vty = vty;
8513 wctx.json = json_mac;
8514
8515 if (!use_json) {
8516 vty_out(vty,
8517 "Number of MACs (local and remote) known for this VNI: %u\n",
8518 num_macs);
8519 vty_out(vty, "%-17s %-6s %-5s %-30s %-5s\n", "MAC", "Type",
8520 "Flags", "Intf/Remote ES/VTEP", "VLAN");
8521 } else
8522 json_object_int_add(json, "numMacs", num_macs);
8523
8524 hash_iterate(zevpn->mac_table, zevpn_print_dad_mac_hash, &wctx);
8525
8526 if (use_json) {
8527 json_object_object_add(json, "macs", json_mac);
8528 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8529 json, JSON_C_TO_STRING_PRETTY));
8530 json_object_free(json);
8531 }
8532
8533 }
8534
8535 int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
8536 struct ethaddr *macaddr)
8537 {
8538 zebra_evpn_t *zevpn;
8539 zebra_mac_t *mac;
8540 struct listnode *node = NULL;
8541 zebra_neigh_t *nbr = NULL;
8542
8543 if (!is_evpn_enabled())
8544 return 0;
8545
8546 zevpn = zevpn_lookup(vni);
8547 if (!zevpn) {
8548 zlog_warn("VNI %u does not exist\n", vni);
8549 return -1;
8550 }
8551
8552 mac = zevpn_mac_lookup(zevpn, macaddr);
8553 if (!mac) {
8554 zlog_warn("Requested MAC does not exist in VNI %u\n", vni);
8555 return -1;
8556 }
8557
8558 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
8559 zlog_warn("Requested MAC is not duplicate detected\n");
8560 return -1;
8561 }
8562
8563 /* Remove all IPs as duplicate associcated with this MAC */
8564 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
8565 /* For local neigh mark inactive so MACIP update is generated
8566 * to BGP. This is a scenario where MAC update received
8567 * and detected as duplicate which marked neigh as duplicate.
8568 * Later local neigh update did not get a chance to relay
8569 * to BGP. Similarly remote macip update, neigh needs to be
8570 * installed locally.
8571 */
8572 if (zvrf->dad_freeze &&
8573 CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
8574 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
8575 ZEBRA_NEIGH_SET_INACTIVE(nbr);
8576 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
8577 zevpn_rem_neigh_install(zevpn, nbr,
8578 false /*was_static*/);
8579 }
8580
8581 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8582 nbr->dad_count = 0;
8583 nbr->detect_start_time.tv_sec = 0;
8584 nbr->dad_dup_detect_time = 0;
8585 }
8586
8587 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
8588 mac->dad_count = 0;
8589 mac->detect_start_time.tv_sec = 0;
8590 mac->detect_start_time.tv_usec = 0;
8591 mac->dad_dup_detect_time = 0;
8592 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
8593
8594 /* warn-only action return */
8595 if (!zvrf->dad_freeze)
8596 return 0;
8597
8598 /* Local: Notify Peer VTEPs, Remote: Install the entry */
8599 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
8600 /* Inform to BGP */
8601 if (zevpn_mac_send_add_to_client(zevpn->vni,
8602 &mac->macaddr,
8603 mac->flags,
8604 mac->loc_seq, mac->es))
8605 return 0;
8606
8607 /* Process all neighbors associated with this MAC. */
8608 zevpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
8609 0 /*es_change*/);
8610
8611 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
8612 zevpn_process_neigh_on_remote_mac_add(zevpn, mac);
8613
8614 /* Install the entry. */
8615 zevpn_rem_mac_install(zevpn, mac, false /* was_static */);
8616 }
8617
8618 return 0;
8619 }
8620
8621 int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
8622 struct ipaddr *ip)
8623 {
8624 zebra_evpn_t *zevpn;
8625 zebra_neigh_t *nbr;
8626 zebra_mac_t *mac;
8627 char buf[INET6_ADDRSTRLEN];
8628 char buf2[ETHER_ADDR_STRLEN];
8629
8630 if (!is_evpn_enabled())
8631 return 0;
8632
8633 zevpn = zevpn_lookup(vni);
8634 if (!zevpn) {
8635 zlog_debug("VNI %u does not exist\n", vni);
8636 return -1;
8637 }
8638
8639 nbr = zevpn_neigh_lookup(zevpn, ip);
8640 if (!nbr) {
8641 zlog_warn("Requested host IP does not exist in VNI %u\n", vni);
8642 return -1;
8643 }
8644
8645 ipaddr2str(&nbr->ip, buf, sizeof(buf));
8646
8647 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
8648 zlog_warn("Requested host IP %s is not duplicate detected\n",
8649 buf);
8650 return -1;
8651 }
8652
8653 mac = zevpn_mac_lookup(zevpn, &nbr->emac);
8654
8655 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
8656 zlog_warn(
8657 "Requested IP's associated MAC %s is still in duplicate state\n",
8658 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
8659 return -1;
8660 }
8661
8662 if (IS_ZEBRA_DEBUG_VXLAN)
8663 zlog_debug("%s: clear neigh %s in dup state, flags 0x%x seq %u",
8664 __func__, buf, nbr->flags, nbr->loc_seq);
8665
8666 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8667 nbr->dad_count = 0;
8668 nbr->detect_start_time.tv_sec = 0;
8669 nbr->detect_start_time.tv_usec = 0;
8670 nbr->dad_dup_detect_time = 0;
8671 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
8672
8673 if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
8674 zevpn_neigh_send_add_to_client(zevpn->vni, ip,
8675 &nbr->emac, nbr->mac,
8676 nbr->flags, nbr->loc_seq);
8677 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
8678 zevpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
8679 }
8680
8681 return 0;
8682 }
8683
8684 static void zevpn_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt)
8685 {
8686 struct mac_walk_ctx *wctx = ctxt;
8687 zebra_mac_t *mac;
8688 zebra_evpn_t *zevpn;
8689 struct listnode *node = NULL;
8690 zebra_neigh_t *nbr = NULL;
8691
8692 mac = (zebra_mac_t *)bucket->data;
8693 if (!mac)
8694 return;
8695
8696 zevpn = wctx->zevpn;
8697
8698 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
8699 return;
8700
8701 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
8702 mac->dad_count = 0;
8703 mac->detect_start_time.tv_sec = 0;
8704 mac->detect_start_time.tv_usec = 0;
8705 mac->dad_dup_detect_time = 0;
8706 THREAD_OFF(mac->dad_mac_auto_recovery_timer);
8707
8708 /* Remove all IPs as duplicate associcated with this MAC */
8709 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
8710 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)
8711 && nbr->dad_count)
8712 ZEBRA_NEIGH_SET_INACTIVE(nbr);
8713
8714 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8715 nbr->dad_count = 0;
8716 nbr->detect_start_time.tv_sec = 0;
8717 nbr->dad_dup_detect_time = 0;
8718 }
8719
8720 /* Local: Notify Peer VTEPs, Remote: Install the entry */
8721 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
8722 /* Inform to BGP */
8723 if (zevpn_mac_send_add_to_client(zevpn->vni,
8724 &mac->macaddr,
8725 mac->flags, mac->loc_seq, mac->es))
8726 return;
8727
8728 /* Process all neighbors associated with this MAC. */
8729 zevpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
8730 0 /*es_change*/);
8731
8732 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
8733 zevpn_process_neigh_on_remote_mac_add(zevpn, mac);
8734
8735 /* Install the entry. */
8736 zevpn_rem_mac_install(zevpn, mac, false /* was_static */);
8737 }
8738 }
8739
8740 static void zevpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt)
8741 {
8742 struct neigh_walk_ctx *wctx = ctxt;
8743 zebra_neigh_t *nbr;
8744 zebra_evpn_t *zevpn;
8745 char buf[INET6_ADDRSTRLEN];
8746
8747 nbr = (zebra_neigh_t *)bucket->data;
8748 if (!nbr)
8749 return;
8750
8751 zevpn = wctx->zevpn;
8752
8753 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
8754 return;
8755
8756 if (IS_ZEBRA_DEBUG_VXLAN) {
8757 ipaddr2str(&nbr->ip, buf, sizeof(buf));
8758 zlog_debug("%s: clear neigh %s dup state, flags 0x%x seq %u",
8759 __func__, buf, nbr->flags, nbr->loc_seq);
8760 }
8761
8762 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
8763 nbr->dad_count = 0;
8764 nbr->detect_start_time.tv_sec = 0;
8765 nbr->detect_start_time.tv_usec = 0;
8766 nbr->dad_dup_detect_time = 0;
8767 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
8768
8769 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
8770 zevpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
8771 &nbr->emac, nbr->mac,
8772 nbr->flags, nbr->loc_seq);
8773 } else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
8774 zevpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
8775 }
8776 }
8777
8778 static void zevpn_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket,
8779 void **args)
8780 {
8781 zebra_evpn_t *zevpn;
8782 struct zebra_vrf *zvrf;
8783 struct mac_walk_ctx m_wctx;
8784 struct neigh_walk_ctx n_wctx;
8785
8786 zevpn = (zebra_evpn_t *)bucket->data;
8787 if (!zevpn)
8788 return;
8789
8790 zvrf = (struct zebra_vrf *)args[0];
8791
8792 if (hashcount(zevpn->neigh_table)) {
8793 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
8794 n_wctx.zevpn = zevpn;
8795 n_wctx.zvrf = zvrf;
8796 hash_iterate(zevpn->neigh_table, zevpn_clear_dup_neigh_hash,
8797 &n_wctx);
8798 }
8799
8800 if (num_valid_macs(zevpn)) {
8801 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
8802 m_wctx.zevpn = zevpn;
8803 m_wctx.zvrf = zvrf;
8804 hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
8805 }
8806
8807 }
8808
8809 int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf)
8810 {
8811 void *args[1];
8812
8813 if (!is_evpn_enabled())
8814 return 0;
8815
8816 args[0] = zvrf;
8817
8818 hash_iterate(zvrf->evpn_table,
8819 (void (*)(struct hash_bucket *, void *))
8820 zevpn_clear_dup_detect_hash_vni_all, args);
8821
8822 return 0;
8823 }
8824
8825 int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni)
8826 {
8827 zebra_evpn_t *zevpn;
8828 struct mac_walk_ctx m_wctx;
8829 struct neigh_walk_ctx n_wctx;
8830
8831 if (!is_evpn_enabled())
8832 return 0;
8833
8834 zevpn = zevpn_lookup(vni);
8835 if (!zevpn) {
8836 zlog_warn("VNI %u does not exist\n", vni);
8837 return CMD_WARNING;
8838 }
8839
8840 if (hashcount(zevpn->neigh_table)) {
8841 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
8842 n_wctx.zevpn = zevpn;
8843 n_wctx.zvrf = zvrf;
8844 hash_iterate(zevpn->neigh_table, zevpn_clear_dup_neigh_hash,
8845 &n_wctx);
8846 }
8847
8848 if (num_valid_macs(zevpn)) {
8849 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
8850 m_wctx.zevpn = zevpn;
8851 m_wctx.zvrf = zvrf;
8852 hash_iterate(zevpn->mac_table, zevpn_clear_dup_mac_hash, &m_wctx);
8853 }
8854
8855 return 0;
8856 }
8857
8858 /*
8859 * Display MACs for a VNI from specific VTEP (VTY command handler).
8860 */
8861 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
8862 vni_t vni, struct in_addr vtep_ip,
8863 bool use_json)
8864 {
8865 zebra_evpn_t *zevpn;
8866 uint32_t num_macs;
8867 struct mac_walk_ctx wctx;
8868 json_object *json = NULL;
8869 json_object *json_mac = NULL;
8870
8871 if (!is_evpn_enabled())
8872 return;
8873 zevpn = zevpn_lookup(vni);
8874 if (!zevpn) {
8875 if (use_json)
8876 vty_out(vty, "{}\n");
8877 else
8878 vty_out(vty, "%% VNI %u does not exist\n", vni);
8879 return;
8880 }
8881 num_macs = num_valid_macs(zevpn);
8882 if (!num_macs)
8883 return;
8884
8885 if (use_json) {
8886 json = json_object_new_object();
8887 json_mac = json_object_new_object();
8888 }
8889
8890 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
8891 wctx.zevpn = zevpn;
8892 wctx.vty = vty;
8893 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
8894 wctx.r_vtep_ip = vtep_ip;
8895 wctx.json = json_mac;
8896 hash_iterate(zevpn->mac_table, zevpn_print_mac_hash, &wctx);
8897
8898 if (use_json) {
8899 json_object_int_add(json, "numMacs", wctx.count);
8900 if (wctx.count)
8901 json_object_object_add(json, "macs", json_mac);
8902 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8903 json, JSON_C_TO_STRING_PRETTY));
8904 json_object_free(json);
8905 }
8906 }
8907
8908
8909 /*
8910 * Display VNI information (VTY command handler).
8911 *
8912 * use_json flag indicates that output should be in JSON format.
8913 * json_array is non NULL when JSON output needs to be aggregated (by the
8914 * caller) and then printed, otherwise, JSON evpn vni info is printed
8915 * right away.
8916 */
8917 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
8918 bool use_json, json_object *json_array)
8919 {
8920 json_object *json = NULL;
8921 void *args[2];
8922 zebra_l3vni_t *zl3vni = NULL;
8923 zebra_evpn_t *zevpn = NULL;
8924
8925 if (!is_evpn_enabled())
8926 return;
8927
8928 if (use_json)
8929 json = json_object_new_object();
8930
8931 args[0] = vty;
8932 args[1] = json;
8933
8934 zl3vni = zl3vni_lookup(vni);
8935 if (zl3vni) {
8936 zl3vni_print(zl3vni, (void *)args);
8937 } else {
8938 zevpn = zevpn_lookup(vni);
8939 if (zevpn)
8940 zevpn_print(zevpn, (void *)args);
8941 else if (!json)
8942 vty_out(vty, "%% VNI %u does not exist\n", vni);
8943 }
8944
8945 if (use_json) {
8946 /*
8947 * Each "json" object contains info about 1 VNI.
8948 * When "json_array" is non-null, we aggreggate the json output
8949 * into json_array and print it as a JSON array.
8950 */
8951 if (json_array)
8952 json_object_array_add(json_array, json);
8953 else {
8954 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8955 json, JSON_C_TO_STRING_PRETTY));
8956 json_object_free(json);
8957 }
8958 }
8959 }
8960
8961 /* Display all global details for EVPN */
8962 void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
8963 {
8964 int num_l2vnis = 0;
8965 int num_l3vnis = 0;
8966 int num_vnis = 0;
8967 json_object *json = NULL;
8968 struct zebra_vrf *zvrf = NULL;
8969
8970 if (!is_evpn_enabled())
8971 return;
8972
8973 zvrf = zebra_vrf_get_evpn();
8974 if (!zvrf)
8975 return;
8976
8977 num_l3vnis = hashcount(zrouter.l3vni_table);
8978 num_l2vnis = hashcount(zvrf->evpn_table);
8979 num_vnis = num_l2vnis + num_l3vnis;
8980
8981 if (uj) {
8982 json = json_object_new_object();
8983 json_object_string_add(json, "advertiseGatewayMacip",
8984 zvrf->advertise_gw_macip ? "Yes" : "No");
8985 json_object_int_add(json, "numVnis", num_vnis);
8986 json_object_int_add(json, "numL2Vnis", num_l2vnis);
8987 json_object_int_add(json, "numL3Vnis", num_l3vnis);
8988 if (zvrf->dup_addr_detect)
8989 json_object_boolean_true_add(json,
8990 "isDuplicateAddrDetection");
8991 else
8992 json_object_boolean_false_add(json,
8993 "isDuplicateAddrDetection");
8994 json_object_int_add(json, "maxMoves", zvrf->dad_max_moves);
8995 json_object_int_add(json, "detectionTime", zvrf->dad_time);
8996 json_object_int_add(json, "detectionFreezeTime",
8997 zvrf->dad_freeze_time);
8998
8999 } else {
9000 vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
9001 vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
9002 vty_out(vty, "Advertise gateway mac-ip: %s\n",
9003 zvrf->advertise_gw_macip ? "Yes" : "No");
9004 vty_out(vty, "Advertise svi mac-ip: %s\n",
9005 zvrf->advertise_svi_macip ? "Yes" : "No");
9006 vty_out(vty, "Duplicate address detection: %s\n",
9007 zvrf->dup_addr_detect ? "Enable" : "Disable");
9008 vty_out(vty, " Detection max-moves %u, time %d\n",
9009 zvrf->dad_max_moves, zvrf->dad_time);
9010 if (zvrf->dad_freeze) {
9011 if (zvrf->dad_freeze_time)
9012 vty_out(vty, " Detection freeze %u\n",
9013 zvrf->dad_freeze_time);
9014 else
9015 vty_out(vty, " Detection freeze %s\n",
9016 "permanent");
9017 }
9018 }
9019
9020 if (uj) {
9021 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9022 json, JSON_C_TO_STRING_PRETTY));
9023 json_object_free(json);
9024 }
9025 }
9026
9027 /*
9028 * Display VNI hash table (VTY command handler).
9029 */
9030 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
9031 bool use_json)
9032 {
9033 json_object *json = NULL;
9034 void *args[2];
9035
9036 if (!is_evpn_enabled())
9037 return;
9038
9039 if (use_json)
9040 json = json_object_new_object();
9041 else
9042 vty_out(vty, "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n", "VNI",
9043 "Type", "VxLAN IF", "# MACs", "# ARPs",
9044 "# Remote VTEPs", "Tenant VRF");
9045
9046 args[0] = vty;
9047 args[1] = json;
9048
9049 /* Display all L2-VNIs */
9050 hash_iterate(zvrf->evpn_table,
9051 (void (*)(struct hash_bucket *, void *))zevpn_print_hash,
9052 args);
9053
9054 /* Display all L3-VNIs */
9055 hash_iterate(zrouter.l3vni_table,
9056 (void (*)(struct hash_bucket *, void *))zl3vni_print_hash,
9057 args);
9058
9059 if (use_json) {
9060 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9061 json, JSON_C_TO_STRING_PRETTY));
9062 json_object_free(json);
9063 }
9064 }
9065
9066 void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS)
9067 {
9068 struct stream *s;
9069 int time = 0;
9070 uint32_t max_moves = 0;
9071 uint32_t freeze_time = 0;
9072 bool dup_addr_detect = false;
9073 bool freeze = false;
9074
9075 s = msg;
9076 STREAM_GETL(s, dup_addr_detect);
9077 STREAM_GETL(s, time);
9078 STREAM_GETL(s, max_moves);
9079 STREAM_GETL(s, freeze);
9080 STREAM_GETL(s, freeze_time);
9081
9082 /* DAD previous state was enabled, and new state is disable,
9083 * clear all duplicate detected addresses.
9084 */
9085 if (zvrf->dup_addr_detect && !dup_addr_detect)
9086 zebra_vxlan_clear_dup_detect_vni_all(zvrf);
9087
9088 zvrf->dup_addr_detect = dup_addr_detect;
9089 zvrf->dad_time = time;
9090 zvrf->dad_max_moves = max_moves;
9091 zvrf->dad_freeze = freeze;
9092 zvrf->dad_freeze_time = freeze_time;
9093
9094 if (IS_ZEBRA_DEBUG_VXLAN)
9095 zlog_debug(
9096 "VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
9097 vrf_id_to_name(zvrf->vrf->vrf_id),
9098 zvrf->dup_addr_detect ? "enable" : "disable",
9099 zvrf->dad_max_moves,
9100 zvrf->dad_time,
9101 zvrf->dad_freeze ? "enable" : "disable",
9102 zvrf->dad_freeze_time);
9103
9104 stream_failure:
9105 return;
9106 }
9107
9108 /*
9109 * Display VNI hash table in detail(VTY command handler).
9110 */
9111 void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
9112 bool use_json)
9113 {
9114 json_object *json_array = NULL;
9115 struct zebra_ns *zns = NULL;
9116 struct zevpn_show zes;
9117
9118 if (!is_evpn_enabled())
9119 return;
9120
9121 zns = zebra_ns_lookup(NS_DEFAULT);
9122 if (!zns)
9123 return;
9124
9125 if (use_json)
9126 json_array = json_object_new_array();
9127
9128 zes.vty = vty;
9129 zes.json = json_array;
9130 zes.zvrf = zvrf;
9131 zes.use_json = use_json;
9132
9133 /* Display all L2-VNIs */
9134 hash_iterate(
9135 zvrf->evpn_table,
9136 (void (*)(struct hash_bucket *, void *))zevpn_print_hash_detail,
9137 &zes);
9138
9139 /* Display all L3-VNIs */
9140 hash_iterate(zrouter.l3vni_table,
9141 (void (*)(struct hash_bucket *,
9142 void *))zl3vni_print_hash_detail,
9143 &zes);
9144
9145 if (use_json) {
9146 vty_out(vty, "%s\n",
9147 json_object_to_json_string_ext(
9148 json_array, JSON_C_TO_STRING_PRETTY));
9149 json_object_free(json_array);
9150 }
9151 }
9152
9153 /*
9154 * Handle neighbor delete notification from the kernel (on a VLAN device
9155 * / L3 interface). This may result in either the neighbor getting deleted
9156 * from our database or being re-added to the kernel (if it is a valid
9157 * remote neighbor).
9158 */
9159 int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
9160 struct interface *link_if,
9161 struct ipaddr *ip)
9162 {
9163 char buf[INET6_ADDRSTRLEN];
9164 char buf2[ETHER_ADDR_STRLEN];
9165 zebra_neigh_t *n = NULL;
9166 zebra_evpn_t *zevpn = NULL;
9167 zebra_mac_t *zmac = NULL;
9168 zebra_l3vni_t *zl3vni = NULL;
9169 struct zebra_vrf *zvrf;
9170 bool old_bgp_ready;
9171 bool new_bgp_ready;
9172
9173 /* check if this is a remote neigh entry corresponding to remote
9174 * next-hop
9175 */
9176 zl3vni = zl3vni_from_svi(ifp, link_if);
9177 if (zl3vni)
9178 return zl3vni_local_nh_del(zl3vni, ip);
9179
9180 /* We are only interested in neighbors on an SVI that resides on top
9181 * of a VxLAN bridge.
9182 */
9183 zevpn = zevpn_from_svi(ifp, link_if);
9184 if (!zevpn) {
9185 if (IS_ZEBRA_DEBUG_VXLAN)
9186 zlog_debug(
9187 "%s: Del neighbor %s EVPN is not present for interface %s",
9188 __func__, ipaddr2str(ip, buf, sizeof(buf)),
9189 ifp->name);
9190 return 0;
9191 }
9192
9193 if (!zevpn->vxlan_if) {
9194 zlog_debug(
9195 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
9196 zevpn->vni, zevpn);
9197 return -1;
9198 }
9199
9200 if (IS_ZEBRA_DEBUG_VXLAN)
9201 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
9202 ipaddr2str(ip, buf, sizeof(buf)), ifp->name,
9203 ifp->ifindex, zevpn->vni);
9204
9205 /* If entry doesn't exist, nothing to do. */
9206 n = zevpn_neigh_lookup(zevpn, ip);
9207 if (!n)
9208 return 0;
9209
9210 zmac = zevpn_mac_lookup(zevpn, &n->emac);
9211 if (!zmac) {
9212 if (IS_ZEBRA_DEBUG_VXLAN)
9213 zlog_debug(
9214 "Trying to del a neigh %s without a mac %s on VNI %u",
9215 ipaddr2str(ip, buf, sizeof(buf)),
9216 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
9217 zevpn->vni);
9218
9219 return 0;
9220 }
9221
9222 /* If it is a remote entry, the kernel has aged this out or someone has
9223 * deleted it, it needs to be re-installed as Quagga is the owner.
9224 */
9225 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
9226 zevpn_rem_neigh_install(zevpn, n, false /*was_static*/);
9227 return 0;
9228 }
9229
9230 /* if this is a sync entry it cannot be dropped re-install it in
9231 * the dataplane
9232 */
9233 old_bgp_ready =
9234 zebra_vxlan_neigh_is_ready_for_bgp(n);
9235 if (zebra_vxlan_neigh_is_static(n)) {
9236 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
9237 zlog_debug("re-add sync neigh vni %u ip %s mac %s 0x%x",
9238 n->zevpn->vni,
9239 ipaddr2str(&n->ip, buf, sizeof(buf)),
9240 prefix_mac2str(&n->emac, buf2,
9241 sizeof(buf2)),
9242 n->flags);
9243
9244 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
9245 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
9246 /* inform-bgp about change in local-activity if any */
9247 new_bgp_ready =
9248 zebra_vxlan_neigh_is_ready_for_bgp(n);
9249 zebra_vxlan_neigh_send_add_del_to_client(n,
9250 old_bgp_ready, new_bgp_ready);
9251
9252 /* re-install the entry in the kernel */
9253 zebra_vxlan_sync_neigh_dp_install(n, false /* set_inactive */,
9254 false /* force_clear_static */, __func__);
9255
9256 return 0;
9257 }
9258
9259 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
9260 if (!zvrf) {
9261 zlog_debug("%s: VNI %u vrf lookup failed.", __func__,
9262 zevpn->vni);
9263 return -1;
9264 }
9265
9266 /* In case of feeze action, if local neigh is in duplicate state,
9267 * Mark the Neigh as inactive before sending delete request to BGPd,
9268 * If BGPd has remote entry, it will re-install
9269 */
9270 if (zvrf->dad_freeze &&
9271 CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
9272 ZEBRA_NEIGH_SET_INACTIVE(n);
9273
9274 /* Remove neighbor from BGP. */
9275 zevpn_neigh_send_del_to_client(zevpn->vni, &n->ip,
9276 &n->emac, n->flags, n->state,
9277 false /* force */);
9278
9279 /* Delete this neighbor entry. */
9280 zevpn_neigh_del(zevpn, n);
9281
9282 /* see if the AUTO mac needs to be deleted */
9283 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
9284 && !listcount(zmac->neigh_list))
9285 zevpn_mac_del(zevpn, zmac);
9286
9287 return 0;
9288 }
9289
9290 /*
9291 * Handle neighbor add or update notification from the kernel (on a VLAN
9292 * device / L3 interface). This is typically for a local neighbor but can
9293 * also be for a remote neighbor (e.g., ageout notification). It could
9294 * also be a "move" scenario.
9295 */
9296 int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
9297 struct interface *link_if,
9298 struct ipaddr *ip,
9299 struct ethaddr *macaddr,
9300 uint16_t state,
9301 bool is_ext,
9302 bool is_router,
9303 bool local_inactive, bool dp_static)
9304 {
9305 char buf[ETHER_ADDR_STRLEN];
9306 char buf2[INET6_ADDRSTRLEN];
9307 zebra_evpn_t *zevpn = NULL;
9308 zebra_l3vni_t *zl3vni = NULL;
9309
9310 /* check if this is a remote neigh entry corresponding to remote
9311 * next-hop
9312 */
9313 zl3vni = zl3vni_from_svi(ifp, link_if);
9314 if (zl3vni)
9315 return zl3vni_local_nh_add_update(zl3vni, ip, state);
9316
9317 /* We are only interested in neighbors on an SVI that resides on top
9318 * of a VxLAN bridge.
9319 */
9320 zevpn = zevpn_from_svi(ifp, link_if);
9321 if (!zevpn)
9322 return 0;
9323
9324 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
9325 zlog_debug(
9326 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s%s%s-> L2-VNI %u",
9327 ipaddr2str(ip, buf2, sizeof(buf2)),
9328 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
9329 ifp->ifindex, state, is_ext ? "ext-learned " : "",
9330 is_router ? "router " : "",
9331 local_inactive ? "local_inactive " : "",
9332 zevpn->vni);
9333
9334 /* Is this about a local neighbor or a remote one? */
9335 if (!is_ext)
9336 return zevpn_local_neigh_update(zevpn, ifp, ip, macaddr,
9337 is_router, local_inactive, dp_static);
9338
9339 return zevpn_remote_neigh_update(zevpn, ifp, ip, macaddr, state);
9340 }
9341
9342 static int32_t
9343 zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
9344 struct ethaddr *macaddr, uint16_t *ipa_len,
9345 struct ipaddr *ip, struct in_addr *vtep_ip,
9346 uint8_t *flags, uint32_t *seq, esi_t *esi)
9347 {
9348 uint16_t l = 0;
9349
9350 /*
9351 * Obtain each remote MACIP and process.
9352 * Message contains VNI, followed by MAC followed by IP (if any)
9353 * followed by remote VTEP IP.
9354 */
9355 memset(ip, 0, sizeof(*ip));
9356 STREAM_GETL(s, *vni);
9357 STREAM_GET(macaddr->octet, s, ETH_ALEN);
9358 STREAM_GETL(s, *ipa_len);
9359
9360 if (*ipa_len) {
9361 if (*ipa_len == IPV4_MAX_BYTELEN)
9362 ip->ipa_type = IPADDR_V4;
9363 else if (*ipa_len == IPV6_MAX_BYTELEN)
9364 ip->ipa_type = IPADDR_V6;
9365 else {
9366 if (IS_ZEBRA_DEBUG_VXLAN)
9367 zlog_debug(
9368 "ipa_len *must* be %d or %d bytes in length not %d",
9369 IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
9370 *ipa_len);
9371 goto stream_failure;
9372 }
9373
9374 STREAM_GET(&ip->ip.addr, s, *ipa_len);
9375 }
9376 l += 4 + ETH_ALEN + 4 + *ipa_len;
9377 STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
9378 l += IPV4_MAX_BYTELEN;
9379
9380 if (add) {
9381 STREAM_GETC(s, *flags);
9382 STREAM_GETL(s, *seq);
9383 l += 5;
9384 STREAM_GET(esi, s, sizeof(esi_t));
9385 l += sizeof(esi_t);
9386 }
9387
9388 return l;
9389
9390 stream_failure:
9391 return -1;
9392 }
9393
9394 /*
9395 * Handle message from client to delete a remote MACIP for a VNI.
9396 */
9397 void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
9398 {
9399 struct stream *s;
9400 vni_t vni;
9401 struct ethaddr macaddr;
9402 struct ipaddr ip;
9403 struct in_addr vtep_ip;
9404 uint16_t l = 0, ipa_len;
9405 char buf[ETHER_ADDR_STRLEN];
9406 char buf1[INET6_ADDRSTRLEN];
9407
9408 memset(&macaddr, 0, sizeof(struct ethaddr));
9409 memset(&ip, 0, sizeof(struct ipaddr));
9410 memset(&vtep_ip, 0, sizeof(struct in_addr));
9411
9412 s = msg;
9413
9414 while (l < hdr->length) {
9415 int res_length = zebra_vxlan_remote_macip_helper(
9416 false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
9417 NULL, NULL);
9418
9419 if (res_length == -1)
9420 goto stream_failure;
9421
9422 l += res_length;
9423 if (IS_ZEBRA_DEBUG_VXLAN)
9424 zlog_debug(
9425 "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
9426 vni,
9427 prefix_mac2str(&macaddr, buf, sizeof(buf)),
9428 ipa_len ? " IP " : "",
9429 ipa_len ?
9430 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
9431 inet_ntoa(vtep_ip),
9432 zebra_route_string(client->proto));
9433
9434 process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
9435 }
9436
9437 stream_failure:
9438 return;
9439 }
9440
9441 /*
9442 * Handle message from client to add a remote MACIP for a VNI. This
9443 * could be just the add of a MAC address or the add of a neighbor
9444 * (IP+MAC).
9445 */
9446 void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
9447 {
9448 struct stream *s;
9449 vni_t vni;
9450 struct ethaddr macaddr;
9451 struct ipaddr ip;
9452 struct in_addr vtep_ip;
9453 uint16_t l = 0, ipa_len;
9454 uint8_t flags = 0;
9455 uint32_t seq;
9456 char buf[ETHER_ADDR_STRLEN];
9457 char buf1[INET6_ADDRSTRLEN];
9458 esi_t esi;
9459 char esi_buf[ESI_STR_LEN];
9460
9461 memset(&macaddr, 0, sizeof(struct ethaddr));
9462 memset(&ip, 0, sizeof(struct ipaddr));
9463 memset(&vtep_ip, 0, sizeof(struct in_addr));
9464
9465 if (!EVPN_ENABLED(zvrf)) {
9466 zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
9467 return;
9468 }
9469
9470 s = msg;
9471
9472 while (l < hdr->length) {
9473 int res_length = zebra_vxlan_remote_macip_helper(
9474 true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
9475 &flags, &seq, &esi);
9476
9477 if (res_length == -1)
9478 goto stream_failure;
9479
9480 l += res_length;
9481 if (IS_ZEBRA_DEBUG_VXLAN) {
9482 if (memcmp(&esi, zero_esi, sizeof(esi_t)))
9483 esi_to_str(&esi, esi_buf, sizeof(esi_buf));
9484 else
9485 strlcpy(esi_buf, "-", ESI_STR_LEN);
9486 zlog_debug(
9487 "Recv %sMACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s ESI %s from %s",
9488 (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ?
9489 "sync-" : "",
9490 vni,
9491 prefix_mac2str(&macaddr, buf, sizeof(buf)),
9492 ipa_len ? " IP " : "",
9493 ipa_len ?
9494 ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
9495 flags, seq, inet_ntoa(vtep_ip), esi_buf,
9496 zebra_route_string(client->proto));
9497 }
9498
9499 process_remote_macip_add(vni, &macaddr, ipa_len, &ip,
9500 flags, seq, vtep_ip, &esi);
9501 }
9502
9503 stream_failure:
9504 return;
9505 }
9506
9507 /*
9508 * Handle remote vtep delete by kernel; re-add the vtep if we have it
9509 */
9510 int zebra_vxlan_check_readd_vtep(struct interface *ifp,
9511 struct in_addr vtep_ip)
9512 {
9513 struct zebra_if *zif;
9514 struct zebra_vrf *zvrf = NULL;
9515 struct zebra_l2info_vxlan *vxl;
9516 vni_t vni;
9517 zebra_evpn_t *zevpn = NULL;
9518 zebra_vtep_t *zvtep = NULL;
9519
9520 zif = ifp->info;
9521 assert(zif);
9522 vxl = &zif->l2info.vxl;
9523 vni = vxl->vni;
9524
9525 /* If EVPN is not enabled, nothing to do. */
9526 if (!is_evpn_enabled())
9527 return 0;
9528
9529 /* Locate VRF corresponding to interface. */
9530 zvrf = vrf_info_lookup(ifp->vrf_id);
9531 if (!zvrf)
9532 return -1;
9533
9534 /* Locate hash entry; it is expected to exist. */
9535 zevpn = zevpn_lookup(vni);
9536 if (!zevpn)
9537 return 0;
9538
9539 /* If the remote vtep entry doesn't exists nothing to do */
9540 zvtep = zevpn_vtep_find(zevpn, &vtep_ip);
9541 if (!zvtep)
9542 return 0;
9543
9544 if (IS_ZEBRA_DEBUG_VXLAN)
9545 zlog_debug(
9546 "Del MAC for remote VTEP %s intf %s(%u) VNI %u - readd",
9547 inet_ntoa(vtep_ip), ifp->name, ifp->ifindex, vni);
9548
9549 zevpn_vtep_install(zevpn, zvtep);
9550 return 0;
9551 }
9552
9553 /*
9554 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
9555 * us, this must involve a multihoming scenario. Treat this as implicit delete
9556 * of any prior local MAC.
9557 */
9558 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
9559 struct interface *br_if,
9560 struct ethaddr *macaddr, vlanid_t vid)
9561 {
9562 struct zebra_if *zif;
9563 struct zebra_l2info_vxlan *vxl;
9564 vni_t vni;
9565 zebra_evpn_t *zevpn;
9566 zebra_mac_t *mac;
9567 char buf[ETHER_ADDR_STRLEN];
9568
9569 zif = ifp->info;
9570 assert(zif);
9571 vxl = &zif->l2info.vxl;
9572 vni = vxl->vni;
9573
9574 /* Check if EVPN is enabled. */
9575 if (!is_evpn_enabled())
9576 return 0;
9577
9578 /* Locate hash entry; it is expected to exist. */
9579 zevpn = zevpn_lookup(vni);
9580 if (!zevpn)
9581 return 0;
9582
9583 /* If entry doesn't exist, nothing to do. */
9584 mac = zevpn_mac_lookup(zevpn, macaddr);
9585 if (!mac)
9586 return 0;
9587
9588 /* Is it a local entry? */
9589 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
9590 return 0;
9591
9592 if (IS_ZEBRA_DEBUG_VXLAN)
9593 zlog_debug(
9594 "Add/update remote MAC %s intf %s(%u) VNI %u flags 0x%x - del local",
9595 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
9596 ifp->ifindex, vni, mac->flags);
9597
9598 /* Remove MAC from BGP. */
9599 zevpn_mac_send_del_to_client(zevpn->vni, macaddr,
9600 mac->flags, false /* force */);
9601
9602 /*
9603 * If there are no neigh associated with the mac delete the mac
9604 * else mark it as AUTO for forward reference
9605 */
9606 if (!listcount(mac->neigh_list)) {
9607 zevpn_mac_del(zevpn, mac);
9608 } else {
9609 UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
9610 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
9611 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
9612 }
9613
9614 return 0;
9615 }
9616
9617 /*
9618 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
9619 * This can happen because the remote MAC entries are also added as "dynamic",
9620 * so the kernel can ageout the entry.
9621 */
9622 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
9623 struct interface *br_if,
9624 struct ethaddr *macaddr, vlanid_t vid)
9625 {
9626 struct zebra_if *zif = NULL;
9627 struct zebra_l2info_vxlan *vxl = NULL;
9628 vni_t vni;
9629 zebra_evpn_t *zevpn = NULL;
9630 zebra_l3vni_t *zl3vni = NULL;
9631 zebra_mac_t *mac = NULL;
9632 char buf[ETHER_ADDR_STRLEN];
9633
9634 zif = ifp->info;
9635 assert(zif);
9636 vxl = &zif->l2info.vxl;
9637 vni = vxl->vni;
9638
9639 /* Check if EVPN is enabled. */
9640 if (!is_evpn_enabled())
9641 return 0;
9642
9643 /* check if this is a remote RMAC and readd simillar to remote macs */
9644 zl3vni = zl3vni_lookup(vni);
9645 if (zl3vni)
9646 return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
9647
9648 /* Locate hash entry; it is expected to exist. */
9649 zevpn = zevpn_lookup(vni);
9650 if (!zevpn)
9651 return 0;
9652
9653 /* If entry doesn't exist, nothing to do. */
9654 mac = zevpn_mac_lookup(zevpn, macaddr);
9655 if (!mac)
9656 return 0;
9657
9658 /* Is it a remote entry? */
9659 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
9660 return 0;
9661
9662 if (IS_ZEBRA_DEBUG_VXLAN)
9663 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
9664 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
9665 ifp->ifindex, vni);
9666
9667 zevpn_rem_mac_install(zevpn, mac, false /* was_static */);
9668 return 0;
9669 }
9670
9671 /*
9672 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
9673 */
9674 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
9675 struct ethaddr *macaddr, vlanid_t vid)
9676 {
9677 zebra_evpn_t *zevpn;
9678 zebra_mac_t *mac;
9679 char buf[ETHER_ADDR_STRLEN];
9680 bool old_bgp_ready;
9681 bool new_bgp_ready;
9682
9683 /* We are interested in MACs only on ports or (port, VLAN) that
9684 * map to a VNI.
9685 */
9686 zevpn = zevpn_map_vlan(ifp, br_if, vid);
9687 if (!zevpn)
9688 return 0;
9689 if (!zevpn->vxlan_if) {
9690 zlog_debug(
9691 "VNI %u hash %p doesn't have intf upon local MAC DEL",
9692 zevpn->vni, zevpn);
9693 return -1;
9694 }
9695
9696 /* If entry doesn't exist, nothing to do. */
9697 mac = zevpn_mac_lookup(zevpn, macaddr);
9698 if (!mac)
9699 return 0;
9700
9701 /* Is it a local entry? */
9702 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
9703 return 0;
9704
9705 if (IS_ZEBRA_DEBUG_VXLAN)
9706 zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u seq %u flags 0x%x nbr count %u",
9707 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
9708 ifp->ifindex, vid, zevpn->vni, mac->loc_seq,
9709 mac->flags, listcount(mac->neigh_list));
9710
9711 old_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
9712 if (zebra_vxlan_mac_is_static(mac)) {
9713 /* this is a synced entry and can only be removed when the
9714 * es-peers stop advertising it.
9715 */
9716 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
9717
9718 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
9719 zlog_debug("re-add sync-mac vni %u mac %s es %s seq %d f 0x%x",
9720 zevpn->vni,
9721 prefix_mac2str(macaddr,
9722 buf, sizeof(buf)),
9723 mac->es ? mac->es->esi_str : "-",
9724 mac->loc_seq,
9725 mac->flags);
9726
9727 /* inform-bgp about change in local-activity if any */
9728 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE)) {
9729 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
9730 new_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
9731 zebra_vxlan_mac_send_add_del_to_client(mac,
9732 old_bgp_ready, new_bgp_ready);
9733 }
9734
9735 /* re-install the entry in the kernel */
9736 zebra_vxlan_sync_mac_dp_install(mac, false /* set_inactive */,
9737 false /* force_clear_static */,
9738 __func__);
9739
9740 return 0;
9741 }
9742
9743 /* Update all the neigh entries associated with this mac */
9744 zevpn_process_neigh_on_local_mac_del(zevpn, mac);
9745
9746 /* Remove MAC from BGP. */
9747 zevpn_mac_send_del_to_client(zevpn->vni, macaddr,
9748 mac->flags, false /* force */);
9749
9750 zebra_evpn_es_mac_deref_entry(mac);
9751
9752 /*
9753 * If there are no neigh associated with the mac delete the mac
9754 * else mark it as AUTO for forward reference
9755 */
9756 if (!listcount(mac->neigh_list)) {
9757 zevpn_mac_del(zevpn, mac);
9758 } else {
9759 UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS);
9760 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
9761 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
9762 }
9763
9764 return 0;
9765 }
9766
9767 /* update local fowarding info. return true if a dest-ES change
9768 * is detected
9769 */
9770 static bool zebra_vxlan_local_mac_update_fwd_info(zebra_mac_t *mac,
9771 struct interface *ifp, vlanid_t vid)
9772 {
9773 struct zebra_if *zif = ifp->info;
9774 bool es_change;
9775
9776 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
9777
9778 es_change = zebra_evpn_es_mac_ref_entry(mac, zif->es_info.es);
9779
9780 if (!mac->es) {
9781 /* if es is set fwd_info is not-relevant/taped-out */
9782 mac->fwd_info.local.ifindex = ifp->ifindex;
9783 mac->fwd_info.local.vid = vid;
9784 }
9785
9786 return es_change;
9787 }
9788
9789 /*
9790 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
9791 */
9792 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
9793 struct interface *br_if,
9794 struct ethaddr *macaddr, vlanid_t vid,
9795 bool sticky, bool local_inactive,
9796 bool dp_static)
9797 {
9798 zebra_evpn_t *zevpn;
9799 zebra_mac_t *mac;
9800 struct zebra_vrf *zvrf;
9801 char buf[ETHER_ADDR_STRLEN];
9802 bool mac_sticky = false;
9803 bool inform_client = false;
9804 bool upd_neigh = false;
9805 bool is_dup_detect = false;
9806 struct in_addr vtep_ip = {.s_addr = 0};
9807 bool es_change = false;
9808 bool new_bgp_ready;
9809 /* assume inactive if not present or if not local */
9810 bool old_local_inactive = true;
9811 bool old_bgp_ready = false;
9812 bool inform_dataplane = false;
9813 bool new_static = false;
9814
9815 if (ifp == NULL)
9816 return -1;
9817
9818 /* We are interested in MACs only on ports or (port, VLAN) that
9819 * map to an EVPN.
9820 */
9821 zevpn = zevpn_map_vlan(ifp, br_if, vid);
9822 if (!zevpn) {
9823 if (IS_ZEBRA_DEBUG_VXLAN)
9824 zlog_debug(
9825 " Add/Update %sMAC %s intf %s(%u) VID %u, could not find EVPN",
9826 sticky ? "sticky " : "",
9827 prefix_mac2str(macaddr, buf, sizeof(buf)),
9828 ifp->name, ifp->ifindex, vid);
9829 return 0;
9830 }
9831
9832 if (!zevpn->vxlan_if) {
9833 if (IS_ZEBRA_DEBUG_VXLAN)
9834 zlog_debug(
9835 " VNI %u hash %p doesn't have intf upon local MAC ADD",
9836 zevpn->vni, zevpn);
9837 return -1;
9838 }
9839
9840 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
9841 if (!zvrf) {
9842 if (IS_ZEBRA_DEBUG_VXLAN)
9843 zlog_debug(" No Vrf found for vrf_id: %d",
9844 zevpn->vxlan_if->vrf_id);
9845 return -1;
9846 }
9847
9848 /* Check if we need to create or update or it is a NO-OP. */
9849 mac = zevpn_mac_lookup(zevpn, macaddr);
9850 if (!mac) {
9851 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
9852 zlog_debug(
9853 "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u%s",
9854 sticky ? "sticky " : "",
9855 prefix_mac2str(macaddr, buf, sizeof(buf)),
9856 ifp->name, ifp->ifindex, vid, zevpn->vni,
9857 local_inactive ? " local-inactive" : "");
9858
9859 mac = zevpn_mac_add(zevpn, macaddr);
9860 if (!mac) {
9861 flog_err(
9862 EC_ZEBRA_MAC_ADD_FAILED,
9863 "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
9864 prefix_mac2str(macaddr, buf, sizeof(buf)),
9865 ifp->name, ifp->ifindex, vid, zevpn->vni);
9866 return -1;
9867 }
9868 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
9869 es_change = zebra_vxlan_local_mac_update_fwd_info(mac,
9870 ifp, vid);
9871 if (sticky)
9872 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
9873 inform_client = true;
9874 } else {
9875 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
9876 zlog_debug(
9877 "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x",
9878 sticky ? "sticky " : "",
9879 prefix_mac2str(macaddr, buf, sizeof(buf)),
9880 ifp->name, ifp->ifindex, vid, zevpn->vni,
9881 local_inactive ? "local-inactive " : "",
9882 mac->flags);
9883
9884 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
9885 struct interface *old_ifp;
9886 vlanid_t old_vid;
9887 bool old_static;
9888
9889 zebra_vxlan_mac_get_access_info(mac,
9890 &old_ifp, &old_vid);
9891 old_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(
9892 mac->flags);
9893 old_local_inactive = !!(mac->flags &
9894 ZEBRA_MAC_LOCAL_INACTIVE);
9895 old_static = zebra_vxlan_mac_is_static(mac);
9896 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
9897 mac_sticky = true;
9898
9899 /*
9900 * Update any changes and if changes are relevant to
9901 * BGP, note it.
9902 */
9903 if (mac_sticky == sticky
9904 && old_ifp == ifp
9905 && old_vid == vid
9906 && old_local_inactive == local_inactive
9907 && dp_static == old_static) {
9908 if (IS_ZEBRA_DEBUG_VXLAN)
9909 zlog_debug(
9910 " Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, entry exists and has not changed ",
9911 sticky ? "sticky " : "",
9912 prefix_mac2str(macaddr, buf,
9913 sizeof(buf)),
9914 ifp->name, ifp->ifindex, vid,
9915 zevpn->vni,
9916 local_inactive ?
9917 " local_inactive" : "");
9918 return 0;
9919 }
9920 if (mac_sticky != sticky) {
9921 if (sticky)
9922 SET_FLAG(mac->flags,
9923 ZEBRA_MAC_STICKY);
9924 else
9925 UNSET_FLAG(mac->flags,
9926 ZEBRA_MAC_STICKY);
9927 inform_client = true;
9928 }
9929
9930 es_change = zebra_vxlan_local_mac_update_fwd_info(mac,
9931 ifp, vid);
9932 /* If an es_change is detected we need to advertise
9933 * the route with a sequence that is one
9934 * greater. This is need to indicate a mac-move
9935 * to the ES peers
9936 */
9937 if (es_change) {
9938 mac->loc_seq = mac->loc_seq + 1;
9939 /* force drop the peer/sync info as it is
9940 * simply no longer relevant
9941 */
9942 if (CHECK_FLAG(mac->flags,
9943 ZEBRA_MAC_ALL_PEER_FLAGS)) {
9944 zebra_vxlan_mac_clear_sync_info(mac);
9945 new_static =
9946 zebra_vxlan_mac_is_static(mac);
9947 /* if we clear peer-flags we
9948 * also need to notify the dataplane
9949 * to drop the static flag
9950 */
9951 if (old_static != new_static)
9952 inform_dataplane = true;
9953 }
9954 }
9955 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
9956 CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
9957 bool do_dad = false;
9958
9959 /*
9960 * MAC has either moved or was "internally" created due
9961 * to a neighbor learn and is now actually learnt. If
9962 * it was learnt as a remote sticky MAC, this is an
9963 * operator error.
9964 */
9965 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
9966 flog_warn(
9967 EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
9968 "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
9969 prefix_mac2str(macaddr, buf,
9970 sizeof(buf)),
9971 inet_ntoa(mac->fwd_info.r_vtep_ip),
9972 zevpn->vni);
9973 return 0;
9974 }
9975
9976 /* If an actual move, compute MAC's seq number */
9977 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
9978 mac->loc_seq = MAX(mac->rem_seq + 1,
9979 mac->loc_seq);
9980 vtep_ip = mac->fwd_info.r_vtep_ip;
9981 /* Trigger DAD for remote MAC */
9982 do_dad = true;
9983 }
9984
9985 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
9986 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
9987 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
9988 es_change = zebra_vxlan_local_mac_update_fwd_info(mac,
9989 ifp, vid);
9990 if (sticky)
9991 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
9992 else
9993 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
9994 /*
9995 * We have to inform BGP of this MAC as well as process
9996 * all neighbors.
9997 */
9998 inform_client = true;
9999 upd_neigh = true;
10000
10001 zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac, vtep_ip,
10002 do_dad,
10003 &is_dup_detect,
10004 true);
10005 if (is_dup_detect) {
10006 inform_client = false;
10007 upd_neigh = false;
10008 }
10009 }
10010 }
10011
10012 /* if the dataplane thinks the entry is sync but it is
10013 * not sync in zebra we need to re-install to fixup
10014 */
10015 if (dp_static) {
10016 new_static = zebra_vxlan_mac_is_static(mac);
10017 if (!new_static)
10018 inform_dataplane = true;
10019 }
10020
10021 if (local_inactive)
10022 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
10023 else
10024 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
10025
10026 new_bgp_ready = zebra_vxlan_mac_is_ready_for_bgp(mac->flags);
10027 /* if local-activity has changed we need update bgp
10028 * even if bgp already knows about the mac
10029 */
10030 if ((old_local_inactive != local_inactive) ||
10031 (new_bgp_ready != old_bgp_ready)) {
10032 if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
10033 zlog_debug("local mac vni %u mac %s es %s seq %d f 0x%x%s",
10034 zevpn->vni,
10035 prefix_mac2str(macaddr,
10036 buf, sizeof(buf)),
10037 mac->es ? mac->es->esi_str : "",
10038 mac->loc_seq,
10039 mac->flags,
10040 local_inactive ?
10041 " local-inactive" : "");
10042 inform_client = true;
10043 }
10044
10045 if (es_change) {
10046 inform_client = true;
10047 upd_neigh = true;
10048 }
10049
10050 /* Inform dataplane if required. */
10051 if (inform_dataplane)
10052 zebra_vxlan_sync_mac_dp_install(mac, false /* set_inactive */,
10053 false /* force_clear_static */, __func__);
10054
10055 /* Inform BGP if required. */
10056 if (inform_client)
10057 zebra_vxlan_mac_send_add_del_to_client(mac,
10058 old_bgp_ready, new_bgp_ready);
10059
10060 /* Process all neighbors associated with this MAC, if required. */
10061 if (upd_neigh)
10062 zevpn_process_neigh_on_local_mac_change(zevpn, mac, 0, es_change);
10063
10064 return 0;
10065 }
10066
10067 /*
10068 * Handle message from client to delete a remote VTEP for an EVPN.
10069 */
10070 void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
10071 {
10072 struct stream *s;
10073 unsigned short l = 0;
10074 vni_t vni;
10075 struct in_addr vtep_ip;
10076 zebra_evpn_t *zevpn;
10077 zebra_vtep_t *zvtep;
10078 struct interface *ifp;
10079 struct zebra_if *zif;
10080
10081 if (!is_evpn_enabled()) {
10082 zlog_debug(
10083 "%s: EVPN is not enabled yet we have received a vtep del command",
10084 __func__);
10085 return;
10086 }
10087
10088 if (!EVPN_ENABLED(zvrf)) {
10089 zlog_debug("Recv MACIP DEL for non-EVPN VRF %u",
10090 zvrf_id(zvrf));
10091 return;
10092 }
10093
10094 s = msg;
10095
10096 while (l < hdr->length) {
10097 int flood_control __attribute__((unused));
10098
10099 /* Obtain each remote VTEP and process. */
10100 STREAM_GETL(s, vni);
10101 l += 4;
10102 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
10103 l += IPV4_MAX_BYTELEN;
10104
10105 /* Flood control is intentionally ignored right now */
10106 STREAM_GETL(s, flood_control);
10107 l += 4;
10108
10109 if (IS_ZEBRA_DEBUG_VXLAN)
10110 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
10111 inet_ntoa(vtep_ip), vni,
10112 zebra_route_string(client->proto));
10113
10114 /* Locate VNI hash entry - expected to exist. */
10115 zevpn = zevpn_lookup(vni);
10116 if (!zevpn) {
10117 if (IS_ZEBRA_DEBUG_VXLAN)
10118 zlog_debug(
10119 "Failed to locate VNI hash upon remote VTEP DEL, VNI %u",
10120 vni);
10121 continue;
10122 }
10123
10124 ifp = zevpn->vxlan_if;
10125 if (!ifp) {
10126 zlog_debug(
10127 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
10128 zevpn->vni, zevpn);
10129 continue;
10130 }
10131 zif = ifp->info;
10132
10133 /* If down or not mapped to a bridge, we're done. */
10134 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
10135 continue;
10136
10137 /* If the remote VTEP does not exist, there's nothing more to
10138 * do.
10139 * Otherwise, uninstall any remote MACs pointing to this VTEP
10140 * and
10141 * then, the VTEP entry itself and remove it.
10142 */
10143 zvtep = zevpn_vtep_find(zevpn, &vtep_ip);
10144 if (!zvtep)
10145 continue;
10146
10147 zevpn_vtep_uninstall(zevpn, &vtep_ip);
10148 zevpn_vtep_del(zevpn, zvtep);
10149 }
10150
10151 stream_failure:
10152 return;
10153 }
10154
10155 /*
10156 * Handle message from client to add a remote VTEP for an EVPN.
10157 */
10158 void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
10159 {
10160 struct stream *s;
10161 unsigned short l = 0;
10162 vni_t vni;
10163 struct in_addr vtep_ip;
10164 zebra_evpn_t *zevpn;
10165 struct interface *ifp;
10166 struct zebra_if *zif;
10167 int flood_control;
10168 zebra_vtep_t *zvtep;
10169
10170 if (!is_evpn_enabled()) {
10171 zlog_debug(
10172 "%s: EVPN not enabled yet we received a vtep_add zapi call",
10173 __func__);
10174 return;
10175 }
10176
10177 if (!EVPN_ENABLED(zvrf)) {
10178 zlog_debug("Recv MACIP ADD for non-EVPN VRF %u",
10179 zvrf_id(zvrf));
10180 return;
10181 }
10182
10183 s = msg;
10184
10185 while (l < hdr->length) {
10186 /* Obtain each remote VTEP and process. */
10187 STREAM_GETL(s, vni);
10188 l += 4;
10189 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
10190 STREAM_GETL(s, flood_control);
10191 l += IPV4_MAX_BYTELEN + 4;
10192
10193 if (IS_ZEBRA_DEBUG_VXLAN)
10194 zlog_debug("Recv VTEP_ADD %s VNI %u flood %d from %s",
10195 inet_ntoa(vtep_ip), vni, flood_control,
10196 zebra_route_string(client->proto));
10197
10198 /* Locate VNI hash entry - expected to exist. */
10199 zevpn = zevpn_lookup(vni);
10200 if (!zevpn) {
10201 flog_err(
10202 EC_ZEBRA_VTEP_ADD_FAILED,
10203 "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
10204 vni);
10205 continue;
10206 }
10207
10208 ifp = zevpn->vxlan_if;
10209 if (!ifp) {
10210 flog_err(
10211 EC_ZEBRA_VTEP_ADD_FAILED,
10212 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
10213 zevpn->vni, zevpn);
10214 continue;
10215 }
10216
10217 zif = ifp->info;
10218
10219 /* If down or not mapped to a bridge, we're done. */
10220 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
10221 continue;
10222
10223 zvtep = zevpn_vtep_find(zevpn, &vtep_ip);
10224 if (zvtep) {
10225 /* If the remote VTEP already exists check if
10226 * the flood mode has changed
10227 */
10228 if (zvtep->flood_control != flood_control) {
10229 if (zvtep->flood_control
10230 == VXLAN_FLOOD_DISABLED)
10231 /* old mode was head-end-replication but
10232 * is no longer; get rid of the HER fdb
10233 * entry installed before
10234 */
10235 zevpn_vtep_uninstall(zevpn, &vtep_ip);
10236 zvtep->flood_control = flood_control;
10237 zevpn_vtep_install(zevpn, zvtep);
10238 }
10239 } else {
10240 zvtep = zevpn_vtep_add(zevpn, &vtep_ip, flood_control);
10241 if (zvtep)
10242 zevpn_vtep_install(zevpn, zvtep);
10243 else
10244 flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
10245 "Failed to add remote VTEP, VNI %u zevpn %p",
10246 vni, zevpn);
10247 }
10248 }
10249
10250 stream_failure:
10251 return;
10252 }
10253
10254 /*
10255 * Add/Del gateway macip to evpn
10256 * g/w can be:
10257 * 1. SVI interface on a vlan aware bridge
10258 * 2. SVI interface on a vlan unaware bridge
10259 * 3. vrr interface (MACVLAN) associated to a SVI
10260 * We advertise macip routes for an interface if it is associated to VxLan vlan
10261 */
10262 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
10263 int add)
10264 {
10265 struct ipaddr ip;
10266 struct ethaddr macaddr;
10267 zebra_evpn_t *zevpn = NULL;
10268
10269 memset(&ip, 0, sizeof(struct ipaddr));
10270 memset(&macaddr, 0, sizeof(struct ethaddr));
10271
10272 /* Check if EVPN is enabled. */
10273 if (!is_evpn_enabled())
10274 return 0;
10275
10276 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
10277 struct interface *svi_if =
10278 NULL; /* SVI corresponding to the MACVLAN */
10279 struct zebra_if *ifp_zif =
10280 NULL; /* Zebra daemon specific info for MACVLAN */
10281 struct zebra_if *svi_if_zif =
10282 NULL; /* Zebra daemon specific info for SVI*/
10283
10284 ifp_zif = ifp->info;
10285 if (!ifp_zif)
10286 return -1;
10287
10288 /*
10289 * for a MACVLAN interface the link represents the svi_if
10290 */
10291 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
10292 ifp_zif->link_ifindex);
10293 if (!svi_if) {
10294 zlog_debug("MACVLAN %s(%u) without link information",
10295 ifp->name, ifp->ifindex);
10296 return -1;
10297 }
10298
10299 if (IS_ZEBRA_IF_VLAN(svi_if)) {
10300 /*
10301 * If it is a vlan aware bridge then the link gives the
10302 * bridge information
10303 */
10304 struct interface *svi_if_link = NULL;
10305
10306 svi_if_zif = svi_if->info;
10307 if (svi_if_zif) {
10308 svi_if_link = if_lookup_by_index_per_ns(
10309 zebra_ns_lookup(NS_DEFAULT),
10310 svi_if_zif->link_ifindex);
10311 zevpn = zevpn_from_svi(svi_if, svi_if_link);
10312 }
10313 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
10314 /*
10315 * If it is a vlan unaware bridge then svi is the bridge
10316 * itself
10317 */
10318 zevpn = zevpn_from_svi(svi_if, svi_if);
10319 }
10320 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
10321 struct zebra_if *svi_if_zif =
10322 NULL; /* Zebra daemon specific info for SVI */
10323 struct interface *svi_if_link =
10324 NULL; /* link info for the SVI = bridge info */
10325
10326 svi_if_zif = ifp->info;
10327 if (svi_if_zif) {
10328 svi_if_link = if_lookup_by_index_per_ns(
10329 zebra_ns_lookup(NS_DEFAULT),
10330 svi_if_zif->link_ifindex);
10331 if (svi_if_link)
10332 zevpn = zevpn_from_svi(ifp, svi_if_link);
10333 }
10334 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
10335 zevpn = zevpn_from_svi(ifp, ifp);
10336 }
10337
10338 if (!zevpn)
10339 return 0;
10340
10341 if (!zevpn->vxlan_if) {
10342 zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
10343 zevpn->vni, zevpn);
10344 return -1;
10345 }
10346
10347
10348 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
10349
10350 if (p->family == AF_INET) {
10351 ip.ipa_type = IPADDR_V4;
10352 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
10353 sizeof(struct in_addr));
10354 } else if (p->family == AF_INET6) {
10355 ip.ipa_type = IPADDR_V6;
10356 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
10357 sizeof(struct in6_addr));
10358 }
10359
10360
10361 if (add)
10362 zevpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
10363 else
10364 zevpn_gw_macip_del(ifp, zevpn, &ip);
10365
10366 return 0;
10367 }
10368
10369 /*
10370 * Handle SVI interface going down.
10371 * SVI can be associated to either L3-VNI or L2-VNI.
10372 * For L2-VNI: At this point, this is a NOP since
10373 * the kernel deletes the neighbor entries on this SVI (if any).
10374 * We only need to update the vrf corresponding to zevpn.
10375 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
10376 * from bgp
10377 */
10378 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
10379 {
10380 zebra_l3vni_t *zl3vni = NULL;
10381
10382 zl3vni = zl3vni_from_svi(ifp, link_if);
10383 if (zl3vni) {
10384
10385 /* process l3-vni down */
10386 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10387
10388 /* remove association with svi-if */
10389 zl3vni->svi_if = NULL;
10390 } else {
10391 zebra_evpn_t *zevpn = NULL;
10392
10393 /* since we dont have svi corresponding to zevpn, we associate it
10394 * to default vrf. Note: the corresponding neigh entries on the
10395 * SVI would have already been deleted */
10396 zevpn = zevpn_from_svi(ifp, link_if);
10397 if (zevpn) {
10398 zevpn->vrf_id = VRF_DEFAULT;
10399
10400 /* update the tenant vrf in BGP */
10401 zevpn_send_add_to_client(zevpn);
10402 }
10403 }
10404 return 0;
10405 }
10406
10407 /*
10408 * Handle SVI interface coming up.
10409 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
10410 * vxlan intf).
10411 * For L2-VNI: we need to install any remote neighbors entried (used for
10412 * apr-suppression)
10413 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
10414 */
10415 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
10416 {
10417 zebra_evpn_t *zevpn = NULL;
10418 zebra_l3vni_t *zl3vni = NULL;
10419
10420 zl3vni = zl3vni_from_svi(ifp, link_if);
10421 if (zl3vni) {
10422
10423 /* associate with svi */
10424 zl3vni->svi_if = ifp;
10425
10426 /* process oper-up */
10427 if (is_l3vni_oper_up(zl3vni))
10428 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10429 } else {
10430
10431 /* process SVI up for l2-vni */
10432 struct neigh_walk_ctx n_wctx;
10433
10434 zevpn = zevpn_from_svi(ifp, link_if);
10435 if (!zevpn)
10436 return 0;
10437
10438 if (!zevpn->vxlan_if) {
10439 zlog_debug(
10440 "VNI %u hash %p doesn't have intf upon SVI up",
10441 zevpn->vni, zevpn);
10442 return -1;
10443 }
10444
10445 if (IS_ZEBRA_DEBUG_VXLAN)
10446 zlog_debug(
10447 "SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
10448 ifp->name, ifp->ifindex, zevpn->vni,
10449 vrf_id_to_name(ifp->vrf_id));
10450
10451 /* update the vrf information for l2-vni and inform bgp */
10452 zevpn->vrf_id = ifp->vrf_id;
10453 zevpn_send_add_to_client(zevpn);
10454
10455 /* Install any remote neighbors for this VNI. */
10456 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
10457 n_wctx.zevpn = zevpn;
10458 hash_iterate(zevpn->neigh_table, zevpn_install_neigh_hash,
10459 &n_wctx);
10460 }
10461
10462 return 0;
10463 }
10464
10465 /*
10466 * Handle MAC-VLAN interface going down.
10467 * L3VNI: When MAC-VLAN interface goes down,
10468 * find its associated SVI and update type2/type-5 routes
10469 * with SVI as RMAC
10470 */
10471 void zebra_vxlan_macvlan_down(struct interface *ifp)
10472 {
10473 zebra_l3vni_t *zl3vni = NULL;
10474 struct zebra_if *zif, *link_zif;
10475 struct interface *link_ifp, *link_if;
10476
10477 zif = ifp->info;
10478 assert(zif);
10479 link_ifp = zif->link;
10480 if (!link_ifp) {
10481 if (IS_ZEBRA_DEBUG_VXLAN) {
10482 struct interface *ifp;
10483
10484 ifp = if_lookup_by_index_all_vrf(zif->link_ifindex);
10485 zlog_debug("macvlan parent link is not found. Parent index %d ifp %s",
10486 zif->link_ifindex, ifp ? ifp->name : " ");
10487 }
10488 return;
10489 }
10490 link_zif = link_ifp->info;
10491 assert(link_zif);
10492
10493 link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
10494 link_zif->link_ifindex);
10495
10496 zl3vni = zl3vni_from_svi(link_ifp, link_if);
10497 if (zl3vni) {
10498 zl3vni->mac_vlan_if = NULL;
10499 if (is_l3vni_oper_up(zl3vni))
10500 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10501 }
10502 }
10503
10504 /*
10505 * Handle MAC-VLAN interface going up.
10506 * L3VNI: When MAC-VLAN interface comes up,
10507 * find its associated SVI and update type-2 routes
10508 * with MAC-VLAN's MAC as RMAC and for type-5 routes
10509 * use SVI's MAC as RMAC.
10510 */
10511 void zebra_vxlan_macvlan_up(struct interface *ifp)
10512 {
10513 zebra_l3vni_t *zl3vni = NULL;
10514 struct zebra_if *zif, *link_zif;
10515 struct interface *link_ifp, *link_if;
10516
10517 zif = ifp->info;
10518 assert(zif);
10519 link_ifp = zif->link;
10520 link_zif = link_ifp->info;
10521 assert(link_zif);
10522
10523 link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
10524 link_zif->link_ifindex);
10525 zl3vni = zl3vni_from_svi(link_ifp, link_if);
10526 if (zl3vni) {
10527 /* associate with macvlan (VRR) interface */
10528 zl3vni->mac_vlan_if = ifp;
10529
10530 /* process oper-up */
10531 if (is_l3vni_oper_up(zl3vni))
10532 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10533 }
10534 }
10535
10536 /*
10537 * Handle VxLAN interface down
10538 */
10539 int zebra_vxlan_if_down(struct interface *ifp)
10540 {
10541 vni_t vni;
10542 struct zebra_if *zif = NULL;
10543 struct zebra_l2info_vxlan *vxl = NULL;
10544 zebra_l3vni_t *zl3vni = NULL;
10545 zebra_evpn_t *zevpn;
10546
10547 /* Check if EVPN is enabled. */
10548 if (!is_evpn_enabled())
10549 return 0;
10550
10551 zif = ifp->info;
10552 assert(zif);
10553 vxl = &zif->l2info.vxl;
10554 vni = vxl->vni;
10555
10556 zl3vni = zl3vni_lookup(vni);
10557 if (zl3vni) {
10558 /* process-if-down for l3-vni */
10559 if (IS_ZEBRA_DEBUG_VXLAN)
10560 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name,
10561 ifp->ifindex, vni);
10562
10563 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10564 } else {
10565 /* process if-down for l2-vni */
10566 if (IS_ZEBRA_DEBUG_VXLAN)
10567 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name,
10568 ifp->ifindex, vni);
10569
10570 /* Locate hash entry; it is expected to exist. */
10571 zevpn = zevpn_lookup(vni);
10572 if (!zevpn) {
10573 zlog_debug(
10574 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
10575 ifp->name, ifp->ifindex, vni);
10576 return -1;
10577 }
10578
10579 assert(zevpn->vxlan_if == ifp);
10580
10581 /* Delete this VNI from BGP. */
10582 zevpn_send_del_to_client(zevpn);
10583
10584 /* Free up all neighbors and MACs, if any. */
10585 zevpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
10586 zevpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
10587
10588 /* Free up all remote VTEPs, if any. */
10589 zevpn_vtep_del_all(zevpn, 1);
10590 }
10591 return 0;
10592 }
10593
10594 /*
10595 * Handle VxLAN interface up - update BGP if required.
10596 */
10597 int zebra_vxlan_if_up(struct interface *ifp)
10598 {
10599 vni_t vni;
10600 struct zebra_if *zif = NULL;
10601 struct zebra_l2info_vxlan *vxl = NULL;
10602 zebra_evpn_t *zevpn = NULL;
10603 zebra_l3vni_t *zl3vni = NULL;
10604
10605 /* Check if EVPN is enabled. */
10606 if (!is_evpn_enabled())
10607 return 0;
10608
10609 zif = ifp->info;
10610 assert(zif);
10611 vxl = &zif->l2info.vxl;
10612 vni = vxl->vni;
10613
10614 zl3vni = zl3vni_lookup(vni);
10615 if (zl3vni) {
10616 /* we need to associate with SVI, if any, we can associate with
10617 * svi-if only after association with vxlan-intf is complete
10618 */
10619 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
10620 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
10621
10622 if (IS_ZEBRA_DEBUG_VXLAN)
10623 zlog_debug("Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s"
10624 , ifp->name, ifp->ifindex, vni,
10625 zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
10626 zl3vni->mac_vlan_if ?
10627 zl3vni->mac_vlan_if->name : "NIL");
10628
10629 if (is_l3vni_oper_up(zl3vni))
10630 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10631 } else {
10632 /* Handle L2-VNI add */
10633 struct interface *vlan_if = NULL;
10634
10635 if (IS_ZEBRA_DEBUG_VXLAN)
10636 zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name,
10637 ifp->ifindex, vni);
10638
10639 /* Locate hash entry; it is expected to exist. */
10640 zevpn = zevpn_lookup(vni);
10641 if (!zevpn) {
10642 zlog_debug(
10643 "Failed to locate EVPN hash at UP, IF %s(%u) VNI %u",
10644 ifp->name, ifp->ifindex, vni);
10645 return -1;
10646 }
10647
10648 assert(zevpn->vxlan_if == ifp);
10649 vlan_if = zevpn_map_to_svi(vxl->access_vlan,
10650 zif->brslave_info.br_if);
10651 if (vlan_if) {
10652 zevpn->vrf_id = vlan_if->vrf_id;
10653 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
10654 if (zl3vni)
10655 listnode_add_sort(zl3vni->l2vnis, zevpn);
10656 }
10657
10658 /* If part of a bridge, inform BGP about this VNI. */
10659 /* Also, read and populate local MACs and neighbors. */
10660 if (zif->brslave_info.br_if) {
10661 zevpn_send_add_to_client(zevpn);
10662 zevpn_read_mac_neigh(zevpn, ifp);
10663 }
10664 }
10665
10666 return 0;
10667 }
10668
10669 /*
10670 * Handle VxLAN interface delete. Locate and remove entry in hash table
10671 * and update BGP, if required.
10672 */
10673 int zebra_vxlan_if_del(struct interface *ifp)
10674 {
10675 vni_t vni;
10676 struct zebra_if *zif = NULL;
10677 struct zebra_l2info_vxlan *vxl = NULL;
10678 zebra_evpn_t *zevpn = NULL;
10679 zebra_l3vni_t *zl3vni = NULL;
10680
10681 /* Check if EVPN is enabled. */
10682 if (!is_evpn_enabled())
10683 return 0;
10684
10685 zif = ifp->info;
10686 assert(zif);
10687 vxl = &zif->l2info.vxl;
10688 vni = vxl->vni;
10689
10690 zl3vni = zl3vni_lookup(vni);
10691 if (zl3vni) {
10692
10693 if (IS_ZEBRA_DEBUG_VXLAN)
10694 zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name,
10695 ifp->ifindex);
10696
10697 /* process oper-down for l3-vni */
10698 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10699
10700 /* remove the association with vxlan_if */
10701 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
10702 zl3vni->vxlan_if = NULL;
10703 } else {
10704
10705 /* process if-del for l2-vni*/
10706 if (IS_ZEBRA_DEBUG_VXLAN)
10707 zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name,
10708 ifp->ifindex);
10709
10710 /* Locate hash entry; it is expected to exist. */
10711 zevpn = zevpn_lookup(vni);
10712 if (!zevpn) {
10713 zlog_debug(
10714 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
10715 ifp->name, ifp->ifindex, vni);
10716 return 0;
10717 }
10718
10719 /* remove from l3-vni list */
10720 zl3vni = zl3vni_from_vrf(zevpn->vrf_id);
10721 if (zl3vni)
10722 listnode_delete(zl3vni->l2vnis, zevpn);
10723 /* Delete VNI from BGP. */
10724 zevpn_send_del_to_client(zevpn);
10725
10726 /* Free up all neighbors and MAC, if any. */
10727 zevpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH);
10728 zevpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
10729
10730 /* Free up all remote VTEPs, if any. */
10731 zevpn_vtep_del_all(zevpn, 0);
10732
10733 /* Delete the hash entry. */
10734 if (zevpn_del(zevpn)) {
10735 flog_err(EC_ZEBRA_VNI_DEL_FAILED,
10736 "Failed to del EVPN hash %p, IF %s(%u) VNI %u",
10737 zevpn, ifp->name, ifp->ifindex, zevpn->vni);
10738 return -1;
10739 }
10740 }
10741 return 0;
10742 }
10743
10744 /*
10745 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
10746 */
10747 int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
10748 {
10749 vni_t vni;
10750 struct zebra_if *zif = NULL;
10751 struct zebra_l2info_vxlan *vxl = NULL;
10752 zebra_evpn_t *zevpn = NULL;
10753 zebra_l3vni_t *zl3vni = NULL;
10754
10755 /* Check if EVPN is enabled. */
10756 if (!is_evpn_enabled())
10757 return 0;
10758
10759 zif = ifp->info;
10760 assert(zif);
10761 vxl = &zif->l2info.vxl;
10762 vni = vxl->vni;
10763
10764 zl3vni = zl3vni_lookup(vni);
10765 if (zl3vni) {
10766
10767 if (IS_ZEBRA_DEBUG_VXLAN)
10768 zlog_debug(
10769 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
10770 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
10771 inet_ntoa(vxl->vtep_ip),
10772 zif->brslave_info.bridge_ifindex, chgflags);
10773
10774 /* Removed from bridge? Cleanup and return */
10775 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
10776 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
10777 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10778 return 0;
10779 }
10780
10781 /* access-vlan change - process oper down, associate with new
10782 * svi_if and then process oper up again
10783 */
10784 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
10785 if (if_is_operative(ifp)) {
10786 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10787 zl3vni->svi_if = NULL;
10788 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
10789 zl3vni->mac_vlan_if =
10790 zl3vni_map_to_mac_vlan_if(zl3vni);
10791 zl3vni->local_vtep_ip = vxl->vtep_ip;
10792 if (is_l3vni_oper_up(zl3vni))
10793 zebra_vxlan_process_l3vni_oper_up(
10794 zl3vni);
10795 }
10796 }
10797
10798 /*
10799 * local-ip change - process oper down, associate with new
10800 * local-ip and then process oper up again
10801 */
10802 if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) {
10803 if (if_is_operative(ifp)) {
10804 zebra_vxlan_process_l3vni_oper_down(zl3vni);
10805 zl3vni->local_vtep_ip = vxl->vtep_ip;
10806 if (is_l3vni_oper_up(zl3vni))
10807 zebra_vxlan_process_l3vni_oper_up(
10808 zl3vni);
10809 }
10810 }
10811
10812 /* Update local tunnel IP. */
10813 zl3vni->local_vtep_ip = vxl->vtep_ip;
10814
10815 /* if we have a valid new master, process l3-vni oper up */
10816 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
10817 if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni))
10818 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10819 }
10820 } else {
10821
10822 /* Update VNI hash. */
10823 zevpn = zevpn_lookup(vni);
10824 if (!zevpn) {
10825 zlog_debug(
10826 "Failed to find EVPN hash on update, IF %s(%u) VNI %u",
10827 ifp->name, ifp->ifindex, vni);
10828 return -1;
10829 }
10830
10831 if (IS_ZEBRA_DEBUG_VXLAN)
10832 zlog_debug(
10833 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
10834 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
10835 inet_ntoa(vxl->vtep_ip),
10836 zif->brslave_info.bridge_ifindex, chgflags);
10837
10838 /* Removed from bridge? Cleanup and return */
10839 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
10840 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
10841 /* Delete from client, remove all remote VTEPs */
10842 /* Also, free up all MACs and neighbors. */
10843 zevpn_send_del_to_client(zevpn);
10844 zevpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
10845 zevpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
10846 zevpn_vtep_del_all(zevpn, 1);
10847 return 0;
10848 }
10849
10850 /* Handle other changes. */
10851 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
10852 /* Remove all existing local neigh and MACs for this VNI
10853 * (including from BGP)
10854 */
10855 zevpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
10856 zevpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
10857 }
10858
10859 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
10860 zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
10861 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
10862 zevpn->mcast_grp);
10863 zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
10864 zevpn->local_vtep_ip = vxl->vtep_ip;
10865 zevpn->mcast_grp = vxl->mcast_grp;
10866 /* on local vtep-ip check if ES orig-ip
10867 * needs to be updated
10868 */
10869 zebra_evpn_es_set_base_evpn(zevpn);
10870 }
10871 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
10872 /* Take further actions needed.
10873 * Note that if we are here, there is a change of interest.
10874 */
10875 /* If down or not mapped to a bridge, we're done. */
10876 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
10877 return 0;
10878
10879 /* Inform BGP, if there is a change of interest. */
10880 if (chgflags
10881 & (ZEBRA_VXLIF_MASTER_CHANGE |
10882 ZEBRA_VXLIF_LOCAL_IP_CHANGE |
10883 ZEBRA_VXLIF_MCAST_GRP_CHANGE))
10884 zevpn_send_add_to_client(zevpn);
10885
10886 /* If there is a valid new master or a VLAN mapping change,
10887 * read and populate local MACs and neighbors.
10888 * Also, reinstall any remote MACs and neighbors
10889 * for this VNI (based on new VLAN).
10890 */
10891 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
10892 zevpn_read_mac_neigh(zevpn, ifp);
10893 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
10894 struct mac_walk_ctx m_wctx;
10895 struct neigh_walk_ctx n_wctx;
10896
10897 zevpn_read_mac_neigh(zevpn, ifp);
10898
10899 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
10900 m_wctx.zevpn = zevpn;
10901 hash_iterate(zevpn->mac_table, zevpn_install_mac_hash,
10902 &m_wctx);
10903
10904 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
10905 n_wctx.zevpn = zevpn;
10906 hash_iterate(zevpn->neigh_table, zevpn_install_neigh_hash,
10907 &n_wctx);
10908 }
10909 }
10910
10911 return 0;
10912 }
10913
10914 /*
10915 * Handle VxLAN interface add.
10916 */
10917 int zebra_vxlan_if_add(struct interface *ifp)
10918 {
10919 vni_t vni;
10920 struct zebra_if *zif = NULL;
10921 struct zebra_l2info_vxlan *vxl = NULL;
10922 zebra_evpn_t *zevpn = NULL;
10923 zebra_l3vni_t *zl3vni = NULL;
10924
10925 /* Check if EVPN is enabled. */
10926 if (!is_evpn_enabled())
10927 return 0;
10928
10929 zif = ifp->info;
10930 assert(zif);
10931 vxl = &zif->l2info.vxl;
10932 vni = vxl->vni;
10933
10934 zl3vni = zl3vni_lookup(vni);
10935 if (zl3vni) {
10936
10937 /* process if-add for l3-vni*/
10938 if (IS_ZEBRA_DEBUG_VXLAN)
10939 zlog_debug(
10940 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
10941 vni, ifp->name, ifp->ifindex, vxl->access_vlan,
10942 inet_ntoa(vxl->vtep_ip),
10943 zif->brslave_info.bridge_ifindex);
10944
10945 /* associate with vxlan_if */
10946 zl3vni->local_vtep_ip = vxl->vtep_ip;
10947 zl3vni->vxlan_if = ifp;
10948
10949 /* Associate with SVI, if any. We can associate with svi-if only
10950 * after association with vxlan_if is complete */
10951 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
10952
10953 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
10954
10955 if (is_l3vni_oper_up(zl3vni))
10956 zebra_vxlan_process_l3vni_oper_up(zl3vni);
10957 } else {
10958
10959 /* process if-add for l2-vni */
10960 struct interface *vlan_if = NULL;
10961
10962 /* Create or update EVPN hash. */
10963 zevpn = zevpn_lookup(vni);
10964 if (!zevpn) {
10965 zevpn = zevpn_add(vni);
10966 if (!zevpn) {
10967 flog_err(
10968 EC_ZEBRA_VNI_ADD_FAILED,
10969 "Failed to add EVPN hash, IF %s(%u) VNI %u",
10970 ifp->name, ifp->ifindex, vni);
10971 return -1;
10972 }
10973 }
10974
10975 if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
10976 zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
10977 zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
10978 zevpn->mcast_grp);
10979 zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
10980 zevpn->local_vtep_ip = vxl->vtep_ip;
10981 zevpn->mcast_grp = vxl->mcast_grp;
10982 /* on local vtep-ip check if ES orig-ip
10983 * needs to be updated
10984 */
10985 zebra_evpn_es_set_base_evpn(zevpn);
10986 }
10987 zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
10988 vlan_if = zevpn_map_to_svi(vxl->access_vlan,
10989 zif->brslave_info.br_if);
10990 if (vlan_if) {
10991 zevpn->vrf_id = vlan_if->vrf_id;
10992 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
10993 if (zl3vni)
10994 listnode_add_sort(zl3vni->l2vnis, zevpn);
10995 }
10996
10997 if (IS_ZEBRA_DEBUG_VXLAN) {
10998 char addr_buf1[INET_ADDRSTRLEN];
10999 char addr_buf2[INET_ADDRSTRLEN];
11000
11001 inet_ntop(AF_INET, &vxl->vtep_ip,
11002 addr_buf1, INET_ADDRSTRLEN);
11003 inet_ntop(AF_INET, &vxl->mcast_grp,
11004 addr_buf2, INET_ADDRSTRLEN);
11005
11006 zlog_debug(
11007 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s mcast_grp %s master %u",
11008 vni,
11009 vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
11010 : VRF_DEFAULT_NAME,
11011 ifp->name, ifp->ifindex, vxl->access_vlan,
11012 addr_buf1, addr_buf2,
11013 zif->brslave_info.bridge_ifindex);
11014 }
11015
11016 /* If down or not mapped to a bridge, we're done. */
11017 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
11018 return 0;
11019
11020 /* Inform BGP */
11021 zevpn_send_add_to_client(zevpn);
11022
11023 /* Read and populate local MACs and neighbors */
11024 zevpn_read_mac_neigh(zevpn, ifp);
11025 }
11026
11027 return 0;
11028 }
11029
11030 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
11031 char *err, int err_str_sz, int filter,
11032 int add)
11033 {
11034 zebra_l3vni_t *zl3vni = NULL;
11035 struct zebra_vrf *zvrf_evpn = NULL;
11036
11037 zvrf_evpn = zebra_vrf_get_evpn();
11038 if (!zvrf_evpn)
11039 return -1;
11040
11041 if (IS_ZEBRA_DEBUG_VXLAN)
11042 zlog_debug("vrf %s vni %u %s", zvrf_name(zvrf), vni,
11043 add ? "ADD" : "DEL");
11044
11045 if (add) {
11046
11047 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
11048
11049 /* check if the vni is already present under zvrf */
11050 if (zvrf->l3vni) {
11051 snprintf(err, err_str_sz,
11052 "VNI is already configured under the vrf");
11053 return -1;
11054 }
11055
11056 /* check if this VNI is already present in the system */
11057 zl3vni = zl3vni_lookup(vni);
11058 if (zl3vni) {
11059 snprintf(err, err_str_sz,
11060 "VNI is already configured as L3-VNI");
11061 return -1;
11062 }
11063
11064 /* add the L3-VNI to the global table */
11065 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
11066 if (!zl3vni) {
11067 snprintf(err, err_str_sz, "Could not add L3-VNI");
11068 return -1;
11069 }
11070
11071 /* associate the vrf with vni */
11072 zvrf->l3vni = vni;
11073
11074 /* set the filter in l3vni to denote if we are using l3vni only
11075 * for prefix routes
11076 */
11077 if (filter)
11078 SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY);
11079
11080 /* associate with vxlan-intf;
11081 * we need to associate with the vxlan-intf first
11082 */
11083 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
11084
11085 /* associate with corresponding SVI interface, we can associate
11086 * with svi-if only after vxlan interface association is
11087 * complete
11088 */
11089 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
11090
11091 zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni);
11092
11093 if (IS_ZEBRA_DEBUG_VXLAN)
11094 zlog_debug(
11095 "%s: l3vni %u svi_if %s mac_vlan_if %s",
11096 __func__, vni,
11097 zl3vni->svi_if ? zl3vni->svi_if->name : "NIL",
11098 zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name
11099 : "NIL");
11100
11101 /* formulate l2vni list */
11102 hash_iterate(zvrf_evpn->evpn_table, zevpn_add_to_l3vni_list,
11103 zl3vni);
11104
11105 if (is_l3vni_oper_up(zl3vni))
11106 zebra_vxlan_process_l3vni_oper_up(zl3vni);
11107
11108 } else {
11109 zl3vni = zl3vni_lookup(vni);
11110 if (!zl3vni) {
11111 snprintf(err, err_str_sz, "VNI doesn't exist");
11112 return -1;
11113 }
11114
11115 if (zvrf->l3vni != vni) {
11116 snprintf(err, err_str_sz,
11117 "VNI %d doesn't exist in VRF: %s",
11118 vni, zvrf->vrf->name);
11119 return -1;
11120 }
11121
11122 if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
11123 snprintf(err, ERR_STR_SZ,
11124 "prefix-routes-only is not set for the vni");
11125 return -1;
11126 }
11127
11128 zebra_vxlan_process_l3vni_oper_down(zl3vni);
11129
11130 /* delete and uninstall all rmacs */
11131 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
11132 zl3vni);
11133
11134 /* delete and uninstall all next-hops */
11135 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
11136 zl3vni);
11137
11138 zvrf->l3vni = 0;
11139 zl3vni_del(zl3vni);
11140
11141 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
11142 }
11143 return 0;
11144 }
11145
11146 int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
11147 {
11148 zebra_l3vni_t *zl3vni = NULL;
11149
11150 if (zvrf->l3vni)
11151 zl3vni = zl3vni_lookup(zvrf->l3vni);
11152 if (!zl3vni)
11153 return 0;
11154
11155 zl3vni->vrf_id = zvrf_id(zvrf);
11156 if (is_l3vni_oper_up(zl3vni))
11157 zebra_vxlan_process_l3vni_oper_up(zl3vni);
11158 return 0;
11159 }
11160
11161 int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
11162 {
11163 zebra_l3vni_t *zl3vni = NULL;
11164
11165 if (zvrf->l3vni)
11166 zl3vni = zl3vni_lookup(zvrf->l3vni);
11167 if (!zl3vni)
11168 return 0;
11169
11170 zebra_vxlan_process_l3vni_oper_down(zl3vni);
11171
11172 /* delete and uninstall all rmacs */
11173 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry, zl3vni);
11174 /* delete and uninstall all next-hops */
11175 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry, zl3vni);
11176
11177 zl3vni->vrf_id = VRF_UNKNOWN;
11178
11179 return 0;
11180 }
11181
11182 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
11183 {
11184 zebra_l3vni_t *zl3vni = NULL;
11185 vni_t vni;
11186
11187 if (zvrf->l3vni)
11188 zl3vni = zl3vni_lookup(zvrf->l3vni);
11189 if (!zl3vni)
11190 return 0;
11191
11192 vni = zl3vni->vni;
11193 zl3vni_del(zl3vni);
11194 zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
11195
11196 return 0;
11197 }
11198
11199 /*
11200 * Handle message from client to specify the flooding mechanism for
11201 * BUM packets. The default is to do head-end (ingress) replication
11202 * and the other supported option is to disable it. This applies to
11203 * all BUM traffic and disabling it applies to both the transmit and
11204 * receive direction.
11205 */
11206 void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
11207 {
11208 struct stream *s;
11209 enum vxlan_flood_control flood_ctrl;
11210
11211 if (!EVPN_ENABLED(zvrf)) {
11212 zlog_err("EVPN flood control for non-EVPN VRF %u",
11213 zvrf_id(zvrf));
11214 return;
11215 }
11216
11217 s = msg;
11218 STREAM_GETC(s, flood_ctrl);
11219
11220 if (IS_ZEBRA_DEBUG_VXLAN)
11221 zlog_debug("EVPN flood control %u, currently %u",
11222 flood_ctrl, zvrf->vxlan_flood_ctrl);
11223
11224 if (zvrf->vxlan_flood_ctrl == flood_ctrl)
11225 return;
11226
11227 zvrf->vxlan_flood_ctrl = flood_ctrl;
11228
11229 /* Install or uninstall flood entries corresponding to
11230 * remote VTEPs.
11231 */
11232 hash_iterate(zvrf->evpn_table, zevpn_handle_flooding_remote_vteps,
11233 zvrf);
11234
11235 stream_failure:
11236 return;
11237 }
11238
11239 /*
11240 * Handle message from client to enable/disable advertisement of svi macip
11241 * routes
11242 */
11243 void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
11244 {
11245 struct stream *s;
11246 int advertise;
11247 vni_t vni = 0;
11248 zebra_evpn_t *zevpn = NULL;
11249 struct interface *ifp = NULL;
11250
11251 if (!EVPN_ENABLED(zvrf)) {
11252 zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
11253 zvrf_id(zvrf));
11254 return;
11255 }
11256
11257 s = msg;
11258 STREAM_GETC(s, advertise);
11259 STREAM_GETL(s, vni);
11260
11261 if (!vni) {
11262 if (IS_ZEBRA_DEBUG_VXLAN)
11263 zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
11264 advertise ? "enabled" : "disabled",
11265 advertise_svi_macip_enabled(NULL)
11266 ? "enabled"
11267 : "disabled");
11268
11269 if (zvrf->advertise_svi_macip == advertise)
11270 return;
11271
11272
11273 if (advertise) {
11274 zvrf->advertise_svi_macip = advertise;
11275 hash_iterate(zvrf->evpn_table,
11276 zevpn_gw_macip_add_for_evpn_hash, NULL);
11277 } else {
11278 hash_iterate(zvrf->evpn_table,
11279 zevpn_svi_macip_del_for_evpn_hash, NULL);
11280 zvrf->advertise_svi_macip = advertise;
11281 }
11282
11283 } else {
11284 struct zebra_if *zif = NULL;
11285 struct zebra_l2info_vxlan zl2_info;
11286 struct interface *vlan_if = NULL;
11287
11288 zevpn = zevpn_lookup(vni);
11289 if (!zevpn)
11290 return;
11291
11292 if (IS_ZEBRA_DEBUG_VXLAN)
11293 zlog_debug(
11294 "EVPN SVI macip Adv %s on VNI %d , currently %s",
11295 advertise ? "enabled" : "disabled", vni,
11296 advertise_svi_macip_enabled(zevpn)
11297 ? "enabled"
11298 : "disabled");
11299
11300 if (zevpn->advertise_svi_macip == advertise)
11301 return;
11302
11303 /* Store flag even though SVI is not present.
11304 * Once SVI comes up triggers self MAC-IP route add.
11305 */
11306 zevpn->advertise_svi_macip = advertise;
11307
11308 ifp = zevpn->vxlan_if;
11309 if (!ifp)
11310 return;
11311
11312 zif = ifp->info;
11313
11314 /* If down or not mapped to a bridge, we're done. */
11315 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
11316 return;
11317
11318 zl2_info = zif->l2info.vxl;
11319 vlan_if = zevpn_map_to_svi(zl2_info.access_vlan,
11320 zif->brslave_info.br_if);
11321 if (!vlan_if)
11322 return;
11323
11324 if (advertise) {
11325 /* Add primary SVI MAC-IP */
11326 zevpn_add_macip_for_intf(vlan_if, zevpn);
11327 } else {
11328 /* Del primary SVI MAC-IP */
11329 zevpn_del_macip_for_intf(vlan_if, zevpn);
11330 }
11331 }
11332
11333 stream_failure:
11334 return;
11335 }
11336
11337 /*
11338 * Handle message from client to enable/disable advertisement of g/w macip
11339 * routes
11340 */
11341 void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
11342 {
11343 struct stream *s;
11344 int advertise;
11345 vni_t vni = 0;
11346 zebra_evpn_t *zevpn = NULL;
11347 struct interface *ifp = NULL;
11348 struct zebra_if *zif = NULL;
11349 struct zebra_l2info_vxlan zl2_info;
11350 struct interface *vlan_if = NULL;
11351
11352 if (!EVPN_ENABLED(zvrf)) {
11353 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
11354 zvrf_id(zvrf));
11355 return;
11356 }
11357
11358 s = msg;
11359 STREAM_GETC(s, advertise);
11360 STREAM_GET(&vni, s, 3);
11361
11362 zevpn = zevpn_lookup(vni);
11363 if (!zevpn)
11364 return;
11365
11366 if (zevpn->advertise_subnet == advertise)
11367 return;
11368
11369 if (IS_ZEBRA_DEBUG_VXLAN)
11370 zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
11371 advertise ? "enabled" : "disabled", vni,
11372 zevpn->advertise_subnet ? "enabled" : "disabled");
11373
11374
11375 zevpn->advertise_subnet = advertise;
11376
11377 ifp = zevpn->vxlan_if;
11378 if (!ifp)
11379 return;
11380
11381 zif = ifp->info;
11382
11383 /* If down or not mapped to a bridge, we're done. */
11384 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
11385 return;
11386
11387 zl2_info = zif->l2info.vxl;
11388
11389 vlan_if =
11390 zevpn_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
11391 if (!vlan_if)
11392 return;
11393
11394 if (zevpn->advertise_subnet)
11395 zevpn_advertise_subnet(zevpn, vlan_if, 1);
11396 else
11397 zevpn_advertise_subnet(zevpn, vlan_if, 0);
11398
11399 stream_failure:
11400 return;
11401 }
11402
11403 /*
11404 * Handle message from client to enable/disable advertisement of g/w macip
11405 * routes
11406 */
11407 void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
11408 {
11409 struct stream *s;
11410 int advertise;
11411 vni_t vni = 0;
11412 zebra_evpn_t *zevpn = NULL;
11413 struct interface *ifp = NULL;
11414
11415 if (!EVPN_ENABLED(zvrf)) {
11416 zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
11417 zvrf_id(zvrf));
11418 return;
11419 }
11420
11421 s = msg;
11422 STREAM_GETC(s, advertise);
11423 STREAM_GETL(s, vni);
11424
11425 if (!vni) {
11426 if (IS_ZEBRA_DEBUG_VXLAN)
11427 zlog_debug("EVPN gateway macip Adv %s, currently %s",
11428 advertise ? "enabled" : "disabled",
11429 advertise_gw_macip_enabled(NULL)
11430 ? "enabled"
11431 : "disabled");
11432
11433 if (zvrf->advertise_gw_macip == advertise)
11434 return;
11435
11436 zvrf->advertise_gw_macip = advertise;
11437
11438 if (advertise_gw_macip_enabled(zevpn))
11439 hash_iterate(zvrf->evpn_table,
11440 zevpn_gw_macip_add_for_evpn_hash, NULL);
11441 else
11442 hash_iterate(zvrf->evpn_table,
11443 zevpn_gw_macip_del_for_evpn_hash, NULL);
11444
11445 } else {
11446 struct zebra_if *zif = NULL;
11447 struct zebra_l2info_vxlan zl2_info;
11448 struct interface *vlan_if = NULL;
11449 struct interface *vrr_if = NULL;
11450
11451 zevpn = zevpn_lookup(vni);
11452 if (!zevpn)
11453 return;
11454
11455 if (IS_ZEBRA_DEBUG_VXLAN)
11456 zlog_debug(
11457 "EVPN gateway macip Adv %s on VNI %d , currently %s",
11458 advertise ? "enabled" : "disabled", vni,
11459 advertise_gw_macip_enabled(zevpn) ? "enabled"
11460 : "disabled");
11461
11462 if (zevpn->advertise_gw_macip == advertise)
11463 return;
11464
11465 zevpn->advertise_gw_macip = advertise;
11466
11467 ifp = zevpn->vxlan_if;
11468 if (!ifp)
11469 return;
11470
11471 zif = ifp->info;
11472
11473 /* If down or not mapped to a bridge, we're done. */
11474 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
11475 return;
11476
11477 zl2_info = zif->l2info.vxl;
11478
11479 vlan_if = zevpn_map_to_svi(zl2_info.access_vlan,
11480 zif->brslave_info.br_if);
11481 if (!vlan_if)
11482 return;
11483
11484 if (advertise_gw_macip_enabled(zevpn)) {
11485 /* Add primary SVI MAC-IP */
11486 zevpn_add_macip_for_intf(vlan_if, zevpn);
11487
11488 /* Add VRR MAC-IP - if any*/
11489 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
11490 if (vrr_if)
11491 zevpn_add_macip_for_intf(vrr_if, zevpn);
11492 } else {
11493 /* Del primary MAC-IP */
11494 zevpn_del_macip_for_intf(vlan_if, zevpn);
11495
11496 /* Del VRR MAC-IP - if any*/
11497 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
11498 if (vrr_if)
11499 zevpn_del_macip_for_intf(vrr_if, zevpn);
11500 }
11501 }
11502
11503 stream_failure:
11504 return;
11505 }
11506
11507
11508 /*
11509 * Handle message from client to learn (or stop learning) about VNIs and MACs.
11510 * When enabled, the VNI hash table will be built and MAC FDB table read;
11511 * when disabled, the entries should be deleted and remote VTEPs and MACs
11512 * uninstalled from the kernel.
11513 * This also informs the setting for BUM handling at the time this change
11514 * occurs; it is relevant only when specifying "learn".
11515 */
11516 void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
11517 {
11518 struct stream *s = NULL;
11519 int advertise = 0;
11520 enum vxlan_flood_control flood_ctrl;
11521
11522 /* Mismatch between EVPN VRF and current VRF (should be prevented by
11523 * bgpd's cli) */
11524 if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
11525 return;
11526
11527 s = msg;
11528 STREAM_GETC(s, advertise);
11529 STREAM_GETC(s, flood_ctrl);
11530
11531 if (IS_ZEBRA_DEBUG_VXLAN)
11532 zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
11533 zvrf_name(zvrf), zvrf_id(zvrf),
11534 advertise ? "enabled" : "disabled",
11535 is_evpn_enabled() ? "enabled" : "disabled",
11536 flood_ctrl);
11537
11538 if (zvrf->advertise_all_vni == advertise)
11539 return;
11540
11541 zvrf->advertise_all_vni = advertise;
11542 if (EVPN_ENABLED(zvrf)) {
11543 zrouter.evpn_vrf = zvrf;
11544
11545 /* Note BUM handling */
11546 zvrf->vxlan_flood_ctrl = flood_ctrl;
11547
11548 /* Replay all ESs */
11549 zebra_evpn_es_send_all_to_client(true /* add */);
11550
11551 /* Build EVPN hash table and inform BGP. */
11552 zevpn_build_hash_table();
11553
11554 /* Add all SVI (L3 GW) MACs to BGP*/
11555 hash_iterate(zvrf->evpn_table, zevpn_gw_macip_add_for_evpn_hash,
11556 NULL);
11557
11558 /* Read the MAC FDB */
11559 macfdb_read(zvrf->zns);
11560
11561 /* Read neighbors */
11562 neigh_read(zvrf->zns);
11563 } else {
11564 /* Cleanup VTEPs for all EVPNs - uninstall from
11565 * kernel and free entries.
11566 */
11567 hash_iterate(zvrf->evpn_table, zevpn_cleanup_all, zvrf);
11568
11569 /* Delete all ESs in BGP */
11570 zebra_evpn_es_send_all_to_client(false /* add */);
11571
11572 /* cleanup all l3vnis */
11573 hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
11574
11575 /* Mark as "no EVPN VRF" */
11576 zrouter.evpn_vrf = NULL;
11577 }
11578
11579 stream_failure:
11580 return;
11581 }
11582
11583 /*
11584 * Allocate EVPN hash table for this VRF and do other initialization.
11585 * NOTE: Currently supported only for default VRF.
11586 */
11587 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
11588 {
11589 if (!zvrf)
11590 return;
11591 zvrf->evpn_table = hash_create(evpn_hash_keymake, vni_hash_cmp,
11592 "Zebra VRF EVPN Table");
11593 zvrf->vxlan_sg_table = hash_create(zebra_vxlan_sg_hash_key_make,
11594 zebra_vxlan_sg_hash_eq, "Zebra VxLAN SG Table");
11595 }
11596
11597 /* Cleanup EVPN info, but don't free the table. */
11598 void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
11599 {
11600 struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn();
11601
11602 if (!zvrf)
11603 return;
11604 hash_iterate(zvrf->evpn_table, zevpn_cleanup_all, zvrf);
11605 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_cleanup, NULL);
11606
11607 if (zvrf == evpn_zvrf)
11608 zebra_evpn_es_cleanup();
11609 }
11610
11611 /* Close all EVPN handling */
11612 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
11613 {
11614 if (!zvrf)
11615 return;
11616 hash_iterate(zvrf->evpn_table, zevpn_cleanup_all, zvrf);
11617 hash_free(zvrf->evpn_table);
11618 }
11619
11620 /* init the l3vni table */
11621 void zebra_vxlan_init(void)
11622 {
11623 zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
11624 "Zebra VRF L3 VNI table");
11625 zrouter.evpn_vrf = NULL;
11626 zebra_evpn_mh_init();
11627 }
11628
11629 /* free l3vni table */
11630 void zebra_vxlan_disable(void)
11631 {
11632 hash_free(zrouter.l3vni_table);
11633 zebra_evpn_mh_terminate();
11634 }
11635
11636 /* get the l3vni svi ifindex */
11637 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
11638 {
11639 zebra_l3vni_t *zl3vni = NULL;
11640
11641 zl3vni = zl3vni_from_vrf(vrf_id);
11642 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
11643 return 0;
11644
11645 return zl3vni->svi_if->ifindex;
11646 }
11647
11648 static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
11649 {
11650 struct zebra_vrf *zvrf = NULL;
11651 zebra_neigh_t *nbr = NULL;
11652 zebra_evpn_t *zevpn = NULL;
11653 char buf1[INET6_ADDRSTRLEN];
11654 char buf2[ETHER_ADDR_STRLEN];
11655
11656 nbr = THREAD_ARG(t);
11657
11658 /* since this is asynchronous we need sanity checks*/
11659 zvrf = vrf_info_lookup(nbr->zevpn->vrf_id);
11660 if (!zvrf)
11661 return 0;
11662
11663 zevpn = zevpn_lookup(nbr->zevpn->vni);
11664 if (!zevpn)
11665 return 0;
11666
11667 nbr = zevpn_neigh_lookup(zevpn, &nbr->ip);
11668 if (!nbr)
11669 return 0;
11670
11671 if (IS_ZEBRA_DEBUG_VXLAN)
11672 zlog_debug(
11673 "%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
11674 __func__,
11675 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)),
11676 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)), nbr->flags,
11677 nbr->dad_count, zevpn->vni);
11678
11679 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
11680 nbr->dad_count = 0;
11681 nbr->detect_start_time.tv_sec = 0;
11682 nbr->detect_start_time.tv_usec = 0;
11683 nbr->dad_dup_detect_time = 0;
11684 nbr->dad_ip_auto_recovery_timer = NULL;
11685 ZEBRA_NEIGH_SET_ACTIVE(nbr);
11686
11687 /* Send to BGP */
11688 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
11689 zevpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip, &nbr->emac,
11690 nbr->mac, nbr->flags, nbr->loc_seq);
11691 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
11692 zevpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
11693 }
11694
11695 return 0;
11696 }
11697
11698 static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
11699 {
11700 struct zebra_vrf *zvrf = NULL;
11701 zebra_mac_t *mac = NULL;
11702 zebra_evpn_t *zevpn = NULL;
11703 struct listnode *node = NULL;
11704 zebra_neigh_t *nbr = NULL;
11705 char buf[ETHER_ADDR_STRLEN];
11706
11707 mac = THREAD_ARG(t);
11708
11709 /* since this is asynchronous we need sanity checks*/
11710 zvrf = vrf_info_lookup(mac->zevpn->vrf_id);
11711 if (!zvrf)
11712 return 0;
11713
11714 zevpn = zevpn_lookup(mac->zevpn->vni);
11715 if (!zevpn)
11716 return 0;
11717
11718 mac = zevpn_mac_lookup(zevpn, &mac->macaddr);
11719 if (!mac)
11720 return 0;
11721
11722 if (IS_ZEBRA_DEBUG_VXLAN)
11723 zlog_debug(
11724 "%s: duplicate addr mac %s flags 0x%x learn count %u host count %u auto recovery expired",
11725 __func__,
11726 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
11727 mac->flags, mac->dad_count, listcount(mac->neigh_list));
11728
11729 /* Remove all IPs as duplicate associcated with this MAC */
11730 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
11731 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
11732 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
11733 ZEBRA_NEIGH_SET_INACTIVE(nbr);
11734 else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
11735 zevpn_rem_neigh_install(zevpn, nbr,
11736 false /*was_static*/);
11737 }
11738
11739 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
11740 nbr->dad_count = 0;
11741 nbr->detect_start_time.tv_sec = 0;
11742 nbr->dad_dup_detect_time = 0;
11743 }
11744
11745 UNSET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
11746 mac->dad_count = 0;
11747 mac->detect_start_time.tv_sec = 0;
11748 mac->detect_start_time.tv_usec = 0;
11749 mac->dad_dup_detect_time = 0;
11750 mac->dad_mac_auto_recovery_timer = NULL;
11751
11752 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
11753 /* Inform to BGP */
11754 if (zevpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
11755 mac->flags, mac->loc_seq, mac->es))
11756 return -1;
11757
11758 /* Process all neighbors associated with this MAC. */
11759 zevpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
11760 0 /*es_change*/);
11761
11762 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
11763 zevpn_process_neigh_on_remote_mac_add(zevpn, mac);
11764
11765 /* Install the entry. */
11766 zevpn_rem_mac_install(zevpn, mac, false /* was_static */);
11767 }
11768
11769 return 0;
11770 }
11771
11772 /************************** vxlan SG cache management ************************/
11773 /* Inform PIM about the mcast group */
11774 static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
11775 struct prefix_sg *sg,
11776 char *sg_str, uint16_t cmd)
11777 {
11778 struct zserv *client = NULL;
11779 struct stream *s = NULL;
11780
11781 client = zserv_find_client(ZEBRA_ROUTE_PIM, 0);
11782 if (!client)
11783 return 0;
11784
11785 if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
11786 return 0;
11787
11788 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
11789
11790 zclient_create_header(s, cmd, VRF_DEFAULT);
11791 stream_putl(s, IPV4_MAX_BYTELEN);
11792 stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
11793 stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
11794
11795 /* Write packet size. */
11796 stream_putw_at(s, 0, stream_get_endp(s));
11797
11798 if (IS_ZEBRA_DEBUG_VXLAN)
11799 zlog_debug(
11800 "Send %s %s to %s",
11801 (cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", sg_str,
11802 zebra_route_string(client->proto));
11803
11804 if (cmd == ZEBRA_VXLAN_SG_ADD)
11805 client->vxlan_sg_add_cnt++;
11806 else
11807 client->vxlan_sg_del_cnt++;
11808
11809 return zserv_send_message(client, s);
11810 }
11811
11812 static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
11813 {
11814 const zebra_vxlan_sg_t *vxlan_sg = p;
11815
11816 return (jhash_2words(vxlan_sg->sg.src.s_addr,
11817 vxlan_sg->sg.grp.s_addr, 0));
11818 }
11819
11820 static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
11821 {
11822 const zebra_vxlan_sg_t *sg1 = p1;
11823 const zebra_vxlan_sg_t *sg2 = p2;
11824
11825 return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
11826 && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
11827 }
11828
11829 static zebra_vxlan_sg_t *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
11830 struct prefix_sg *sg)
11831 {
11832 zebra_vxlan_sg_t *vxlan_sg;
11833
11834 vxlan_sg = XCALLOC(MTYPE_ZVXLAN_SG, sizeof(*vxlan_sg));
11835
11836 vxlan_sg->zvrf = zvrf;
11837 vxlan_sg->sg = *sg;
11838 prefix_sg2str(sg, vxlan_sg->sg_str);
11839
11840 vxlan_sg = hash_get(zvrf->vxlan_sg_table, vxlan_sg, hash_alloc_intern);
11841
11842 if (IS_ZEBRA_DEBUG_VXLAN)
11843 zlog_debug("vxlan SG %s created", vxlan_sg->sg_str);
11844
11845 return vxlan_sg;
11846 }
11847
11848 static zebra_vxlan_sg_t *zebra_vxlan_sg_find(struct zebra_vrf *zvrf,
11849 struct prefix_sg *sg)
11850 {
11851 zebra_vxlan_sg_t lookup;
11852
11853 lookup.sg = *sg;
11854 return hash_lookup(zvrf->vxlan_sg_table, &lookup);
11855 }
11856
11857 static zebra_vxlan_sg_t *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
11858 struct prefix_sg *sg)
11859 {
11860 zebra_vxlan_sg_t *vxlan_sg;
11861 zebra_vxlan_sg_t *parent = NULL;
11862 struct in_addr sip;
11863
11864 vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
11865 if (vxlan_sg)
11866 return vxlan_sg;
11867
11868 /* create a *G entry for every BUM group implicitly -
11869 * 1. The SG entry is used by pimd to setup the vxlan-origination-mroute
11870 * 2. the XG entry is used by pimd to setup the
11871 * vxlan-termination-mroute
11872 */
11873 if (sg->src.s_addr != INADDR_ANY) {
11874 memset(&sip, 0, sizeof(sip));
11875 parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
11876 if (!parent)
11877 return NULL;
11878 }
11879
11880 vxlan_sg = zebra_vxlan_sg_new(zvrf, sg);
11881 if (!vxlan_sg) {
11882 if (parent)
11883 zebra_vxlan_sg_do_deref(zvrf, sip, sg->grp);
11884 return vxlan_sg;
11885 }
11886
11887 zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
11888 ZEBRA_VXLAN_SG_ADD);
11889
11890 return vxlan_sg;
11891 }
11892
11893 static void zebra_vxlan_sg_del(zebra_vxlan_sg_t *vxlan_sg)
11894 {
11895 struct in_addr sip;
11896 struct zebra_vrf *zvrf;
11897
11898 zvrf = vrf_info_lookup(VRF_DEFAULT);
11899 if (!zvrf)
11900 return;
11901
11902 /* On SG entry deletion remove the reference to its parent XG
11903 * entry
11904 */
11905 if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
11906 memset(&sip, 0, sizeof(sip));
11907 zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
11908 }
11909
11910 zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
11911 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
11912
11913 hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
11914
11915 if (IS_ZEBRA_DEBUG_VXLAN)
11916 zlog_debug("VXLAN SG %s deleted", vxlan_sg->sg_str);
11917
11918 XFREE(MTYPE_ZVXLAN_SG, vxlan_sg);
11919 }
11920
11921 static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
11922 struct in_addr sip, struct in_addr mcast_grp)
11923 {
11924 zebra_vxlan_sg_t *vxlan_sg;
11925 struct prefix_sg sg;
11926
11927 sg.family = AF_INET;
11928 sg.prefixlen = IPV4_MAX_BYTELEN;
11929 sg.src = sip;
11930 sg.grp = mcast_grp;
11931 vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
11932 if (!vxlan_sg)
11933 return;
11934
11935 if (vxlan_sg->ref_cnt)
11936 --vxlan_sg->ref_cnt;
11937
11938 if (!vxlan_sg->ref_cnt)
11939 zebra_vxlan_sg_del(vxlan_sg);
11940 }
11941
11942 static zebra_vxlan_sg_t *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
11943 struct in_addr sip, struct in_addr mcast_grp)
11944 {
11945 zebra_vxlan_sg_t *vxlan_sg;
11946 struct prefix_sg sg;
11947
11948 sg.family = AF_INET;
11949 sg.prefixlen = IPV4_MAX_BYTELEN;
11950 sg.src = sip;
11951 sg.grp = mcast_grp;
11952 vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
11953 if (vxlan_sg)
11954 ++vxlan_sg->ref_cnt;
11955
11956 return vxlan_sg;
11957 }
11958
11959 static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
11960 struct in_addr mcast_grp)
11961 {
11962 struct zebra_vrf *zvrf;
11963
11964 if (local_vtep_ip.s_addr == INADDR_ANY
11965 || mcast_grp.s_addr == INADDR_ANY)
11966 return;
11967
11968 zvrf = vrf_info_lookup(VRF_DEFAULT);
11969 if (!zvrf)
11970 return;
11971
11972 zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
11973 }
11974
11975 static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
11976 struct in_addr mcast_grp)
11977 {
11978 struct zebra_vrf *zvrf;
11979
11980 if (local_vtep_ip.s_addr == INADDR_ANY
11981 || mcast_grp.s_addr == INADDR_ANY)
11982 return;
11983
11984 zvrf = vrf_info_lookup(VRF_DEFAULT);
11985 if (!zvrf)
11986 return;
11987 zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
11988 }
11989
11990 static void zebra_vxlan_sg_cleanup(struct hash_bucket *backet, void *arg)
11991 {
11992 zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data;
11993
11994 zebra_vxlan_sg_del(vxlan_sg);
11995 }
11996
11997 static void zebra_vxlan_sg_replay_send(struct hash_bucket *backet, void *arg)
11998 {
11999 zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data;
12000
12001 zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
12002 vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
12003 }
12004
12005 /* Handle message from client to replay vxlan SG entries */
12006 void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
12007 {
12008 if (IS_ZEBRA_DEBUG_VXLAN)
12009 zlog_debug("VxLAN SG updates to PIM, start");
12010
12011 SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
12012
12013 if (!EVPN_ENABLED(zvrf)) {
12014 if (IS_ZEBRA_DEBUG_VXLAN)
12015 zlog_debug("VxLAN SG replay request on unexpected vrf %d",
12016 zvrf->vrf->vrf_id);
12017 return;
12018 }
12019
12020 hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
12021 }
12022
12023 /************************** EVPN BGP config management ************************/
12024 /* Notify Local MACs to the clienti, skips GW MAC */
12025 static void zevpn_send_mac_hash_entry_to_client(struct hash_bucket *bucket,
12026 void *arg)
12027 {
12028 struct mac_walk_ctx *wctx = arg;
12029 zebra_mac_t *zmac = bucket->data;
12030
12031 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_DEF_GW))
12032 return;
12033
12034 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL))
12035 zevpn_mac_send_add_to_client(wctx->zevpn->vni, &zmac->macaddr,
12036 zmac->flags, zmac->loc_seq, zmac->es);
12037 }
12038
12039 /* Iterator to Notify Local MACs of a EVPN */
12040 static void zevpn_send_mac_to_client(zebra_evpn_t *zevpn)
12041 {
12042 struct mac_walk_ctx wctx;
12043
12044 if (!zevpn->mac_table)
12045 return;
12046
12047 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
12048 wctx.zevpn = zevpn;
12049
12050 hash_iterate(zevpn->mac_table, zevpn_send_mac_hash_entry_to_client,
12051 &wctx);
12052 }
12053
12054 /* Notify Neighbor entries to the Client, skips the GW entry */
12055 static void zevpn_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
12056 void *arg)
12057 {
12058 struct mac_walk_ctx *wctx = arg;
12059 zebra_neigh_t *zn = bucket->data;
12060 zebra_mac_t *zmac = NULL;
12061
12062 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
12063 return;
12064
12065 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL) &&
12066 IS_ZEBRA_NEIGH_ACTIVE(zn)) {
12067 zmac = zevpn_mac_lookup(wctx->zevpn, &zn->emac);
12068 if (!zmac)
12069 return;
12070
12071 zevpn_neigh_send_add_to_client(wctx->zevpn->vni, &zn->ip,
12072 &zn->emac, zn->mac, zn->flags,
12073 zn->loc_seq);
12074 }
12075 }
12076
12077 /* Iterator of a specific EVPN */
12078 static void zevpn_send_neigh_to_client(zebra_evpn_t *zevpn)
12079 {
12080 struct neigh_walk_ctx wctx;
12081
12082 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
12083 wctx.zevpn = zevpn;
12084
12085 hash_iterate(zevpn->neigh_table, zevpn_send_neigh_hash_entry_to_client,
12086 &wctx);
12087 }
12088
12089 static void zevpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt)
12090 {
12091 zebra_evpn_t *zevpn = NULL;
12092
12093 zevpn = (zebra_evpn_t *)bucket->data;
12094 zevpn->advertise_gw_macip = 0;
12095 zevpn->advertise_svi_macip = 0;
12096 zevpn->advertise_subnet = 0;
12097
12098 zevpn_neigh_del_all(zevpn, 1, 0,
12099 DEL_REMOTE_NEIGH | DEL_REMOTE_NEIGH_FROM_VTEP);
12100 zevpn_mac_del_all(zevpn, 1, 0,
12101 DEL_REMOTE_MAC | DEL_REMOTE_MAC_FROM_VTEP);
12102 zevpn_vtep_del_all(zevpn, 1);
12103 }
12104
12105 /* Cleanup EVPN configuration of a specific VRF */
12106 static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
12107 {
12108 zebra_l3vni_t *zl3vni = NULL;
12109
12110 zvrf->advertise_all_vni = 0;
12111 zvrf->advertise_gw_macip = 0;
12112 zvrf->advertise_svi_macip = 0;
12113 zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
12114
12115 hash_iterate(zvrf->evpn_table, zevpn_cfg_cleanup, NULL);
12116
12117 if (zvrf->l3vni)
12118 zl3vni = zl3vni_lookup(zvrf->l3vni);
12119 if (zl3vni) {
12120 /* delete and uninstall all rmacs */
12121 hash_iterate(zl3vni->rmac_table, zl3vni_del_rmac_hash_entry,
12122 zl3vni);
12123 /* delete and uninstall all next-hops */
12124 hash_iterate(zl3vni->nh_table, zl3vni_del_nh_hash_entry,
12125 zl3vni);
12126 }
12127 }
12128
12129 /* Cleanup BGP EVPN configuration upon client disconnect */
12130 static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
12131 {
12132 struct vrf *vrf;
12133 struct zebra_vrf *zvrf;
12134
12135 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
12136 zvrf = vrf->info;
12137 if (zvrf)
12138 zebra_evpn_vrf_cfg_cleanup(zvrf);
12139 }
12140
12141 return 0;
12142 }
12143
12144 static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
12145 {
12146 struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
12147
12148 if (zvrf && CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
12149 if (IS_ZEBRA_DEBUG_VXLAN)
12150 zlog_debug("VxLAN SG updates to PIM, stop");
12151 UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
12152 }
12153
12154 return 0;
12155 }
12156
12157 static int zebra_evpn_cfg_clean_up(struct zserv *client)
12158 {
12159 if (client->proto == ZEBRA_ROUTE_BGP)
12160 return zebra_evpn_bgp_cfg_clean_up(client);
12161
12162 if (client->proto == ZEBRA_ROUTE_PIM)
12163 return zebra_evpn_pim_cfg_clean_up(client);
12164
12165 return 0;
12166 }
12167
12168 /*
12169 * Handle results for vxlan dataplane operations.
12170 */
12171 extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx)
12172 {
12173 /* TODO -- anything other than freeing the context? */
12174 dplane_ctx_fini(&ctx);
12175 }
12176
12177 /* Cleanup BGP EVPN configuration upon client disconnect */
12178 extern void zebra_evpn_init(void)
12179 {
12180 hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
12181 }