]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_evpn_neigh.c
Merge pull request #6738 from deastoe/frr-reload-log-level
[mirror_frr.git] / zebra / zebra_evpn_neigh.c
1 /*
2 * Zebra EVPN Neighbor 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 "interface.h"
27 #include "jhash.h"
28 #include "memory.h"
29 #include "prefix.h"
30 #include "vlan.h"
31 #include "json.h"
32
33 #include "zebra/zserv.h"
34 #include "zebra/debug.h"
35 #include "zebra/zebra_router.h"
36 #include "zebra/rt.h"
37 #include "zebra/zebra_memory.h"
38 #include "zebra/zebra_errors.h"
39 #include "zebra/zebra_vrf.h"
40 #include "zebra/zebra_evpn.h"
41 #include "zebra/zebra_evpn_mh.h"
42 #include "zebra/zebra_evpn_neigh.h"
43 #include "zebra/zebra_evpn_mac.h"
44
45 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "EVI Neighbor");
46
47 /*
48 * Make hash key for neighbors.
49 */
50 static unsigned int neigh_hash_keymake(const void *p)
51 {
52 const zebra_neigh_t *n = p;
53 const struct ipaddr *ip = &n->ip;
54
55 if (IS_IPADDR_V4(ip))
56 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
57
58 return jhash2(ip->ipaddr_v6.s6_addr32,
59 array_size(ip->ipaddr_v6.s6_addr32), 0);
60 }
61
62 /*
63 * Compare two neighbor hash structures.
64 */
65 static bool neigh_cmp(const void *p1, const void *p2)
66 {
67 const zebra_neigh_t *n1 = p1;
68 const zebra_neigh_t *n2 = p2;
69
70 if (n1 == NULL && n2 == NULL)
71 return true;
72
73 if (n1 == NULL || n2 == NULL)
74 return false;
75
76 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
77 }
78
79 int neigh_list_cmp(void *p1, void *p2)
80 {
81 const zebra_neigh_t *n1 = p1;
82 const zebra_neigh_t *n2 = p2;
83
84 return memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr));
85 }
86
87 struct hash *zebra_neigh_db_create(const char *desc)
88 {
89 return hash_create(neigh_hash_keymake, neigh_cmp, desc);
90 }
91
92 uint32_t num_dup_detected_neighs(zebra_evpn_t *zevpn)
93 {
94 unsigned int i;
95 uint32_t num_neighs = 0;
96 struct hash *hash;
97 struct hash_bucket *hb;
98 zebra_neigh_t *nbr;
99
100 hash = zevpn->neigh_table;
101 if (!hash)
102 return num_neighs;
103 for (i = 0; i < hash->size; i++) {
104 for (hb = hash->index[i]; hb; hb = hb->next) {
105 nbr = (zebra_neigh_t *)hb->data;
106 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
107 num_neighs++;
108 }
109 }
110
111 return num_neighs;
112 }
113
114 /*
115 * Helper function to determine maximum width of neighbor IP address for
116 * display - just because we're dealing with IPv6 addresses that can
117 * widely vary.
118 */
119 void zebra_evpn_find_neigh_addr_width(struct hash_bucket *bucket, void *ctxt)
120 {
121 zebra_neigh_t *n;
122 char buf[INET6_ADDRSTRLEN];
123 struct neigh_walk_ctx *wctx = ctxt;
124 int width;
125
126 n = (zebra_neigh_t *)bucket->data;
127
128 ipaddr2str(&n->ip, buf, sizeof(buf));
129 width = strlen(buf);
130 if (width > wctx->addr_width)
131 wctx->addr_width = width;
132 }
133
134 /*
135 * Count of remote neighbors referencing this MAC.
136 */
137 int remote_neigh_count(zebra_mac_t *zmac)
138 {
139 zebra_neigh_t *n = NULL;
140 struct listnode *node = NULL;
141 int count = 0;
142
143 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
144 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
145 count++;
146 }
147
148 return count;
149 }
150
151 /*
152 * Install remote neighbor into the kernel.
153 */
154 int zebra_evpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n,
155 bool was_static)
156 {
157 struct interface *vlan_if;
158 int flags;
159 int ret = 0;
160
161 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
162 return 0;
163
164 vlan_if = zevpn_map_to_svi(zevpn);
165 if (!vlan_if)
166 return -1;
167
168 flags = DPLANE_NTF_EXT_LEARNED;
169 if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
170 flags |= DPLANE_NTF_ROUTER;
171 ZEBRA_NEIGH_SET_ACTIVE(n);
172
173 dplane_rem_neigh_add(vlan_if, &n->ip, &n->emac, flags, was_static);
174
175 return ret;
176 }
177
178 /*
179 * Install neighbor hash entry - called upon access VLAN change.
180 */
181 void zebra_evpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt)
182 {
183 zebra_neigh_t *n;
184 struct neigh_walk_ctx *wctx = ctxt;
185
186 n = (zebra_neigh_t *)bucket->data;
187
188 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
189 zebra_evpn_rem_neigh_install(wctx->zevpn, n,
190 false /*was_static*/);
191 }
192
193 /*
194 * Callback to allocate neighbor hash entry.
195 */
196 static void *zebra_evpn_neigh_alloc(void *p)
197 {
198 const zebra_neigh_t *tmp_n = p;
199 zebra_neigh_t *n;
200
201 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
202 *n = *tmp_n;
203
204 return ((void *)n);
205 }
206
207 static void zebra_evpn_local_neigh_ref_mac(zebra_neigh_t *n,
208 struct ethaddr *macaddr,
209 zebra_mac_t *mac,
210 bool send_mac_update)
211 {
212 char macbuf[ETHER_ADDR_STRLEN];
213 char ipbuf[INET6_ADDRSTRLEN];
214 bool old_static;
215 bool new_static;
216
217 memcpy(&n->emac, macaddr, ETH_ALEN);
218 n->mac = mac;
219
220 /* Link to new MAC */
221 if (!mac)
222 return;
223
224 listnode_add_sort(mac->neigh_list, n);
225 if (n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) {
226 old_static = zebra_evpn_mac_is_static(mac);
227 ++mac->sync_neigh_cnt;
228 new_static = zebra_evpn_mac_is_static(mac);
229 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
230 zlog_debug(
231 "sync-neigh ref mac vni %u ip %s mac %s ref %d",
232 n->zevpn->vni,
233 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
234 prefix_mac2str(&n->emac, macbuf,
235 sizeof(macbuf)),
236 mac->sync_neigh_cnt);
237 if ((old_static != new_static) && send_mac_update)
238 /* program the local mac in the kernel */
239 zebra_evpn_sync_mac_dp_install(
240 mac, false /*set_inactive*/,
241 false /*force_clear_static*/, __func__);
242 }
243 }
244
245 /* sync-path that is active on an ES peer */
246 static void zebra_evpn_sync_neigh_dp_install(zebra_neigh_t *n,
247 bool set_inactive,
248 bool force_clear_static,
249 const char *caller)
250 {
251 char macbuf[ETHER_ADDR_STRLEN];
252 char ipbuf[INET6_ADDRSTRLEN];
253 struct zebra_ns *zns;
254 struct interface *ifp;
255 bool set_static;
256 bool set_router;
257
258 zns = zebra_ns_lookup(NS_DEFAULT);
259 ifp = if_lookup_by_index_per_ns(zns, n->ifindex);
260 if (!ifp) {
261 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
262 zlog_debug(
263 "%s: dp-install sync-neigh vni %u ip %s mac %s if %d f 0x%x skipped",
264 caller, n->zevpn->vni,
265 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
266 prefix_mac2str(&n->emac, macbuf,
267 sizeof(macbuf)),
268 n->ifindex, n->flags);
269 return;
270 }
271
272 if (force_clear_static)
273 set_static = false;
274 else
275 set_static = zebra_evpn_neigh_is_static(n);
276
277 set_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
278
279 /* XXX - this will change post integration with the new kernel */
280 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
281 set_inactive = true;
282
283 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
284 zlog_debug(
285 "%s: dp-install sync-neigh vni %u ip %s mac %s if %s(%d) f 0x%x%s%s%s",
286 caller, n->zevpn->vni,
287 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
288 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
289 ifp->name, n->ifindex, n->flags,
290 set_router ? " router" : "",
291 set_static ? " static" : "",
292 set_inactive ? " inactive" : "");
293 dplane_local_neigh_add(ifp, &n->ip, &n->emac, set_router, set_static,
294 set_inactive);
295 }
296
297 /*
298 * Inform BGP about local neighbor addition.
299 */
300 int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
301 struct ethaddr *macaddr,
302 zebra_mac_t *zmac, uint32_t neigh_flags,
303 uint32_t seq)
304 {
305 uint8_t flags = 0;
306
307 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
308 /* host reachability has not been verified locally */
309
310 /* if no ES peer is claiming reachability we can't advertise
311 * the entry
312 */
313 if (!CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
314 return 0;
315
316 /* ES peers are claiming reachability; we will
317 * advertise the entry but with a proxy flag
318 */
319 SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT);
320 }
321
322 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
323 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
324 /* Set router flag (R-bit) based on local neigh entry add */
325 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
326 SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
327 if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_SVI_IP))
328 SET_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP);
329
330 return zebra_evpn_macip_send_msg_to_client(
331 vni, macaddr, ip, flags, seq, ZEBRA_NEIGH_ACTIVE,
332 zmac ? zmac->es : NULL, ZEBRA_MACIP_ADD);
333 }
334
335 /*
336 * Inform BGP about local neighbor deletion.
337 */
338 int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
339 struct ethaddr *macaddr, uint32_t flags,
340 int state, bool force)
341 {
342 if (!force) {
343 if (CHECK_FLAG(flags, ZEBRA_NEIGH_LOCAL_INACTIVE)
344 && !CHECK_FLAG(flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
345 /* the neigh was not advertised - nothing to delete */
346 return 0;
347 }
348
349 return zebra_evpn_macip_send_msg_to_client(
350 vni, macaddr, ip, flags, 0, state, NULL, ZEBRA_MACIP_DEL);
351 }
352
353 static void zebra_evpn_neigh_send_add_del_to_client(zebra_neigh_t *n,
354 bool old_bgp_ready,
355 bool new_bgp_ready)
356 {
357 if (new_bgp_ready)
358 zebra_evpn_neigh_send_add_to_client(n->zevpn->vni, &n->ip,
359 &n->emac, n->mac, n->flags,
360 n->loc_seq);
361 else if (old_bgp_ready)
362 zebra_evpn_neigh_send_del_to_client(n->zevpn->vni, &n->ip,
363 &n->emac, n->flags,
364 n->state, true /*force*/);
365 }
366
367 /* if the static flag associated with the neigh changes we need
368 * to update the sync-neigh references against the MAC
369 * and inform the dataplane about the static flag changes.
370 */
371 void zebra_evpn_sync_neigh_static_chg(zebra_neigh_t *n, bool old_n_static,
372 bool new_n_static, bool defer_n_dp,
373 bool defer_mac_dp, const char *caller)
374 {
375 zebra_mac_t *mac = n->mac;
376 bool old_mac_static;
377 bool new_mac_static;
378 char macbuf[ETHER_ADDR_STRLEN];
379 char ipbuf[INET6_ADDRSTRLEN];
380
381 if (old_n_static == new_n_static)
382 return;
383
384 /* update the neigh sync references in the dataplane. if
385 * the neigh is in the middle of updates the caller can
386 * request for a defer
387 */
388 if (!defer_n_dp)
389 zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
390 false /* force_clear_static */,
391 __func__);
392
393 if (!mac)
394 return;
395
396 /* update the mac sync ref cnt */
397 old_mac_static = zebra_evpn_mac_is_static(mac);
398 if (new_n_static) {
399 ++mac->sync_neigh_cnt;
400 } else if (old_n_static) {
401 if (mac->sync_neigh_cnt)
402 --mac->sync_neigh_cnt;
403 }
404 new_mac_static = zebra_evpn_mac_is_static(mac);
405
406 /* update the mac sync references in the dataplane */
407 if ((old_mac_static != new_mac_static) && !defer_mac_dp)
408 zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
409 false /* force_clear_static */,
410 __func__);
411
412 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
413 zlog_debug(
414 "sync-neigh ref-chg vni %u ip %s mac %s f 0x%x %d%s%s%s%s by %s",
415 n->zevpn->vni, ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
416 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
417 n->flags, mac->sync_neigh_cnt,
418 old_n_static ? " old_n_static" : "",
419 new_n_static ? " new_n_static" : "",
420 old_mac_static ? " old_mac_static" : "",
421 new_mac_static ? " new_mac_static" : "", caller);
422 }
423
424 /* Neigh hold timer is used to age out peer-active flag.
425 *
426 * During this wait time we expect the dataplane component or an
427 * external neighmgr daemon to probe existing hosts to independently
428 * establish their presence on the ES.
429 */
430 static int zebra_evpn_neigh_hold_exp_cb(struct thread *t)
431 {
432 zebra_neigh_t *n;
433 bool old_bgp_ready;
434 bool new_bgp_ready;
435 bool old_n_static;
436 bool new_n_static;
437 char macbuf[ETHER_ADDR_STRLEN];
438 char ipbuf[INET6_ADDRSTRLEN];
439
440 n = THREAD_ARG(t);
441 /* the purpose of the hold timer is to age out the peer-active
442 * flag
443 */
444 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
445 return 0;
446
447 old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
448 old_n_static = zebra_evpn_neigh_is_static(n);
449 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
450 new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
451 new_n_static = zebra_evpn_neigh_is_static(n);
452
453 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
454 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x hold expired",
455 n->zevpn->vni,
456 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
457 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
458 n->flags);
459
460 /* re-program the local neigh in the dataplane if the neigh is no
461 * longer static
462 */
463 if (old_n_static != new_n_static)
464 zebra_evpn_sync_neigh_static_chg(
465 n, old_n_static, new_n_static, false /*defer_n_dp*/,
466 false /*defer_mac_dp*/, __func__);
467
468 /* inform bgp if needed */
469 if (old_bgp_ready != new_bgp_ready)
470 zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
471 new_bgp_ready);
472
473 return 0;
474 }
475
476 static inline void zebra_evpn_neigh_start_hold_timer(zebra_neigh_t *n)
477 {
478 char macbuf[ETHER_ADDR_STRLEN];
479 char ipbuf[INET6_ADDRSTRLEN];
480
481 if (n->hold_timer)
482 return;
483
484 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
485 zlog_debug("sync-neigh vni %u ip %s mac %s 0x%x hold start",
486 n->zevpn->vni,
487 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
488 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
489 n->flags);
490 thread_add_timer(zrouter.master, zebra_evpn_neigh_hold_exp_cb, n,
491 zmh_info->neigh_hold_time, &n->hold_timer);
492 }
493
494 static void zebra_evpn_local_neigh_deref_mac(zebra_neigh_t *n,
495 bool send_mac_update)
496 {
497 zebra_mac_t *mac = n->mac;
498 zebra_evpn_t *zevpn = n->zevpn;
499 char macbuf[ETHER_ADDR_STRLEN];
500 char ipbuf[INET6_ADDRSTRLEN];
501 bool old_static;
502 bool new_static;
503
504 n->mac = NULL;
505 if (!mac)
506 return;
507
508 if ((n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) && mac->sync_neigh_cnt) {
509 old_static = zebra_evpn_mac_is_static(mac);
510 --mac->sync_neigh_cnt;
511 new_static = zebra_evpn_mac_is_static(mac);
512 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
513 zlog_debug(
514 "sync-neigh deref mac vni %u ip %s mac %s ref %d",
515 n->zevpn->vni,
516 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
517 prefix_mac2str(&n->emac, macbuf,
518 sizeof(macbuf)),
519 mac->sync_neigh_cnt);
520 if ((old_static != new_static) && send_mac_update)
521 /* program the local mac in the kernel */
522 zebra_evpn_sync_mac_dp_install(
523 mac, false /* set_inactive */,
524 false /* force_clear_static */, __func__);
525 }
526
527 listnode_delete(mac->neigh_list, n);
528 zebra_evpn_deref_ip2mac(zevpn, mac);
529 }
530
531 bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
532 struct ethaddr *macaddr, uint32_t seq)
533 {
534 char macbuf[ETHER_ADDR_STRLEN];
535 char ipbuf[INET6_ADDRSTRLEN];
536 uint32_t tmp_seq;
537
538 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
539 tmp_seq = n->loc_seq;
540 else
541 tmp_seq = n->rem_seq;
542
543 if (seq < tmp_seq) {
544 /* if the neigh was never advertised to bgp we must accept
545 * whatever sequence number bgp sends
546 * XXX - check with Vivek
547 */
548 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
549 && !zebra_evpn_neigh_is_ready_for_bgp(n)) {
550 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
551 zlog_debug(
552 "sync-macip accept vni %u mac %s IP %s lower seq %u f 0x%x",
553 zevpn->vni,
554 prefix_mac2str(macaddr, macbuf,
555 sizeof(macbuf)),
556 ipaddr2str(&n->ip, ipbuf,
557 sizeof(ipbuf)),
558 tmp_seq, n->flags);
559 return true;
560 }
561
562 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
563 zlog_debug(
564 "sync-macip ignore vni %u mac %s IP %s as existing has higher seq %u f 0x%x",
565 zevpn->vni,
566 prefix_mac2str(macaddr, macbuf, sizeof(macbuf)),
567 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
568 tmp_seq, n->flags);
569 return false;
570 }
571
572 return true;
573 }
574
575 /*
576 * Add neighbor entry.
577 */
578 static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn,
579 struct ipaddr *ip,
580 struct ethaddr *mac,
581 zebra_mac_t *zmac, uint32_t n_flags)
582 {
583 zebra_neigh_t tmp_n;
584 zebra_neigh_t *n = NULL;
585
586 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
587 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
588 n = hash_get(zevpn->neigh_table, &tmp_n, zebra_evpn_neigh_alloc);
589 assert(n);
590
591 n->state = ZEBRA_NEIGH_INACTIVE;
592 n->zevpn = zevpn;
593 n->dad_ip_auto_recovery_timer = NULL;
594 n->flags = n_flags;
595
596 if (!zmac)
597 zmac = zebra_evpn_mac_lookup(zevpn, mac);
598 zebra_evpn_local_neigh_ref_mac(n, mac, zmac,
599 false /* send_mac_update */);
600
601 return n;
602 }
603
604 /*
605 * Delete neighbor entry.
606 */
607 int zebra_evpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n)
608 {
609 zebra_neigh_t *tmp_n;
610
611 if (n->mac)
612 listnode_delete(n->mac->neigh_list, n);
613
614 /* Cancel auto recovery */
615 THREAD_OFF(n->dad_ip_auto_recovery_timer);
616
617 /* Free the VNI hash entry and allocated memory. */
618 tmp_n = hash_release(zevpn->neigh_table, n);
619 XFREE(MTYPE_NEIGH, tmp_n);
620
621 return 0;
622 }
623
624 void zebra_evpn_sync_neigh_del(zebra_neigh_t *n)
625 {
626 bool old_n_static;
627 bool new_n_static;
628 char macbuf[ETHER_ADDR_STRLEN];
629 char ipbuf[INET6_ADDRSTRLEN];
630
631 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
632 zlog_debug("sync-neigh del vni %u ip %s mac %s f 0x%x",
633 n->zevpn->vni,
634 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
635 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
636 n->flags);
637
638 old_n_static = zebra_evpn_neigh_is_static(n);
639 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
640 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
641 zebra_evpn_neigh_start_hold_timer(n);
642 new_n_static = zebra_evpn_neigh_is_static(n);
643
644 if (old_n_static != new_n_static)
645 zebra_evpn_sync_neigh_static_chg(
646 n, old_n_static, new_n_static, false /*defer-dp*/,
647 false /*defer_mac_dp*/, __func__);
648 }
649
650 zebra_neigh_t *
651 zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
652 uint16_t ipa_len, struct ipaddr *ipaddr,
653 uint8_t flags, uint32_t seq, esi_t *esi,
654 struct sync_mac_ip_ctx *ctx)
655 {
656 struct interface *ifp = NULL;
657 bool is_router;
658 zebra_mac_t *mac = ctx->mac;
659 uint32_t tmp_seq;
660 bool old_router = false;
661 bool old_bgp_ready = false;
662 bool new_bgp_ready;
663 bool inform_dataplane = false;
664 bool inform_bgp = false;
665 bool old_mac_static;
666 bool new_mac_static;
667 bool set_dp_inactive = false;
668 char macbuf[ETHER_ADDR_STRLEN];
669 char ipbuf[INET6_ADDRSTRLEN];
670 bool created;
671 ifindex_t ifindex = 0;
672
673 /* locate l3-svi */
674 ifp = zevpn_map_to_svi(zevpn);
675 if (ifp)
676 ifindex = ifp->ifindex;
677
678 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
679 old_mac_static = zebra_evpn_mac_is_static(mac);
680
681 if (!n) {
682 uint32_t n_flags = 0;
683
684 /* New neighbor - create */
685 SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL);
686 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
687 SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_PROXY);
688 else
689 SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
690 SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
691
692 n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr, mac,
693 n_flags);
694 n->ifindex = ifindex;
695 ZEBRA_NEIGH_SET_ACTIVE(n);
696
697 created = true;
698 inform_dataplane = true;
699 inform_bgp = true;
700 set_dp_inactive = true;
701 } else {
702 bool mac_change;
703 uint32_t old_flags = n->flags;
704 bool old_n_static;
705 bool new_n_static;
706
707 created = false;
708 old_n_static = zebra_evpn_neigh_is_static(n);
709 old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
710 old_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
711
712 mac_change = !!memcmp(&n->emac, &mac->macaddr, ETH_ALEN);
713
714 /* deref and clear old info */
715 if (mac_change) {
716 if (old_bgp_ready) {
717 zebra_evpn_neigh_send_del_to_client(
718 zevpn->vni, &n->ip, &n->emac, n->flags,
719 n->state, false /*force*/);
720 old_bgp_ready = false;
721 }
722 if (n->mac)
723 zebra_evpn_local_neigh_deref_mac(
724 n, false /*send_mac_update*/);
725 }
726 /* clear old fwd info */
727 n->rem_seq = 0;
728 n->r_vtep_ip.s_addr = 0;
729
730 /* setup new flags */
731 n->flags = 0;
732 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
733 /* retain activity flag if the neigh was
734 * previously local
735 */
736 if (old_flags & ZEBRA_NEIGH_LOCAL) {
737 n->flags |= (old_flags & ZEBRA_NEIGH_LOCAL_INACTIVE);
738 } else {
739 inform_dataplane = true;
740 set_dp_inactive = true;
741 n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
742 }
743
744 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
745 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
746 else
747 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
748
749 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
750 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
751 /* if the neigh was peer-active previously we
752 * need to keep the flag and start the
753 * holdtimer on it. the peer-active flag is
754 * cleared on holdtimer expiry.
755 */
756 if (CHECK_FLAG(old_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
757 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
758 zebra_evpn_neigh_start_hold_timer(n);
759 }
760 } else {
761 SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
762 /* stop hold timer if a peer has verified
763 * reachability
764 */
765 zebra_evpn_neigh_stop_hold_timer(n);
766 }
767 ZEBRA_NEIGH_SET_ACTIVE(n);
768
769 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH && (old_flags != n->flags))
770 zlog_debug(
771 "sync-neigh vni %u ip %s mac %s old_f 0x%x new_f 0x%x",
772 n->zevpn->vni,
773 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
774 prefix_mac2str(&n->emac, macbuf,
775 sizeof(macbuf)),
776 old_flags, n->flags);
777
778 new_n_static = zebra_evpn_neigh_is_static(n);
779 if (mac_change) {
780 set_dp_inactive = true;
781 n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
782 inform_dataplane = true;
783 zebra_evpn_local_neigh_ref_mac(
784 n, &mac->macaddr, mac,
785 false /*send_mac_update*/);
786 } else if (old_n_static != new_n_static) {
787 inform_dataplane = true;
788 /* if static flags have changed without a mac change
789 * we need to create the correct sync-refs against
790 * the existing mac
791 */
792 zebra_evpn_sync_neigh_static_chg(
793 n, old_n_static, new_n_static,
794 true /*defer_dp*/, true /*defer_mac_dp*/,
795 __func__);
796 }
797
798 /* Update the forwarding info. */
799 if (n->ifindex != ifindex) {
800 n->ifindex = ifindex;
801 inform_dataplane = true;
802 }
803 }
804
805 /* update the neigh seq. we don't bother with the mac seq as
806 * sync_mac_update already took care of that
807 */
808 tmp_seq = MAX(n->loc_seq, seq);
809 if (tmp_seq != n->loc_seq) {
810 n->loc_seq = tmp_seq;
811 inform_bgp = true;
812 }
813
814 /* Mark Router flag (R-bit) */
815 if (is_router)
816 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
817 else
818 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
819
820 if (old_router != is_router)
821 inform_dataplane = true;
822
823 new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
824 if (old_bgp_ready != new_bgp_ready)
825 inform_bgp = true;
826
827 new_mac_static = zebra_evpn_mac_is_static(mac);
828 if ((old_mac_static != new_mac_static) || ctx->mac_dp_update_deferred)
829 zebra_evpn_sync_mac_dp_install(mac, ctx->mac_inactive,
830 false /* force_clear_static */,
831 __func__);
832
833 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
834 zlog_debug(
835 "sync-neigh %s vni %u ip %s mac %s if %s(%d) seq %d f 0x%x%s%s",
836 created ? "created" : "updated", n->zevpn->vni,
837 ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
838 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
839 ifp ? ifp->name : "", ifindex, n->loc_seq, n->flags,
840 inform_bgp ? " inform_bgp" : "",
841 inform_dataplane ? " inform_dp" : "");
842
843 if (inform_dataplane)
844 zebra_evpn_sync_neigh_dp_install(n, set_dp_inactive,
845 false /* force_clear_static */,
846 __func__);
847
848 if (inform_bgp)
849 zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
850 new_bgp_ready);
851
852 return n;
853 }
854
855 /*
856 * Uninstall remote neighbor from the kernel.
857 */
858 static int zebra_evpn_neigh_uninstall(zebra_evpn_t *zevpn, zebra_neigh_t *n)
859 {
860 struct interface *vlan_if;
861
862 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
863 return 0;
864
865 vlan_if = zevpn_map_to_svi(zevpn);
866 if (!vlan_if)
867 return -1;
868
869 ZEBRA_NEIGH_SET_INACTIVE(n);
870 n->loc_seq = 0;
871
872 dplane_rem_neigh_delete(vlan_if, &n->ip);
873
874 return 0;
875 }
876
877 /*
878 * Free neighbor hash entry (callback)
879 */
880 static void zebra_evpn_neigh_del_hash_entry(struct hash_bucket *bucket,
881 void *arg)
882 {
883 struct neigh_walk_ctx *wctx = arg;
884 zebra_neigh_t *n = bucket->data;
885
886 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
887 || ((wctx->flags & DEL_REMOTE_NEIGH)
888 && (n->flags & ZEBRA_NEIGH_REMOTE))
889 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
890 && (n->flags & ZEBRA_NEIGH_REMOTE)
891 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
892 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
893 zebra_evpn_neigh_send_del_to_client(
894 wctx->zevpn->vni, &n->ip, &n->emac, n->flags,
895 n->state, false /*force*/);
896
897 if (wctx->uninstall) {
898 if (zebra_evpn_neigh_is_static(n))
899 zebra_evpn_sync_neigh_dp_install(
900 n, false /* set_inactive */,
901 true /* force_clear_static */,
902 __func__);
903 if ((n->flags & ZEBRA_NEIGH_REMOTE))
904 zebra_evpn_neigh_uninstall(wctx->zevpn, n);
905 }
906
907 zebra_evpn_neigh_del(wctx->zevpn, n);
908 }
909
910 return;
911 }
912
913 /*
914 * Delete all neighbor entries for this EVPN.
915 */
916 void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall,
917 int upd_client, uint32_t flags)
918 {
919 struct neigh_walk_ctx wctx;
920
921 if (!zevpn->neigh_table)
922 return;
923
924 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
925 wctx.zevpn = zevpn;
926 wctx.uninstall = uninstall;
927 wctx.upd_client = upd_client;
928 wctx.flags = flags;
929
930 hash_iterate(zevpn->neigh_table, zebra_evpn_neigh_del_hash_entry,
931 &wctx);
932 }
933
934 /*
935 * Look up neighbor hash entry.
936 */
937 zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip)
938 {
939 zebra_neigh_t tmp;
940 zebra_neigh_t *n;
941
942 memset(&tmp, 0, sizeof(tmp));
943 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
944 n = hash_lookup(zevpn->neigh_table, &tmp);
945
946 return n;
947 }
948
949 /*
950 * Process all neighbors associated with a MAC upon the MAC being learnt
951 * locally or undergoing any other change (such as sequence number).
952 */
953 void zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn,
954 zebra_mac_t *zmac,
955 bool seq_change,
956 bool es_change)
957 {
958 zebra_neigh_t *n = NULL;
959 struct listnode *node = NULL;
960 struct zebra_vrf *zvrf = NULL;
961 char buf[ETHER_ADDR_STRLEN];
962
963 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
964
965 if (IS_ZEBRA_DEBUG_VXLAN)
966 zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
967 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
968 seq_change ? "CHANGE" : "ADD", zevpn->vni);
969
970 /* Walk all neighbors and mark any inactive local neighbors as
971 * active and/or update sequence number upon a move, and inform BGP.
972 * The action for remote neighbors is TBD.
973 * NOTE: We can't simply uninstall remote neighbors as the kernel may
974 * accidentally end up deleting a just-learnt local neighbor.
975 */
976 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
977 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
978 if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change
979 || es_change) {
980 ZEBRA_NEIGH_SET_ACTIVE(n);
981 n->loc_seq = zmac->loc_seq;
982 if (!(zvrf->dup_addr_detect && zvrf->dad_freeze
983 && !!CHECK_FLAG(n->flags,
984 ZEBRA_NEIGH_DUPLICATE)))
985 zebra_evpn_neigh_send_add_to_client(
986 zevpn->vni, &n->ip, &n->emac,
987 n->mac, n->flags, n->loc_seq);
988 }
989 }
990 }
991 }
992
993 /*
994 * Process all neighbors associated with a local MAC upon the MAC being
995 * deleted.
996 */
997 void zebra_evpn_process_neigh_on_local_mac_del(zebra_evpn_t *zevpn,
998 zebra_mac_t *zmac)
999 {
1000 zebra_neigh_t *n = NULL;
1001 struct listnode *node = NULL;
1002 char buf[ETHER_ADDR_STRLEN];
1003
1004 if (IS_ZEBRA_DEBUG_VXLAN)
1005 zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
1006 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
1007 zevpn->vni);
1008
1009 /* Walk all local neighbors and mark as inactive and inform
1010 * BGP, if needed.
1011 * TBD: There is currently no handling for remote neighbors. We
1012 * don't expect them to exist, if they do, do we install the MAC
1013 * as a remote MAC and the neighbor as remote?
1014 */
1015 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1016 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1017 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1018 ZEBRA_NEIGH_SET_INACTIVE(n);
1019 n->loc_seq = 0;
1020 zebra_evpn_neigh_send_del_to_client(
1021 zevpn->vni, &n->ip, &n->emac, n->flags,
1022 ZEBRA_NEIGH_ACTIVE, false /*force*/);
1023 }
1024 }
1025 }
1026 }
1027
1028 /*
1029 * Process all neighbors associated with a MAC upon the MAC being remotely
1030 * learnt.
1031 */
1032 void zebra_evpn_process_neigh_on_remote_mac_add(zebra_evpn_t *zevpn,
1033 zebra_mac_t *zmac)
1034 {
1035 zebra_neigh_t *n = NULL;
1036 struct listnode *node = NULL;
1037 char buf[ETHER_ADDR_STRLEN];
1038
1039 if (IS_ZEBRA_DEBUG_VXLAN)
1040 zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
1041 prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
1042 zevpn->vni);
1043
1044 /* Walk all local neighbors and mark as inactive and inform
1045 * BGP, if needed.
1046 */
1047 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1048 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1049 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1050 ZEBRA_NEIGH_SET_INACTIVE(n);
1051 n->loc_seq = 0;
1052 zebra_evpn_neigh_send_del_to_client(
1053 zevpn->vni, &n->ip, &n->emac, n->flags,
1054 ZEBRA_NEIGH_ACTIVE, false /* force */);
1055 }
1056 }
1057 }
1058 }
1059
1060 /*
1061 * Process all neighbors associated with a remote MAC upon the MAC being
1062 * deleted.
1063 */
1064 void zebra_evpn_process_neigh_on_remote_mac_del(zebra_evpn_t *zevpn,
1065 zebra_mac_t *zmac)
1066 {
1067 /* NOTE: Currently a NO-OP. */
1068 }
1069
1070 static inline void zebra_evpn_local_neigh_update_log(
1071 const char *pfx, zebra_neigh_t *n, bool is_router, bool local_inactive,
1072 bool old_bgp_ready, bool new_bgp_ready, bool inform_dataplane,
1073 bool inform_bgp, const char *sfx)
1074 {
1075 char macbuf[ETHER_ADDR_STRLEN];
1076 char ipbuf[INET6_ADDRSTRLEN];
1077
1078 if (!IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
1079 return;
1080
1081 zlog_debug("%s neigh vni %u ip %s mac %s f 0x%x%s%s%s%s%s%s %s", pfx,
1082 n->zevpn->vni, ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
1083 prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)), n->flags,
1084 is_router ? " router" : "",
1085 local_inactive ? " local-inactive" : "",
1086 old_bgp_ready ? " old_bgp_ready" : "",
1087 new_bgp_ready ? " new_bgp_ready" : "",
1088 inform_dataplane ? " inform_dp" : "",
1089 inform_bgp ? " inform_bgp" : "", sfx);
1090 }
1091
1092 /* As part Duplicate Address Detection (DAD) for IP mobility
1093 * MAC binding changes, ensure to inherit duplicate flag
1094 * from MAC.
1095 */
1096 static int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
1097 zebra_mac_t *old_zmac,
1098 zebra_mac_t *new_zmac,
1099 zebra_neigh_t *nbr)
1100 {
1101 bool is_old_mac_dup = false;
1102 bool is_new_mac_dup = false;
1103
1104 if (!zvrf->dup_addr_detect)
1105 return 0;
1106 /* Check old or new MAC is detected as duplicate
1107 * mark this neigh as duplicate
1108 */
1109 if (old_zmac)
1110 is_old_mac_dup =
1111 CHECK_FLAG(old_zmac->flags, ZEBRA_MAC_DUPLICATE);
1112 if (new_zmac)
1113 is_new_mac_dup =
1114 CHECK_FLAG(new_zmac->flags, ZEBRA_MAC_DUPLICATE);
1115 /* Old and/or new MAC can be in duplicate state,
1116 * based on that IP/Neigh Inherits the flag.
1117 * If New MAC is marked duplicate, inherit to the IP.
1118 * If old MAC is duplicate but new MAC is not, clear
1119 * duplicate flag for IP and reset detection params
1120 * and let IP DAD retrigger.
1121 */
1122 if (is_new_mac_dup && !CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1123 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1124 /* Capture Duplicate detection time */
1125 nbr->dad_dup_detect_time = monotime(NULL);
1126 /* Mark neigh inactive */
1127 ZEBRA_NEIGH_SET_INACTIVE(nbr);
1128
1129 return 1;
1130 } else if (is_old_mac_dup && !is_new_mac_dup) {
1131 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1132 nbr->dad_count = 0;
1133 nbr->detect_start_time.tv_sec = 0;
1134 nbr->detect_start_time.tv_usec = 0;
1135 }
1136 return 0;
1137 }
1138
1139 static int zebra_evpn_dad_ip_auto_recovery_exp(struct thread *t)
1140 {
1141 struct zebra_vrf *zvrf = NULL;
1142 zebra_neigh_t *nbr = NULL;
1143 zebra_evpn_t *zevpn = NULL;
1144 char buf1[INET6_ADDRSTRLEN];
1145 char buf2[ETHER_ADDR_STRLEN];
1146
1147 nbr = THREAD_ARG(t);
1148
1149 /* since this is asynchronous we need sanity checks*/
1150 zvrf = vrf_info_lookup(nbr->zevpn->vrf_id);
1151 if (!zvrf)
1152 return 0;
1153
1154 zevpn = zebra_evpn_lookup(nbr->zevpn->vni);
1155 if (!zevpn)
1156 return 0;
1157
1158 nbr = zebra_evpn_neigh_lookup(zevpn, &nbr->ip);
1159 if (!nbr)
1160 return 0;
1161
1162 if (IS_ZEBRA_DEBUG_VXLAN)
1163 zlog_debug(
1164 "%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
1165 __func__,
1166 prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)),
1167 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)), nbr->flags,
1168 nbr->dad_count, zevpn->vni);
1169
1170 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1171 nbr->dad_count = 0;
1172 nbr->detect_start_time.tv_sec = 0;
1173 nbr->detect_start_time.tv_usec = 0;
1174 nbr->dad_dup_detect_time = 0;
1175 nbr->dad_ip_auto_recovery_timer = NULL;
1176 ZEBRA_NEIGH_SET_ACTIVE(nbr);
1177
1178 /* Send to BGP */
1179 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1180 zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1181 &nbr->emac, nbr->mac,
1182 nbr->flags, nbr->loc_seq);
1183 } else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1184 zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1185 }
1186
1187 return 0;
1188 }
1189
1190 static void
1191 zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr,
1192 struct in_addr vtep_ip, bool do_dad,
1193 bool *is_dup_detect, bool is_local)
1194 {
1195
1196 struct timeval elapsed = {0, 0};
1197 char buf[ETHER_ADDR_STRLEN];
1198 char buf1[INET6_ADDRSTRLEN];
1199 bool reset_params = false;
1200
1201 if (!zvrf->dup_addr_detect)
1202 return;
1203
1204 /* IP is detected as duplicate or inherit dup
1205 * state, hold on to install as remote entry
1206 * only if freeze is enabled.
1207 */
1208 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1209 if (IS_ZEBRA_DEBUG_VXLAN)
1210 zlog_debug(
1211 "%s: duplicate addr MAC %s IP %s flags 0x%x skip installing, learn count %u recover time %u",
1212 __func__,
1213 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1214 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1215 nbr->flags, nbr->dad_count,
1216 zvrf->dad_freeze_time);
1217
1218 if (zvrf->dad_freeze)
1219 *is_dup_detect = true;
1220
1221 /* warn-only action, neigh will be installed.
1222 * freeze action, it wil not be installed.
1223 */
1224 return;
1225 }
1226
1227 if (!do_dad)
1228 return;
1229
1230 /* Check if detection time (M-secs) expired.
1231 * Reset learn count and detection start time.
1232 * During remote mac add, count should already be 1
1233 * via local learning.
1234 */
1235 monotime_since(&nbr->detect_start_time, &elapsed);
1236 reset_params = (elapsed.tv_sec > zvrf->dad_time);
1237
1238 if (is_local && !reset_params) {
1239 /* RFC-7432: A PE/VTEP that detects a MAC mobility
1240 * event via LOCAL learning starts an M-second timer.
1241 *
1242 * NOTE: This is the START of the probe with count is
1243 * 0 during LOCAL learn event.
1244 */
1245 reset_params = !nbr->dad_count;
1246 }
1247
1248 if (reset_params) {
1249 if (IS_ZEBRA_DEBUG_VXLAN)
1250 zlog_debug(
1251 "%s: duplicate addr MAC %s IP %s flags 0x%x detection time passed, reset learn count %u",
1252 __func__,
1253 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1254 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1255 nbr->flags, nbr->dad_count);
1256 /* Reset learn count but do not start detection
1257 * during REMOTE learn event.
1258 */
1259 nbr->dad_count = 0;
1260 /* Start dup. addr detection (DAD) start time,
1261 * ONLY during LOCAL learn.
1262 */
1263 if (is_local)
1264 monotime(&nbr->detect_start_time);
1265
1266 } else if (!is_local) {
1267 /* For REMOTE IP/Neigh, increment detection count
1268 * ONLY while in probe window, once window passed,
1269 * next local learn event should trigger DAD.
1270 */
1271 nbr->dad_count++;
1272 }
1273
1274 /* For LOCAL IP/Neigh learn event, once count is reset above via either
1275 * initial/start detection time or passed the probe time, the count
1276 * needs to be incremented.
1277 */
1278 if (is_local)
1279 nbr->dad_count++;
1280
1281 if (nbr->dad_count >= zvrf->dad_max_moves) {
1282 flog_warn(
1283 EC_ZEBRA_DUP_IP_DETECTED,
1284 "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s",
1285 nbr->zevpn->vni,
1286 prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1287 ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1288 is_local ? "local update, last" : "remote update, from",
1289 inet_ntoa(vtep_ip));
1290
1291 SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1292
1293 /* Capture Duplicate detection time */
1294 nbr->dad_dup_detect_time = monotime(NULL);
1295
1296 /* Start auto recovery timer for this IP */
1297 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
1298 if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
1299 if (IS_ZEBRA_DEBUG_VXLAN)
1300 zlog_debug(
1301 "%s: duplicate addr MAC %s IP %s flags 0x%x auto recovery time %u start",
1302 __func__,
1303 prefix_mac2str(&nbr->emac, buf,
1304 sizeof(buf)),
1305 ipaddr2str(&nbr->ip, buf1,
1306 sizeof(buf1)),
1307 nbr->flags, zvrf->dad_freeze_time);
1308
1309 thread_add_timer(zrouter.master,
1310 zebra_evpn_dad_ip_auto_recovery_exp,
1311 nbr, zvrf->dad_freeze_time,
1312 &nbr->dad_ip_auto_recovery_timer);
1313 }
1314 if (zvrf->dad_freeze)
1315 *is_dup_detect = true;
1316 }
1317 }
1318
1319 int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
1320 struct ipaddr *ip, struct ethaddr *macaddr,
1321 bool is_router, bool local_inactive,
1322 bool dp_static)
1323 {
1324 char buf[ETHER_ADDR_STRLEN];
1325 char buf2[INET6_ADDRSTRLEN];
1326 struct zebra_vrf *zvrf;
1327 zebra_neigh_t *n = NULL;
1328 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
1329 uint32_t old_mac_seq = 0, mac_new_seq = 0;
1330 bool upd_mac_seq = false;
1331 bool neigh_mac_change = false;
1332 bool neigh_on_hold = false;
1333 bool neigh_was_remote = false;
1334 bool do_dad = false;
1335 struct in_addr vtep_ip = {.s_addr = 0};
1336 bool inform_dataplane = false;
1337 bool created = false;
1338 bool new_static = false;
1339 bool old_bgp_ready = false;
1340 bool new_bgp_ready;
1341
1342 /* Check if the MAC exists. */
1343 zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1344 if (!zmac) {
1345 /* create a dummy MAC if the MAC is not already present */
1346 if (IS_ZEBRA_DEBUG_VXLAN)
1347 zlog_debug("AUTO MAC %s created for neigh %s on VNI %u",
1348 prefix_mac2str(macaddr, buf, sizeof(buf)),
1349 ipaddr2str(ip, buf2, sizeof(buf2)),
1350 zevpn->vni);
1351
1352 zmac = zebra_evpn_mac_add(zevpn, macaddr);
1353 if (!zmac) {
1354 zlog_debug("Failed to add MAC %s VNI %u",
1355 prefix_mac2str(macaddr, buf, sizeof(buf)),
1356 zevpn->vni);
1357 return -1;
1358 }
1359
1360 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
1361 memset(&zmac->flags, 0, sizeof(uint32_t));
1362 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
1363 } else {
1364 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1365 /*
1366 * We don't change the MAC to local upon a neighbor
1367 * learn event, we wait for the explicit local MAC
1368 * learn. However, we have to compute its sequence
1369 * number in preparation for when it actually turns
1370 * local.
1371 */
1372 upd_mac_seq = true;
1373 }
1374 }
1375
1376 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
1377 if (!zvrf) {
1378 if (IS_ZEBRA_DEBUG_VXLAN)
1379 zlog_debug(" Unable to find vrf for: %d",
1380 zevpn->vxlan_if->vrf_id);
1381 return -1;
1382 }
1383
1384 /* Check if the neighbor exists. */
1385 n = zebra_evpn_neigh_lookup(zevpn, ip);
1386 if (!n) {
1387 /* New neighbor - create */
1388 n = zebra_evpn_neigh_add(zevpn, ip, macaddr, zmac, 0);
1389 if (!n) {
1390 flog_err(
1391 EC_ZEBRA_MAC_ADD_FAILED,
1392 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1393 ipaddr2str(ip, buf2, sizeof(buf2)),
1394 prefix_mac2str(macaddr, buf, sizeof(buf)),
1395 ifp->name, ifp->ifindex, zevpn->vni);
1396 return -1;
1397 }
1398 /* Set "local" forwarding info. */
1399 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1400 n->ifindex = ifp->ifindex;
1401 created = true;
1402 } else {
1403 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1404 bool mac_different;
1405 bool cur_is_router;
1406 bool old_local_inactive;
1407
1408 old_local_inactive = !!CHECK_FLAG(
1409 n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1410
1411 old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1412
1413 /* Note any changes and see if of interest to BGP. */
1414 mac_different = !!memcmp(&n->emac, macaddr, ETH_ALEN);
1415 cur_is_router =
1416 !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1417 new_static = zebra_evpn_neigh_is_static(n);
1418 if (!mac_different && is_router == cur_is_router
1419 && old_local_inactive == local_inactive
1420 && dp_static != new_static) {
1421 if (IS_ZEBRA_DEBUG_VXLAN)
1422 zlog_debug(
1423 " Ignoring entry mac is the same and is_router == cur_is_router");
1424 n->ifindex = ifp->ifindex;
1425 return 0;
1426 }
1427
1428 old_zmac = n->mac;
1429 if (!mac_different) {
1430 /* XXX - cleanup this code duplication */
1431 bool is_neigh_freezed = false;
1432
1433 /* Only the router flag has changed. */
1434 if (is_router)
1435 SET_FLAG(n->flags,
1436 ZEBRA_NEIGH_ROUTER_FLAG);
1437 else
1438 UNSET_FLAG(n->flags,
1439 ZEBRA_NEIGH_ROUTER_FLAG);
1440
1441 if (local_inactive)
1442 SET_FLAG(n->flags,
1443 ZEBRA_NEIGH_LOCAL_INACTIVE);
1444 else
1445 UNSET_FLAG(n->flags,
1446 ZEBRA_NEIGH_LOCAL_INACTIVE);
1447 new_bgp_ready =
1448 zebra_evpn_neigh_is_ready_for_bgp(n);
1449
1450 /* Neigh is in freeze state and freeze action
1451 * is enabled, do not send update to client.
1452 */
1453 is_neigh_freezed =
1454 (zvrf->dup_addr_detect
1455 && zvrf->dad_freeze
1456 && CHECK_FLAG(n->flags,
1457 ZEBRA_NEIGH_DUPLICATE));
1458
1459 zebra_evpn_local_neigh_update_log(
1460 "local", n, is_router, local_inactive,
1461 old_bgp_ready, new_bgp_ready, false,
1462 false, "flag-update");
1463
1464 /* if the neigh can no longer be advertised
1465 * remove it from bgp
1466 */
1467 if (!is_neigh_freezed) {
1468 zebra_evpn_neigh_send_add_del_to_client(
1469 n, old_bgp_ready,
1470 new_bgp_ready);
1471 } else {
1472 if (IS_ZEBRA_DEBUG_VXLAN
1473 && IS_ZEBRA_NEIGH_ACTIVE(n))
1474 zlog_debug(
1475 " Neighbor active and frozen");
1476 }
1477 return 0;
1478 }
1479
1480 /* The MAC has changed, need to issue a delete
1481 * first as this means a different MACIP route.
1482 * Also, need to do some unlinking/relinking.
1483 * We also need to update the MAC's sequence number
1484 * in different situations.
1485 */
1486 if (old_bgp_ready) {
1487 zebra_evpn_neigh_send_del_to_client(
1488 zevpn->vni, &n->ip, &n->emac, n->flags,
1489 n->state, false /*force*/);
1490 old_bgp_ready = false;
1491 }
1492 if (old_zmac) {
1493 old_mac_seq = CHECK_FLAG(old_zmac->flags,
1494 ZEBRA_MAC_REMOTE)
1495 ? old_zmac->rem_seq
1496 : old_zmac->loc_seq;
1497 neigh_mac_change = upd_mac_seq = true;
1498 zebra_evpn_local_neigh_deref_mac(
1499 n, true /* send_mac_update */);
1500 }
1501
1502 /* if mac changes abandon peer flags and tell
1503 * dataplane to clear the static flag
1504 */
1505 if (zebra_evpn_neigh_clear_sync_info(n))
1506 inform_dataplane = true;
1507 /* Update the forwarding info. */
1508 n->ifindex = ifp->ifindex;
1509
1510 /* Link to new MAC */
1511 zebra_evpn_local_neigh_ref_mac(
1512 n, macaddr, zmac, true /* send_mac_update */);
1513 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1514 /*
1515 * Neighbor has moved from remote to local. Its
1516 * MAC could have also changed as part of the move.
1517 */
1518 if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN)
1519 != 0) {
1520 old_zmac = n->mac;
1521 if (old_zmac) {
1522 old_mac_seq =
1523 CHECK_FLAG(old_zmac->flags,
1524 ZEBRA_MAC_REMOTE)
1525 ? old_zmac->rem_seq
1526 : old_zmac->loc_seq;
1527 neigh_mac_change = upd_mac_seq = true;
1528 zebra_evpn_local_neigh_deref_mac(
1529 n, true /* send_update */);
1530 }
1531
1532 /* Link to new MAC */
1533 zebra_evpn_local_neigh_ref_mac(
1534 n, macaddr, zmac, true /*send_update*/);
1535 }
1536 /* Based on Mobility event Scenario-B from the
1537 * draft, neigh's previous state was remote treat this
1538 * event for DAD.
1539 */
1540 neigh_was_remote = true;
1541 vtep_ip = n->r_vtep_ip;
1542 /* Mark appropriately */
1543 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1544 n->r_vtep_ip.s_addr = INADDR_ANY;
1545 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1546 n->ifindex = ifp->ifindex;
1547 }
1548 }
1549
1550 /* If MAC was previously remote, or the neighbor had a different
1551 * MAC earlier, recompute the sequence number.
1552 */
1553 if (upd_mac_seq) {
1554 uint32_t seq1, seq2;
1555
1556 seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)
1557 ? zmac->rem_seq + 1
1558 : zmac->loc_seq;
1559 seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
1560 mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ? MAX(seq1, seq2)
1561 : zmac->loc_seq;
1562 }
1563
1564 if (local_inactive)
1565 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1566 else
1567 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1568
1569 /* Mark Router flag (R-bit) */
1570 if (is_router)
1571 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1572 else
1573 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1574
1575 /* if the dataplane thinks that this is a sync entry but
1576 * zebra doesn't we need to re-concile the diff
1577 * by re-installing the dataplane entry
1578 */
1579 if (dp_static) {
1580 new_static = zebra_evpn_neigh_is_static(n);
1581 if (!new_static)
1582 inform_dataplane = true;
1583 }
1584
1585 /* Check old and/or new MAC detected as duplicate mark
1586 * the neigh as duplicate
1587 */
1588 if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
1589 flog_warn(
1590 EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
1591 "VNI %u: MAC %s IP %s detected as duplicate during local update, inherit duplicate from MAC",
1592 zevpn->vni, prefix_mac2str(macaddr, buf, sizeof(buf)),
1593 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1594 }
1595
1596 /* For IP Duplicate Address Detection (DAD) is trigger,
1597 * when the event is extended mobility based on scenario-B
1598 * from the draft, IP/Neigh's MAC binding changed and
1599 * neigh's previous state was remote.
1600 */
1601 if (neigh_mac_change && neigh_was_remote)
1602 do_dad = true;
1603
1604 zebra_evpn_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
1605 &neigh_on_hold, true);
1606
1607 if (inform_dataplane)
1608 zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
1609 false /* force_clear_static */,
1610 __func__);
1611
1612 /* Before we program this in BGP, we need to check if MAC is locally
1613 * learnt. If not, force neighbor to be inactive and reset its seq.
1614 */
1615 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
1616 zebra_evpn_local_neigh_update_log(
1617 "local", n, is_router, local_inactive, false, false,
1618 inform_dataplane, false, "auto-mac");
1619 ZEBRA_NEIGH_SET_INACTIVE(n);
1620 n->loc_seq = 0;
1621 zmac->loc_seq = mac_new_seq;
1622 return 0;
1623 }
1624
1625 zebra_evpn_local_neigh_update_log("local", n, is_router, local_inactive,
1626 false, false, inform_dataplane, true,
1627 created ? "created" : "updated");
1628
1629 /* If the MAC's sequence number has changed, inform the MAC and all
1630 * neighbors associated with the MAC to BGP, else just inform this
1631 * neighbor.
1632 */
1633 if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
1634 if (IS_ZEBRA_DEBUG_VXLAN)
1635 zlog_debug(
1636 "Seq changed for MAC %s VNI %u - old %u new %u",
1637 prefix_mac2str(macaddr, buf, sizeof(buf)),
1638 zevpn->vni, zmac->loc_seq, mac_new_seq);
1639 zmac->loc_seq = mac_new_seq;
1640 if (zebra_evpn_mac_send_add_to_client(zevpn->vni, macaddr,
1641 zmac->flags,
1642 zmac->loc_seq, zmac->es))
1643 return -1;
1644 zebra_evpn_process_neigh_on_local_mac_change(zevpn, zmac, 1,
1645 0 /*es_change*/);
1646 return 0;
1647 }
1648
1649 n->loc_seq = zmac->loc_seq;
1650
1651 if (!neigh_on_hold) {
1652 ZEBRA_NEIGH_SET_ACTIVE(n);
1653 new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1654 zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
1655 new_bgp_ready);
1656 } else {
1657 if (IS_ZEBRA_DEBUG_VXLAN)
1658 zlog_debug(" Neighbor on hold not sending");
1659 }
1660 return 0;
1661 }
1662
1663 int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
1664 struct ipaddr *ip, struct ethaddr *macaddr,
1665 uint16_t state)
1666 {
1667 char buf[ETHER_ADDR_STRLEN];
1668 char buf2[INET6_ADDRSTRLEN];
1669 zebra_neigh_t *n = NULL;
1670 zebra_mac_t *zmac = NULL;
1671
1672 /* If the neighbor is unknown, there is no further action. */
1673 n = zebra_evpn_neigh_lookup(zevpn, ip);
1674 if (!n)
1675 return 0;
1676
1677 /* If a remote entry, see if it needs to be refreshed */
1678 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1679 #ifdef GNU_LINUX
1680 if (state & NUD_STALE)
1681 zebra_evpn_rem_neigh_install(zevpn, n,
1682 false /*was_static*/);
1683 #endif
1684 } else {
1685 /* We got a "remote" neighbor notification for an entry
1686 * we think is local. This can happen in a multihoming
1687 * scenario - but only if the MAC is already "remote".
1688 * Just mark our entry as "remote".
1689 */
1690 zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1691 if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1692 zlog_debug(
1693 "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
1694 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
1695 prefix_mac2str(macaddr, buf, sizeof(buf)),
1696 zevpn->vni);
1697 return -1;
1698 }
1699
1700 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
1701 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1702 ZEBRA_NEIGH_SET_ACTIVE(n);
1703 n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
1704 }
1705
1706 return 0;
1707 }
1708
1709 /* Notify Neighbor entries to the Client, skips the GW entry */
1710 static void
1711 zebra_evpn_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
1712 void *arg)
1713 {
1714 struct mac_walk_ctx *wctx = arg;
1715 zebra_neigh_t *zn = bucket->data;
1716 zebra_mac_t *zmac = NULL;
1717
1718 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
1719 return;
1720
1721 if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL)
1722 && IS_ZEBRA_NEIGH_ACTIVE(zn)) {
1723 zmac = zebra_evpn_mac_lookup(wctx->zevpn, &zn->emac);
1724 if (!zmac)
1725 return;
1726
1727 zebra_evpn_neigh_send_add_to_client(wctx->zevpn->vni, &zn->ip,
1728 &zn->emac, zn->mac,
1729 zn->flags, zn->loc_seq);
1730 }
1731 }
1732
1733 /* Iterator of a specific EVPN */
1734 void zebra_evpn_send_neigh_to_client(zebra_evpn_t *zevpn)
1735 {
1736 struct neigh_walk_ctx wctx;
1737
1738 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1739 wctx.zevpn = zevpn;
1740
1741 hash_iterate(zevpn->neigh_table,
1742 zebra_evpn_send_neigh_hash_entry_to_client, &wctx);
1743 }
1744
1745 void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1746 {
1747 struct neigh_walk_ctx *wctx = ctxt;
1748 zebra_neigh_t *nbr;
1749 zebra_evpn_t *zevpn;
1750 char buf[INET6_ADDRSTRLEN];
1751
1752 nbr = (zebra_neigh_t *)bucket->data;
1753 if (!nbr)
1754 return;
1755
1756 zevpn = wctx->zevpn;
1757
1758 if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
1759 return;
1760
1761 if (IS_ZEBRA_DEBUG_VXLAN) {
1762 ipaddr2str(&nbr->ip, buf, sizeof(buf));
1763 zlog_debug("%s: clear neigh %s dup state, flags 0x%x seq %u",
1764 __func__, buf, nbr->flags, nbr->loc_seq);
1765 }
1766
1767 UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1768 nbr->dad_count = 0;
1769 nbr->detect_start_time.tv_sec = 0;
1770 nbr->detect_start_time.tv_usec = 0;
1771 nbr->dad_dup_detect_time = 0;
1772 THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
1773
1774 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1775 zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1776 &nbr->emac, nbr->mac,
1777 nbr->flags, nbr->loc_seq);
1778 } else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1779 zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1780 }
1781 }
1782
1783 /*
1784 * Print a specific neighbor entry.
1785 */
1786 void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
1787 {
1788 struct vty *vty;
1789 char buf1[ETHER_ADDR_STRLEN];
1790 char buf2[INET6_ADDRSTRLEN];
1791 const char *type_str;
1792 const char *state_str;
1793 bool flags_present = false;
1794 struct zebra_vrf *zvrf = NULL;
1795 struct timeval detect_start_time = {0, 0};
1796 char timebuf[MONOTIME_STRLEN];
1797 char thread_buf[THREAD_TIMER_STRLEN];
1798
1799 zvrf = zebra_vrf_get_evpn();
1800 if (!zvrf)
1801 return;
1802
1803 ipaddr2str(&n->ip, buf2, sizeof(buf2));
1804 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1805 type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote";
1806 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1807 vty = (struct vty *)ctxt;
1808 if (json == NULL) {
1809 bool sync_info = false;
1810
1811 vty_out(vty, "IP: %s\n",
1812 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1813 vty_out(vty, " Type: %s\n", type_str);
1814 vty_out(vty, " State: %s\n", state_str);
1815 vty_out(vty, " MAC: %s\n",
1816 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1817 vty_out(vty, " Sync-info:");
1818 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
1819 vty_out(vty, " local-inactive");
1820 sync_info = true;
1821 }
1822 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY)) {
1823 vty_out(vty, " peer-proxy");
1824 sync_info = true;
1825 }
1826 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
1827 vty_out(vty, " peer-active");
1828 sync_info = true;
1829 }
1830 if (n->hold_timer) {
1831 vty_out(vty, " (ht: %s)",
1832 thread_timer_to_hhmmss(thread_buf,
1833 sizeof(thread_buf),
1834 n->hold_timer));
1835 sync_info = true;
1836 }
1837 if (!sync_info)
1838 vty_out(vty, " -");
1839 vty_out(vty, "\n");
1840 } else {
1841 json_object_string_add(json, "ip", buf2);
1842 json_object_string_add(json, "type", type_str);
1843 json_object_string_add(json, "state", state_str);
1844 json_object_string_add(json, "mac", buf1);
1845 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
1846 json_object_boolean_true_add(json, "localInactive");
1847 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY))
1848 json_object_boolean_true_add(json, "peerProxy");
1849 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
1850 json_object_boolean_true_add(json, "peerActive");
1851 if (n->hold_timer)
1852 json_object_string_add(
1853 json, "peerActiveHold",
1854 thread_timer_to_hhmmss(thread_buf,
1855 sizeof(thread_buf),
1856 n->hold_timer));
1857 }
1858 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1859 if (n->mac->es) {
1860 if (json)
1861 json_object_string_add(json, "remoteEs",
1862 n->mac->es->esi_str);
1863 else
1864 vty_out(vty, " Remote ES: %s\n",
1865 n->mac->es->esi_str);
1866 } else {
1867 if (json)
1868 json_object_string_add(json, "remoteVtep",
1869 inet_ntoa(n->r_vtep_ip));
1870 else
1871 vty_out(vty, " Remote VTEP: %s\n",
1872 inet_ntoa(n->r_vtep_ip));
1873 }
1874 }
1875 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
1876 if (!json) {
1877 vty_out(vty, " Flags: Default-gateway");
1878 flags_present = true;
1879 } else
1880 json_object_boolean_true_add(json, "defaultGateway");
1881 }
1882 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
1883 if (!json) {
1884 vty_out(vty,
1885 flags_present ? " ,Router" : " Flags: Router");
1886 flags_present = true;
1887 }
1888 }
1889 if (json == NULL) {
1890 if (flags_present)
1891 vty_out(vty, "\n");
1892 vty_out(vty, " Local Seq: %u Remote Seq: %u\n", n->loc_seq,
1893 n->rem_seq);
1894
1895 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
1896 vty_out(vty, " Duplicate, detected at %s",
1897 time_to_string(n->dad_dup_detect_time,
1898 timebuf));
1899 } else if (n->dad_count) {
1900 monotime_since(&n->detect_start_time,
1901 &detect_start_time);
1902 if (detect_start_time.tv_sec <= zvrf->dad_time) {
1903 time_to_string(n->detect_start_time.tv_sec,
1904 timebuf);
1905 vty_out(vty,
1906 " Duplicate detection started at %s, detection count %u\n",
1907 timebuf, n->dad_count);
1908 }
1909 }
1910 } else {
1911 json_object_int_add(json, "localSequence", n->loc_seq);
1912 json_object_int_add(json, "remoteSequence", n->rem_seq);
1913 json_object_int_add(json, "detectionCount", n->dad_count);
1914 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1915 json_object_boolean_true_add(json, "isDuplicate");
1916 else
1917 json_object_boolean_false_add(json, "isDuplicate");
1918 }
1919 }
1920
1921 void zebra_evpn_print_neigh_hdr(struct vty *vty, struct neigh_walk_ctx *wctx)
1922 {
1923 vty_out(vty, "Flags: I=local-inactive, P=peer-active, X=peer-proxy\n");
1924 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %s\n", -wctx->addr_width,
1925 "Neighbor", "Type", "Flags", "State", "MAC", "Remote ES/VTEP",
1926 "Seq #'s");
1927 }
1928
1929 static char *zebra_evpn_print_neigh_flags(zebra_neigh_t *n, char *flags_buf,
1930 uint32_t flags_buf_sz)
1931 {
1932 snprintf(flags_buf, flags_buf_sz, "%s%s%s",
1933 (n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE) ?
1934 "P" : "",
1935 (n->flags & ZEBRA_NEIGH_ES_PEER_PROXY) ?
1936 "X" : "",
1937 (n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) ?
1938 "I" : "");
1939
1940 return flags_buf;
1941 }
1942
1943 /*
1944 * Print neighbor hash entry - called for display of all neighbors.
1945 */
1946 void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1947 {
1948 struct vty *vty;
1949 json_object *json_evpn = NULL, *json_row = NULL;
1950 zebra_neigh_t *n;
1951 char buf1[ETHER_ADDR_STRLEN];
1952 char buf2[INET6_ADDRSTRLEN];
1953 struct neigh_walk_ctx *wctx = ctxt;
1954 const char *state_str;
1955 char flags_buf[6];
1956
1957 vty = wctx->vty;
1958 json_evpn = wctx->json;
1959 n = (zebra_neigh_t *)bucket->data;
1960
1961 if (json_evpn)
1962 json_row = json_object_new_object();
1963
1964 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1965 ipaddr2str(&n->ip, buf2, sizeof(buf2));
1966 state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1967 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1968 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
1969 return;
1970
1971 if (json_evpn == NULL) {
1972 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
1973 -wctx->addr_width, buf2, "local",
1974 zebra_evpn_print_neigh_flags(n, flags_buf,
1975 sizeof(flags_buf)), state_str, buf1,
1976 "", n->loc_seq, n->rem_seq);
1977 } else {
1978 json_object_string_add(json_row, "type", "local");
1979 json_object_string_add(json_row, "state", state_str);
1980 json_object_string_add(json_row, "mac", buf1);
1981 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
1982 json_object_boolean_true_add(json_row,
1983 "defaultGateway");
1984 json_object_int_add(json_row, "localSequence",
1985 n->loc_seq);
1986 json_object_int_add(json_row, "remoteSequence",
1987 n->rem_seq);
1988 json_object_int_add(json_row, "detectionCount",
1989 n->dad_count);
1990 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1991 json_object_boolean_true_add(json_row,
1992 "isDuplicate");
1993 else
1994 json_object_boolean_false_add(json_row,
1995 "isDuplicate");
1996 }
1997 wctx->count++;
1998 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1999 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
2000 && !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
2001 return;
2002
2003 if (json_evpn == NULL) {
2004 if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
2005 && (wctx->count == 0))
2006 zebra_evpn_print_neigh_hdr(vty, wctx);
2007 vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
2008 -wctx->addr_width, buf2, "remote",
2009 zebra_evpn_print_neigh_flags(n, flags_buf,
2010 sizeof(flags_buf)), state_str, buf1,
2011 n->mac->es ? n->mac->es->esi_str
2012 : inet_ntoa(n->r_vtep_ip),
2013 n->loc_seq, n->rem_seq);
2014 } else {
2015 json_object_string_add(json_row, "type", "remote");
2016 json_object_string_add(json_row, "state", state_str);
2017 json_object_string_add(json_row, "mac", buf1);
2018 if (n->mac->es)
2019 json_object_string_add(json_row, "remoteEs",
2020 n->mac->es->esi_str);
2021 else
2022 json_object_string_add(json_row, "remoteVtep",
2023 inet_ntoa(n->r_vtep_ip));
2024 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
2025 json_object_boolean_true_add(json_row,
2026 "defaultGateway");
2027 json_object_int_add(json_row, "localSequence",
2028 n->loc_seq);
2029 json_object_int_add(json_row, "remoteSequence",
2030 n->rem_seq);
2031 json_object_int_add(json_row, "detectionCount",
2032 n->dad_count);
2033 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
2034 json_object_boolean_true_add(json_row,
2035 "isDuplicate");
2036 else
2037 json_object_boolean_false_add(json_row,
2038 "isDuplicate");
2039 }
2040 wctx->count++;
2041 }
2042
2043 if (json_evpn)
2044 json_object_object_add(json_evpn, buf2, json_row);
2045 }
2046
2047 /*
2048 * Print neighbor hash entry in detail - called for display of all neighbors.
2049 */
2050 void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt)
2051 {
2052 struct vty *vty;
2053 json_object *json_evpn = NULL, *json_row = NULL;
2054 zebra_neigh_t *n;
2055 char buf[INET6_ADDRSTRLEN];
2056 struct neigh_walk_ctx *wctx = ctxt;
2057
2058 vty = wctx->vty;
2059 json_evpn = wctx->json;
2060 n = (zebra_neigh_t *)bucket->data;
2061 if (!n)
2062 return;
2063
2064 ipaddr2str(&n->ip, buf, sizeof(buf));
2065 if (json_evpn)
2066 json_row = json_object_new_object();
2067
2068 zebra_evpn_print_neigh(n, vty, json_row);
2069
2070 if (json_evpn)
2071 json_object_object_add(json_evpn, buf, json_row);
2072 }
2073
2074 void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt)
2075 {
2076 zebra_neigh_t *nbr;
2077
2078 nbr = (zebra_neigh_t *)bucket->data;
2079 if (!nbr)
2080 return;
2081
2082 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2083 zebra_evpn_print_neigh_hash(bucket, ctxt);
2084 }
2085
2086 void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
2087 void *ctxt)
2088 {
2089 zebra_neigh_t *nbr;
2090
2091 nbr = (zebra_neigh_t *)bucket->data;
2092 if (!nbr)
2093 return;
2094
2095 if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2096 zebra_evpn_print_neigh_hash_detail(bucket, ctxt);
2097 }
2098
2099 void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
2100 struct ipaddr *ipaddr, zebra_mac_t *mac,
2101 struct in_addr vtep_ip, uint8_t flags,
2102 uint32_t seq)
2103 {
2104 zebra_neigh_t *n;
2105 int update_neigh = 0;
2106 uint32_t tmp_seq;
2107 char buf[ETHER_ADDR_STRLEN];
2108 char buf1[INET6_ADDRSTRLEN];
2109 zebra_mac_t *old_mac = NULL;
2110 bool old_static = false;
2111 bool do_dad = false;
2112 bool is_dup_detect = false;
2113 bool is_router;
2114
2115 assert(mac);
2116 is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
2117
2118 /* Check if the remote neighbor itself is unknown or has a
2119 * change. If so, create or update and then install the entry.
2120 */
2121 n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
2122 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2123 || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
2124 || (memcmp(&n->emac, &mac->macaddr, sizeof(struct ethaddr)) != 0)
2125 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) || seq != n->rem_seq)
2126 update_neigh = 1;
2127
2128 if (update_neigh) {
2129 if (!n) {
2130 n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr,
2131 mac, 0);
2132 if (!n) {
2133 zlog_warn(
2134 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2135 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
2136 prefix_mac2str(&mac->macaddr, buf,
2137 sizeof(buf)),
2138 zevpn->vni, inet_ntoa(vtep_ip));
2139 return;
2140 }
2141
2142 } else {
2143 const char *n_type;
2144
2145 /* When host moves but changes its (MAC,IP)
2146 * binding, BGP may install a MACIP entry that
2147 * corresponds to "older" location of the host
2148 * in transient situations (because {IP1,M1}
2149 * is a different route from {IP1,M2}). Check
2150 * the sequence number and ignore this update
2151 * if appropriate.
2152 */
2153 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2154 tmp_seq = n->loc_seq;
2155 n_type = "local";
2156 } else {
2157 tmp_seq = n->rem_seq;
2158 n_type = "remote";
2159 }
2160 if (seq < tmp_seq) {
2161 if (IS_ZEBRA_DEBUG_VXLAN)
2162 zlog_debug(
2163 "Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
2164 zevpn->vni,
2165 prefix_mac2str(&mac->macaddr,
2166 buf,
2167 sizeof(buf)),
2168 " IP ",
2169 ipaddr2str(ipaddr, buf1,
2170 sizeof(buf1)),
2171 n_type, tmp_seq);
2172 return;
2173 }
2174 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2175 old_static = zebra_evpn_neigh_is_static(n);
2176 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2177 zlog_debug(
2178 "sync->remote neigh vni %u ip %s mac %s seq %d f0x%x",
2179 n->zevpn->vni,
2180 ipaddr2str(&n->ip, buf1,
2181 sizeof(buf1)),
2182 prefix_mac2str(&n->emac, buf,
2183 sizeof(buf)),
2184 seq, n->flags);
2185 zebra_evpn_neigh_clear_sync_info(n);
2186 if (IS_ZEBRA_NEIGH_ACTIVE(n))
2187 zebra_evpn_mac_send_del_to_client(
2188 zevpn->vni, &mac->macaddr,
2189 mac->flags, false /*force*/);
2190 }
2191 if (memcmp(&n->emac, &mac->macaddr,
2192 sizeof(struct ethaddr))
2193 != 0) {
2194 /* update neigh list for macs */
2195 old_mac =
2196 zebra_evpn_mac_lookup(zevpn, &n->emac);
2197 if (old_mac) {
2198 listnode_delete(old_mac->neigh_list, n);
2199 n->mac = NULL;
2200 zebra_evpn_deref_ip2mac(zevpn, old_mac);
2201 }
2202 n->mac = mac;
2203 listnode_add_sort(mac->neigh_list, n);
2204 memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2205
2206 /* Check Neigh's curent state is local
2207 * (this is the case where neigh/host has moved
2208 * from L->R) and check previous detction
2209 * started via local learning.
2210 *
2211 * RFC-7432: A PE/VTEP that detects a MAC
2212 * mobilit event via local learning starts
2213 * an M-second timer.
2214 * VTEP-IP or seq. change along is not
2215 * considered for dup. detection.
2216 *
2217 * Mobilty event scenario-B IP-MAC binding
2218 * changed.
2219 */
2220 if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2221 && n->dad_count)
2222 do_dad = true;
2223 }
2224 }
2225
2226 /* Set "remote" forwarding info. */
2227 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
2228 n->r_vtep_ip = vtep_ip;
2229 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2230
2231 /* Set router flag (R-bit) to this Neighbor entry */
2232 if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
2233 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2234 else
2235 UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2236
2237 /* Check old or new MAC detected as duplicate,
2238 * inherit duplicate flag to this neigh.
2239 */
2240 if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_mac, mac, n)) {
2241 flog_warn(
2242 EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
2243 "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
2244 zevpn->vni,
2245 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2246 ipaddr2str(&n->ip, buf1, sizeof(buf1)));
2247 }
2248
2249 /* Check duplicate address detection for IP */
2250 zebra_evpn_dup_addr_detect_for_neigh(
2251 zvrf, n, n->r_vtep_ip, do_dad, &is_dup_detect, false);
2252 /* Install the entry. */
2253 if (!is_dup_detect)
2254 zebra_evpn_rem_neigh_install(zevpn, n, old_static);
2255 }
2256
2257 /* Update seq number. */
2258 n->rem_seq = seq;
2259 }
2260
2261 int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
2262 struct ipaddr *ip, zebra_mac_t *mac)
2263 {
2264 zebra_neigh_t *n;
2265 char buf[ETHER_ADDR_STRLEN];
2266 char buf2[INET6_ADDRSTRLEN];
2267
2268 assert(mac);
2269
2270 n = zebra_evpn_neigh_lookup(zevpn, ip);
2271 if (!n) {
2272 n = zebra_evpn_neigh_add(zevpn, ip, &mac->macaddr, mac, 0);
2273 if (!n) {
2274 flog_err(
2275 EC_ZEBRA_MAC_ADD_FAILED,
2276 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2277 ipaddr2str(ip, buf2, sizeof(buf2)),
2278 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2279 ifp->name, ifp->ifindex, zevpn->vni);
2280 return -1;
2281 }
2282 }
2283
2284 /* Set "local" forwarding info. */
2285 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2286 ZEBRA_NEIGH_SET_ACTIVE(n);
2287 memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2288 n->ifindex = ifp->ifindex;
2289
2290 /* Only advertise in BGP if the knob is enabled */
2291 if (advertise_gw_macip_enabled(zevpn)) {
2292
2293 SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
2294 SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
2295 /* Set Router flag (R-bit) */
2296 if (ip->ipa_type == IPADDR_V6)
2297 SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2298
2299 if (IS_ZEBRA_DEBUG_VXLAN)
2300 zlog_debug(
2301 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
2302 ifp->name, ifp->ifindex, zevpn->vni,
2303 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2304 ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
2305
2306 zebra_evpn_neigh_send_add_to_client(
2307 zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2308 } else if (advertise_svi_macip_enabled(zevpn)) {
2309
2310 SET_FLAG(n->flags, ZEBRA_NEIGH_SVI_IP);
2311 if (IS_ZEBRA_DEBUG_VXLAN)
2312 zlog_debug(
2313 "SVI %s(%u) L2-VNI %u, sending SVI MAC %s IP %s add to BGP with flags 0x%x",
2314 ifp->name, ifp->ifindex, zevpn->vni,
2315 prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2316 ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
2317
2318 zebra_evpn_neigh_send_add_to_client(
2319 zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2320 }
2321
2322 return 0;
2323 }
2324
2325 void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn,
2326 struct zebra_vrf *zvrf, zebra_neigh_t *n,
2327 zebra_mac_t *mac, struct ipaddr *ipaddr)
2328 {
2329 char buf1[INET6_ADDRSTRLEN];
2330
2331 if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)
2332 && CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2333 && (memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN) == 0)) {
2334 struct interface *vlan_if;
2335
2336 vlan_if = zevpn_map_to_svi(zevpn);
2337 if (IS_ZEBRA_DEBUG_VXLAN)
2338 zlog_debug(
2339 "%s: IP %s (flags 0x%x intf %s) is remote and duplicate, read kernel for local entry",
2340 __func__,
2341 ipaddr2str(ipaddr, buf1, sizeof(buf1)),
2342 n->flags, vlan_if ? vlan_if->name : "Unknown");
2343 if (vlan_if)
2344 neigh_read_specific_ip(ipaddr, vlan_if);
2345 }
2346
2347 /* When the MAC changes for an IP, it is possible the
2348 * client may update the new MAC before trying to delete the
2349 * "old" neighbor (as these are two different MACIP routes).
2350 * Do the delete only if the MAC matches.
2351 */
2352 if (!memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN)) {
2353 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2354 zebra_evpn_sync_neigh_del(n);
2355 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2356 zebra_evpn_neigh_uninstall(zevpn, n);
2357 zebra_evpn_neigh_del(zevpn, n);
2358 zebra_evpn_deref_ip2mac(zevpn, mac);
2359 }
2360 }
2361 }
2362
2363 int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip)
2364 {
2365 zebra_neigh_t *n;
2366 zebra_mac_t *zmac;
2367 bool old_bgp_ready;
2368 bool new_bgp_ready;
2369 char buf[INET6_ADDRSTRLEN];
2370 char buf2[ETHER_ADDR_STRLEN];
2371 struct zebra_vrf *zvrf;
2372
2373 /* If entry doesn't exist, nothing to do. */
2374 n = zebra_evpn_neigh_lookup(zevpn, ip);
2375 if (!n)
2376 return 0;
2377
2378 zmac = zebra_evpn_mac_lookup(zevpn, &n->emac);
2379 if (!zmac) {
2380 if (IS_ZEBRA_DEBUG_VXLAN)
2381 zlog_debug(
2382 "Trying to del a neigh %s without a mac %s on VNI %u",
2383 ipaddr2str(ip, buf, sizeof(buf)),
2384 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2385 zevpn->vni);
2386
2387 return 0;
2388 }
2389
2390 /* If it is a remote entry, the kernel has aged this out or someone has
2391 * deleted it, it needs to be re-installed as Quagga is the owner.
2392 */
2393 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2394 zebra_evpn_rem_neigh_install(zevpn, n, false /*was_static*/);
2395 return 0;
2396 }
2397
2398 /* if this is a sync entry it cannot be dropped re-install it in
2399 * the dataplane
2400 */
2401 old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2402 if (zebra_evpn_neigh_is_static(n)) {
2403 if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2404 zlog_debug("re-add sync neigh vni %u ip %s mac %s 0x%x",
2405 n->zevpn->vni,
2406 ipaddr2str(&n->ip, buf, sizeof(buf)),
2407 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2408 n->flags);
2409
2410 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
2411 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
2412 /* inform-bgp about change in local-activity if any */
2413 new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2414 zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
2415 new_bgp_ready);
2416
2417 /* re-install the entry in the kernel */
2418 zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
2419 false /* force_clear_static */,
2420 __func__);
2421
2422 return 0;
2423 }
2424
2425 zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
2426 if (!zvrf) {
2427 zlog_debug("%s: VNI %u vrf lookup failed.", __func__,
2428 zevpn->vni);
2429 return -1;
2430 }
2431
2432 /* In case of feeze action, if local neigh is in duplicate state,
2433 * Mark the Neigh as inactive before sending delete request to BGPd,
2434 * If BGPd has remote entry, it will re-install
2435 */
2436 if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
2437 ZEBRA_NEIGH_SET_INACTIVE(n);
2438
2439 /* Remove neighbor from BGP. */
2440 zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
2441 n->flags, n->state,
2442 false /* force */);
2443
2444 /* Delete this neighbor entry. */
2445 zebra_evpn_neigh_del(zevpn, n);
2446
2447 /* see if the AUTO mac needs to be deleted */
2448 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
2449 && !listcount(zmac->neigh_list))
2450 zebra_evpn_mac_del(zevpn, zmac);
2451
2452 return 0;
2453 }