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  */
neigh_hash_keymake(const void * p)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  */
neigh_cmp(const void * p1,const void * p2)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 
neigh_list_cmp(void * p1,void * p2)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 
zebra_neigh_db_create(const char * desc)87 struct hash *zebra_neigh_db_create(const char *desc)
88 {
89 	return hash_create(neigh_hash_keymake, neigh_cmp, desc);
90 }
91 
num_dup_detected_neighs(zebra_evpn_t * zevpn)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  */
zebra_evpn_find_neigh_addr_width(struct hash_bucket * bucket,void * ctxt)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  */
remote_neigh_count(zebra_mac_t * zmac)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  */
zebra_evpn_rem_neigh_install(zebra_evpn_t * zevpn,zebra_neigh_t * n,bool was_static)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  */
zebra_evpn_install_neigh_hash(struct hash_bucket * bucket,void * ctxt)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  */
zebra_evpn_neigh_alloc(void * p)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 
zebra_evpn_local_neigh_ref_mac(zebra_neigh_t * n,struct ethaddr * macaddr,zebra_mac_t * mac,bool send_mac_update)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 */
zebra_evpn_sync_neigh_dp_install(zebra_neigh_t * n,bool set_inactive,bool force_clear_static,const char * caller)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  */
zebra_evpn_neigh_send_add_to_client(vni_t vni,struct ipaddr * ip,struct ethaddr * macaddr,zebra_mac_t * zmac,uint32_t neigh_flags,uint32_t seq)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  */
zebra_evpn_neigh_send_del_to_client(vni_t vni,struct ipaddr * ip,struct ethaddr * macaddr,uint32_t flags,int state,bool force)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 
zebra_evpn_neigh_send_add_del_to_client(zebra_neigh_t * n,bool old_bgp_ready,bool new_bgp_ready)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  */
zebra_evpn_sync_neigh_static_chg(zebra_neigh_t * n,bool old_n_static,bool new_n_static,bool defer_n_dp,bool defer_mac_dp,const char * caller)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  */
zebra_evpn_neigh_hold_exp_cb(struct thread * t)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 
zebra_evpn_neigh_start_hold_timer(zebra_neigh_t * n)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 
zebra_evpn_local_neigh_deref_mac(zebra_neigh_t * n,bool send_mac_update)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 
zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t * zevpn,zebra_neigh_t * n,struct ethaddr * macaddr,uint32_t seq)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  */
zebra_evpn_neigh_add(zebra_evpn_t * zevpn,struct ipaddr * ip,struct ethaddr * mac,zebra_mac_t * zmac,uint32_t n_flags)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  */
zebra_evpn_neigh_del(zebra_evpn_t * zevpn,zebra_neigh_t * n)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 	/* Cancel proxy hold timer */
618 	zebra_evpn_neigh_stop_hold_timer(n);
619 
620 	/* Free the VNI hash entry and allocated memory. */
621 	tmp_n = hash_release(zevpn->neigh_table, n);
622 	XFREE(MTYPE_NEIGH, tmp_n);
623 
624 	return 0;
625 }
626 
zebra_evpn_sync_neigh_del(zebra_neigh_t * n)627 void zebra_evpn_sync_neigh_del(zebra_neigh_t *n)
628 {
629 	bool old_n_static;
630 	bool new_n_static;
631 	char macbuf[ETHER_ADDR_STRLEN];
632 	char ipbuf[INET6_ADDRSTRLEN];
633 
634 	if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
635 		zlog_debug("sync-neigh del vni %u ip %s mac %s f 0x%x",
636 			   n->zevpn->vni,
637 			   ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
638 			   prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
639 			   n->flags);
640 
641 	old_n_static = zebra_evpn_neigh_is_static(n);
642 	UNSET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
643 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
644 		zebra_evpn_neigh_start_hold_timer(n);
645 	new_n_static = zebra_evpn_neigh_is_static(n);
646 
647 	if (old_n_static != new_n_static)
648 		zebra_evpn_sync_neigh_static_chg(
649 			n, old_n_static, new_n_static, false /*defer-dp*/,
650 			false /*defer_mac_dp*/, __func__);
651 }
652 
653 zebra_neigh_t *
zebra_evpn_proc_sync_neigh_update(zebra_evpn_t * zevpn,zebra_neigh_t * n,uint16_t ipa_len,struct ipaddr * ipaddr,uint8_t flags,uint32_t seq,esi_t * esi,struct sync_mac_ip_ctx * ctx)654 zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
655 				  uint16_t ipa_len, struct ipaddr *ipaddr,
656 				  uint8_t flags, uint32_t seq, esi_t *esi,
657 				  struct sync_mac_ip_ctx *ctx)
658 {
659 	struct interface *ifp = NULL;
660 	bool is_router;
661 	zebra_mac_t *mac = ctx->mac;
662 	uint32_t tmp_seq;
663 	bool old_router = false;
664 	bool old_bgp_ready = false;
665 	bool new_bgp_ready;
666 	bool inform_dataplane = false;
667 	bool inform_bgp = false;
668 	bool old_mac_static;
669 	bool new_mac_static;
670 	bool set_dp_inactive = false;
671 	char macbuf[ETHER_ADDR_STRLEN];
672 	char ipbuf[INET6_ADDRSTRLEN];
673 	bool created;
674 	ifindex_t ifindex = 0;
675 
676 	/* locate l3-svi */
677 	ifp = zevpn_map_to_svi(zevpn);
678 	if (ifp)
679 		ifindex = ifp->ifindex;
680 
681 	is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
682 	old_mac_static = zebra_evpn_mac_is_static(mac);
683 
684 	if (!n) {
685 		uint32_t n_flags = 0;
686 
687 		/* New neighbor - create */
688 		SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL);
689 		if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
690 			SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_PROXY);
691 		else
692 			SET_FLAG(n_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
693 		SET_FLAG(n_flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
694 
695 		n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr, mac,
696 					 n_flags);
697 		n->ifindex = ifindex;
698 		ZEBRA_NEIGH_SET_ACTIVE(n);
699 
700 		created = true;
701 		inform_dataplane = true;
702 		inform_bgp = true;
703 		set_dp_inactive = true;
704 	} else {
705 		bool mac_change;
706 		uint32_t old_flags = n->flags;
707 		bool old_n_static;
708 		bool new_n_static;
709 
710 		created = false;
711 		old_n_static = zebra_evpn_neigh_is_static(n);
712 		old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
713 		old_router = !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
714 
715 		mac_change = !!memcmp(&n->emac, &mac->macaddr, ETH_ALEN);
716 
717 		/* deref and clear old info */
718 		if (mac_change) {
719 			if (old_bgp_ready) {
720 				zebra_evpn_neigh_send_del_to_client(
721 					zevpn->vni, &n->ip, &n->emac, n->flags,
722 					n->state, false /*force*/);
723 				old_bgp_ready = false;
724 			}
725 			if (n->mac)
726 				zebra_evpn_local_neigh_deref_mac(
727 					n, false /*send_mac_update*/);
728 		}
729 		/* clear old fwd info */
730 		n->rem_seq = 0;
731 		n->r_vtep_ip.s_addr = 0;
732 
733 		/* setup new flags */
734 		n->flags = 0;
735 		SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
736 		/* retain activity flag if the neigh was
737 		 * previously local
738 		 */
739 		if (old_flags & ZEBRA_NEIGH_LOCAL) {
740 			n->flags |= (old_flags & ZEBRA_NEIGH_LOCAL_INACTIVE);
741 		} else {
742 			inform_dataplane = true;
743 			set_dp_inactive = true;
744 			n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
745 		}
746 
747 		if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
748 			SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
749 		else
750 			SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
751 
752 		if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
753 			SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
754 			/* if the neigh was peer-active previously we
755 			 * need to keep the flag and start the
756 			 * holdtimer on it. the peer-active flag is
757 			 * cleared on holdtimer expiry.
758 			 */
759 			if (CHECK_FLAG(old_flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
760 				SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
761 				zebra_evpn_neigh_start_hold_timer(n);
762 			}
763 		} else {
764 			SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
765 			/* stop hold timer if a peer has verified
766 			 * reachability
767 			 */
768 			zebra_evpn_neigh_stop_hold_timer(n);
769 		}
770 		ZEBRA_NEIGH_SET_ACTIVE(n);
771 
772 		if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH && (old_flags != n->flags))
773 			zlog_debug(
774 				"sync-neigh vni %u ip %s mac %s old_f 0x%x new_f 0x%x",
775 				n->zevpn->vni,
776 				ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
777 				prefix_mac2str(&n->emac, macbuf,
778 					       sizeof(macbuf)),
779 				old_flags, n->flags);
780 
781 		new_n_static = zebra_evpn_neigh_is_static(n);
782 		if (mac_change) {
783 			set_dp_inactive = true;
784 			n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
785 			inform_dataplane = true;
786 			zebra_evpn_local_neigh_ref_mac(
787 				n, &mac->macaddr, mac,
788 				false /*send_mac_update*/);
789 		} else if (old_n_static != new_n_static) {
790 			inform_dataplane = true;
791 			/* if static flags have changed without a mac change
792 			 * we need to create the correct sync-refs against
793 			 * the existing mac
794 			 */
795 			zebra_evpn_sync_neigh_static_chg(
796 				n, old_n_static, new_n_static,
797 				true /*defer_dp*/, true /*defer_mac_dp*/,
798 				__func__);
799 		}
800 
801 		/* Update the forwarding info. */
802 		if (n->ifindex != ifindex) {
803 			n->ifindex = ifindex;
804 			inform_dataplane = true;
805 		}
806 	}
807 
808 	/* update the neigh seq. we don't bother with the mac seq as
809 	 * sync_mac_update already took care of that
810 	 */
811 	tmp_seq = MAX(n->loc_seq, seq);
812 	if (tmp_seq != n->loc_seq) {
813 		n->loc_seq = tmp_seq;
814 		inform_bgp = true;
815 	}
816 
817 	/* Mark Router flag (R-bit) */
818 	if (is_router)
819 		SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
820 	else
821 		UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
822 
823 	if (old_router != is_router)
824 		inform_dataplane = true;
825 
826 	new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
827 	if (old_bgp_ready != new_bgp_ready)
828 		inform_bgp = true;
829 
830 	new_mac_static = zebra_evpn_mac_is_static(mac);
831 	if ((old_mac_static != new_mac_static) || ctx->mac_dp_update_deferred)
832 		zebra_evpn_sync_mac_dp_install(mac, ctx->mac_inactive,
833 					       false /* force_clear_static */,
834 					       __func__);
835 
836 	if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
837 		zlog_debug(
838 			"sync-neigh %s vni %u ip %s mac %s if %s(%d) seq %d f 0x%x%s%s",
839 			created ? "created" : "updated", n->zevpn->vni,
840 			ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
841 			prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)),
842 			ifp ? ifp->name : "", ifindex, n->loc_seq, n->flags,
843 			inform_bgp ? " inform_bgp" : "",
844 			inform_dataplane ? " inform_dp" : "");
845 
846 	if (inform_dataplane)
847 		zebra_evpn_sync_neigh_dp_install(n, set_dp_inactive,
848 						 false /* force_clear_static */,
849 						 __func__);
850 
851 	if (inform_bgp)
852 		zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
853 							new_bgp_ready);
854 
855 	return n;
856 }
857 
858 /*
859  * Uninstall remote neighbor from the kernel.
860  */
zebra_evpn_neigh_uninstall(zebra_evpn_t * zevpn,zebra_neigh_t * n)861 static int zebra_evpn_neigh_uninstall(zebra_evpn_t *zevpn, zebra_neigh_t *n)
862 {
863 	struct interface *vlan_if;
864 
865 	if (!(n->flags & ZEBRA_NEIGH_REMOTE))
866 		return 0;
867 
868 	vlan_if = zevpn_map_to_svi(zevpn);
869 	if (!vlan_if)
870 		return -1;
871 
872 	ZEBRA_NEIGH_SET_INACTIVE(n);
873 	n->loc_seq = 0;
874 
875 	dplane_rem_neigh_delete(vlan_if, &n->ip);
876 
877 	return 0;
878 }
879 
880 /*
881  * Free neighbor hash entry (callback)
882  */
zebra_evpn_neigh_del_hash_entry(struct hash_bucket * bucket,void * arg)883 static void zebra_evpn_neigh_del_hash_entry(struct hash_bucket *bucket,
884 					    void *arg)
885 {
886 	struct neigh_walk_ctx *wctx = arg;
887 	zebra_neigh_t *n = bucket->data;
888 
889 	if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
890 	    || ((wctx->flags & DEL_REMOTE_NEIGH)
891 		&& (n->flags & ZEBRA_NEIGH_REMOTE))
892 	    || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
893 		&& (n->flags & ZEBRA_NEIGH_REMOTE)
894 		&& IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
895 		if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
896 			zebra_evpn_neigh_send_del_to_client(
897 				wctx->zevpn->vni, &n->ip, &n->emac, n->flags,
898 				n->state, false /*force*/);
899 
900 		if (wctx->uninstall) {
901 			if (zebra_evpn_neigh_is_static(n))
902 				zebra_evpn_sync_neigh_dp_install(
903 					n, false /* set_inactive */,
904 					true /* force_clear_static */,
905 					__func__);
906 			if ((n->flags & ZEBRA_NEIGH_REMOTE))
907 				zebra_evpn_neigh_uninstall(wctx->zevpn, n);
908 		}
909 
910 		zebra_evpn_neigh_del(wctx->zevpn, n);
911 	}
912 
913 	return;
914 }
915 
916 /*
917  * Delete all neighbor entries for this EVPN.
918  */
zebra_evpn_neigh_del_all(zebra_evpn_t * zevpn,int uninstall,int upd_client,uint32_t flags)919 void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall,
920 			      int upd_client, uint32_t flags)
921 {
922 	struct neigh_walk_ctx wctx;
923 
924 	if (!zevpn->neigh_table)
925 		return;
926 
927 	memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
928 	wctx.zevpn = zevpn;
929 	wctx.uninstall = uninstall;
930 	wctx.upd_client = upd_client;
931 	wctx.flags = flags;
932 
933 	hash_iterate(zevpn->neigh_table, zebra_evpn_neigh_del_hash_entry,
934 		     &wctx);
935 }
936 
937 /*
938  * Look up neighbor hash entry.
939  */
zebra_evpn_neigh_lookup(zebra_evpn_t * zevpn,struct ipaddr * ip)940 zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip)
941 {
942 	zebra_neigh_t tmp;
943 	zebra_neigh_t *n;
944 
945 	memset(&tmp, 0, sizeof(tmp));
946 	memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
947 	n = hash_lookup(zevpn->neigh_table, &tmp);
948 
949 	return n;
950 }
951 
952 /*
953  * Process all neighbors associated with a MAC upon the MAC being learnt
954  * locally or undergoing any other change (such as sequence number).
955  */
zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t * zevpn,zebra_mac_t * zmac,bool seq_change,bool es_change)956 void zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn,
957 						  zebra_mac_t *zmac,
958 						  bool seq_change,
959 						  bool es_change)
960 {
961 	zebra_neigh_t *n = NULL;
962 	struct listnode *node = NULL;
963 	struct zebra_vrf *zvrf = NULL;
964 	char buf[ETHER_ADDR_STRLEN];
965 
966 	zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
967 
968 	if (IS_ZEBRA_DEBUG_VXLAN)
969 		zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
970 			   prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
971 			   seq_change ? "CHANGE" : "ADD", zevpn->vni);
972 
973 	/* Walk all neighbors and mark any inactive local neighbors as
974 	 * active and/or update sequence number upon a move, and inform BGP.
975 	 * The action for remote neighbors is TBD.
976 	 * NOTE: We can't simply uninstall remote neighbors as the kernel may
977 	 * accidentally end up deleting a just-learnt local neighbor.
978 	 */
979 	for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
980 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
981 			if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change
982 			    || es_change) {
983 				ZEBRA_NEIGH_SET_ACTIVE(n);
984 				n->loc_seq = zmac->loc_seq;
985 				if (!(zvrf->dup_addr_detect && zvrf->dad_freeze
986 				      && !!CHECK_FLAG(n->flags,
987 						      ZEBRA_NEIGH_DUPLICATE)))
988 					zebra_evpn_neigh_send_add_to_client(
989 						zevpn->vni, &n->ip, &n->emac,
990 						n->mac, n->flags, n->loc_seq);
991 			}
992 		}
993 	}
994 }
995 
996 /*
997  * Process all neighbors associated with a local MAC upon the MAC being
998  * deleted.
999  */
zebra_evpn_process_neigh_on_local_mac_del(zebra_evpn_t * zevpn,zebra_mac_t * zmac)1000 void zebra_evpn_process_neigh_on_local_mac_del(zebra_evpn_t *zevpn,
1001 					       zebra_mac_t *zmac)
1002 {
1003 	zebra_neigh_t *n = NULL;
1004 	struct listnode *node = NULL;
1005 	char buf[ETHER_ADDR_STRLEN];
1006 
1007 	if (IS_ZEBRA_DEBUG_VXLAN)
1008 		zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
1009 			   prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
1010 			   zevpn->vni);
1011 
1012 	/* Walk all local neighbors and mark as inactive and inform
1013 	 * BGP, if needed.
1014 	 * TBD: There is currently no handling for remote neighbors. We
1015 	 * don't expect them to exist, if they do, do we install the MAC
1016 	 * as a remote MAC and the neighbor as remote?
1017 	 */
1018 	for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1019 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1020 			if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1021 				ZEBRA_NEIGH_SET_INACTIVE(n);
1022 				n->loc_seq = 0;
1023 				zebra_evpn_neigh_send_del_to_client(
1024 					zevpn->vni, &n->ip, &n->emac, n->flags,
1025 					ZEBRA_NEIGH_ACTIVE, false /*force*/);
1026 			}
1027 		}
1028 	}
1029 }
1030 
1031 /*
1032  * Process all neighbors associated with a MAC upon the MAC being remotely
1033  * learnt.
1034  */
zebra_evpn_process_neigh_on_remote_mac_add(zebra_evpn_t * zevpn,zebra_mac_t * zmac)1035 void zebra_evpn_process_neigh_on_remote_mac_add(zebra_evpn_t *zevpn,
1036 						zebra_mac_t *zmac)
1037 {
1038 	zebra_neigh_t *n = NULL;
1039 	struct listnode *node = NULL;
1040 	char buf[ETHER_ADDR_STRLEN];
1041 
1042 	if (IS_ZEBRA_DEBUG_VXLAN)
1043 		zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
1044 			   prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
1045 			   zevpn->vni);
1046 
1047 	/* Walk all local neighbors and mark as inactive and inform
1048 	 * BGP, if needed.
1049 	 */
1050 	for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1051 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1052 			if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1053 				ZEBRA_NEIGH_SET_INACTIVE(n);
1054 				n->loc_seq = 0;
1055 				zebra_evpn_neigh_send_del_to_client(
1056 					zevpn->vni, &n->ip, &n->emac, n->flags,
1057 					ZEBRA_NEIGH_ACTIVE, false /* force */);
1058 			}
1059 		}
1060 	}
1061 }
1062 
1063 /*
1064  * Process all neighbors associated with a remote MAC upon the MAC being
1065  * deleted.
1066  */
zebra_evpn_process_neigh_on_remote_mac_del(zebra_evpn_t * zevpn,zebra_mac_t * zmac)1067 void zebra_evpn_process_neigh_on_remote_mac_del(zebra_evpn_t *zevpn,
1068 						zebra_mac_t *zmac)
1069 {
1070 	/* NOTE: Currently a NO-OP. */
1071 }
1072 
zebra_evpn_local_neigh_update_log(const char * pfx,zebra_neigh_t * n,bool is_router,bool local_inactive,bool old_bgp_ready,bool new_bgp_ready,bool inform_dataplane,bool inform_bgp,const char * sfx)1073 static inline void zebra_evpn_local_neigh_update_log(
1074 	const char *pfx, zebra_neigh_t *n, bool is_router, bool local_inactive,
1075 	bool old_bgp_ready, bool new_bgp_ready, bool inform_dataplane,
1076 	bool inform_bgp, const char *sfx)
1077 {
1078 	char macbuf[ETHER_ADDR_STRLEN];
1079 	char ipbuf[INET6_ADDRSTRLEN];
1080 
1081 	if (!IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
1082 		return;
1083 
1084 	zlog_debug("%s neigh vni %u ip %s mac %s f 0x%x%s%s%s%s%s%s %s", pfx,
1085 		   n->zevpn->vni, ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
1086 		   prefix_mac2str(&n->emac, macbuf, sizeof(macbuf)), n->flags,
1087 		   is_router ? " router" : "",
1088 		   local_inactive ? " local-inactive" : "",
1089 		   old_bgp_ready ? " old_bgp_ready" : "",
1090 		   new_bgp_ready ? " new_bgp_ready" : "",
1091 		   inform_dataplane ? " inform_dp" : "",
1092 		   inform_bgp ? " inform_bgp" : "", sfx);
1093 }
1094 
1095 /* As part Duplicate Address Detection (DAD) for IP mobility
1096  * MAC binding changes, ensure to inherit duplicate flag
1097  * from MAC.
1098  */
zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf * zvrf,zebra_mac_t * old_zmac,zebra_mac_t * new_zmac,zebra_neigh_t * nbr)1099 static int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
1100 					      zebra_mac_t *old_zmac,
1101 					      zebra_mac_t *new_zmac,
1102 					      zebra_neigh_t *nbr)
1103 {
1104 	bool is_old_mac_dup = false;
1105 	bool is_new_mac_dup = false;
1106 
1107 	if (!zvrf->dup_addr_detect)
1108 		return 0;
1109 	/* Check old or new MAC is detected as duplicate
1110 	 * mark this neigh as duplicate
1111 	 */
1112 	if (old_zmac)
1113 		is_old_mac_dup =
1114 			CHECK_FLAG(old_zmac->flags, ZEBRA_MAC_DUPLICATE);
1115 	if (new_zmac)
1116 		is_new_mac_dup =
1117 			CHECK_FLAG(new_zmac->flags, ZEBRA_MAC_DUPLICATE);
1118 	/* Old and/or new MAC can be in duplicate state,
1119 	 * based on that IP/Neigh Inherits the flag.
1120 	 * If New MAC is marked duplicate, inherit to the IP.
1121 	 * If old MAC is duplicate but new MAC is not, clear
1122 	 * duplicate flag for IP and reset detection params
1123 	 * and let IP DAD retrigger.
1124 	 */
1125 	if (is_new_mac_dup && !CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1126 		SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1127 		/* Capture Duplicate detection time */
1128 		nbr->dad_dup_detect_time = monotime(NULL);
1129 		/* Mark neigh inactive */
1130 		ZEBRA_NEIGH_SET_INACTIVE(nbr);
1131 
1132 		return 1;
1133 	} else if (is_old_mac_dup && !is_new_mac_dup) {
1134 		UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1135 		nbr->dad_count = 0;
1136 		nbr->detect_start_time.tv_sec = 0;
1137 		nbr->detect_start_time.tv_usec = 0;
1138 	}
1139 	return 0;
1140 }
1141 
zebra_evpn_dad_ip_auto_recovery_exp(struct thread * t)1142 static int zebra_evpn_dad_ip_auto_recovery_exp(struct thread *t)
1143 {
1144 	struct zebra_vrf *zvrf = NULL;
1145 	zebra_neigh_t *nbr = NULL;
1146 	zebra_evpn_t *zevpn = NULL;
1147 	char buf1[INET6_ADDRSTRLEN];
1148 	char buf2[ETHER_ADDR_STRLEN];
1149 
1150 	nbr = THREAD_ARG(t);
1151 
1152 	/* since this is asynchronous we need sanity checks*/
1153 	zvrf = vrf_info_lookup(nbr->zevpn->vrf_id);
1154 	if (!zvrf)
1155 		return 0;
1156 
1157 	zevpn = zebra_evpn_lookup(nbr->zevpn->vni);
1158 	if (!zevpn)
1159 		return 0;
1160 
1161 	nbr = zebra_evpn_neigh_lookup(zevpn, &nbr->ip);
1162 	if (!nbr)
1163 		return 0;
1164 
1165 	if (IS_ZEBRA_DEBUG_VXLAN)
1166 		zlog_debug(
1167 			"%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
1168 			__func__,
1169 			prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)),
1170 			ipaddr2str(&nbr->ip, buf1, sizeof(buf1)), nbr->flags,
1171 			nbr->dad_count, zevpn->vni);
1172 
1173 	UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1174 	nbr->dad_count = 0;
1175 	nbr->detect_start_time.tv_sec = 0;
1176 	nbr->detect_start_time.tv_usec = 0;
1177 	nbr->dad_dup_detect_time = 0;
1178 	nbr->dad_ip_auto_recovery_timer = NULL;
1179 	ZEBRA_NEIGH_SET_ACTIVE(nbr);
1180 
1181 	/* Send to BGP */
1182 	if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1183 		zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1184 						    &nbr->emac, nbr->mac,
1185 						    nbr->flags, nbr->loc_seq);
1186 	} else if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1187 		zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1188 	}
1189 
1190 	return 0;
1191 }
1192 
1193 static void
zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf * zvrf,zebra_neigh_t * nbr,struct in_addr vtep_ip,bool do_dad,bool * is_dup_detect,bool is_local)1194 zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr,
1195 				     struct in_addr vtep_ip, bool do_dad,
1196 				     bool *is_dup_detect, bool is_local)
1197 {
1198 
1199 	struct timeval elapsed = {0, 0};
1200 	char buf[ETHER_ADDR_STRLEN];
1201 	char buf1[INET6_ADDRSTRLEN];
1202 	bool reset_params = false;
1203 
1204 	if (!zvrf->dup_addr_detect)
1205 		return;
1206 
1207 	/* IP is detected as duplicate or inherit dup
1208 	 * state, hold on to install as remote entry
1209 	 * only if freeze is enabled.
1210 	 */
1211 	if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
1212 		if (IS_ZEBRA_DEBUG_VXLAN)
1213 			zlog_debug(
1214 				"%s: duplicate addr MAC %s IP %s flags 0x%x skip installing, learn count %u recover time %u",
1215 				__func__,
1216 				prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1217 				ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1218 				nbr->flags, nbr->dad_count,
1219 				zvrf->dad_freeze_time);
1220 
1221 		if (zvrf->dad_freeze)
1222 			*is_dup_detect = true;
1223 
1224 		/* warn-only action, neigh will be installed.
1225 		 * freeze action, it wil not be installed.
1226 		 */
1227 		return;
1228 	}
1229 
1230 	if (!do_dad)
1231 		return;
1232 
1233 	/* Check if detection time (M-secs) expired.
1234 	 * Reset learn count and detection start time.
1235 	 * During remote mac add, count should already be 1
1236 	 * via local learning.
1237 	 */
1238 	monotime_since(&nbr->detect_start_time, &elapsed);
1239 	reset_params = (elapsed.tv_sec > zvrf->dad_time);
1240 
1241 	if (is_local && !reset_params) {
1242 		/* RFC-7432: A PE/VTEP that detects a MAC mobility
1243 		 * event via LOCAL learning starts an M-second timer.
1244 		 *
1245 		 * NOTE: This is the START of the probe with count is
1246 		 * 0 during LOCAL learn event.
1247 		 */
1248 		reset_params = !nbr->dad_count;
1249 	}
1250 
1251 	if (reset_params) {
1252 		if (IS_ZEBRA_DEBUG_VXLAN)
1253 			zlog_debug(
1254 				"%s: duplicate addr MAC %s IP %s flags 0x%x detection time passed, reset learn count %u",
1255 				__func__,
1256 				prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1257 				ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1258 				nbr->flags, nbr->dad_count);
1259 		/* Reset learn count but do not start detection
1260 		 * during REMOTE learn event.
1261 		 */
1262 		nbr->dad_count = 0;
1263 		/* Start dup. addr detection (DAD) start time,
1264 		 * ONLY during LOCAL learn.
1265 		 */
1266 		if (is_local)
1267 			monotime(&nbr->detect_start_time);
1268 
1269 	} else if (!is_local) {
1270 		/* For REMOTE IP/Neigh, increment detection count
1271 		 * ONLY while in probe window, once window passed,
1272 		 * next local learn event should trigger DAD.
1273 		 */
1274 		nbr->dad_count++;
1275 	}
1276 
1277 	/* For LOCAL IP/Neigh learn event, once count is reset above via either
1278 	 * initial/start detection time or passed the probe time, the count
1279 	 * needs to be incremented.
1280 	 */
1281 	if (is_local)
1282 		nbr->dad_count++;
1283 
1284 	if (nbr->dad_count >= zvrf->dad_max_moves) {
1285 		flog_warn(
1286 			EC_ZEBRA_DUP_IP_DETECTED,
1287 			"VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s",
1288 			nbr->zevpn->vni,
1289 			prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
1290 			ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
1291 			is_local ? "local update, last" : "remote update, from",
1292 			inet_ntoa(vtep_ip));
1293 
1294 		SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1295 
1296 		/* Capture Duplicate detection time */
1297 		nbr->dad_dup_detect_time = monotime(NULL);
1298 
1299 		/* Start auto recovery timer for this IP */
1300 		THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
1301 		if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
1302 			if (IS_ZEBRA_DEBUG_VXLAN)
1303 				zlog_debug(
1304 					"%s: duplicate addr MAC %s IP %s flags 0x%x auto recovery time %u start",
1305 					__func__,
1306 					prefix_mac2str(&nbr->emac, buf,
1307 						       sizeof(buf)),
1308 					ipaddr2str(&nbr->ip, buf1,
1309 						   sizeof(buf1)),
1310 					nbr->flags, zvrf->dad_freeze_time);
1311 
1312 			thread_add_timer(zrouter.master,
1313 					 zebra_evpn_dad_ip_auto_recovery_exp,
1314 					 nbr, zvrf->dad_freeze_time,
1315 					 &nbr->dad_ip_auto_recovery_timer);
1316 		}
1317 		if (zvrf->dad_freeze)
1318 			*is_dup_detect = true;
1319 	}
1320 }
1321 
zebra_evpn_local_neigh_update(zebra_evpn_t * zevpn,struct interface * ifp,struct ipaddr * ip,struct ethaddr * macaddr,bool is_router,bool local_inactive,bool dp_static)1322 int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
1323 				  struct ipaddr *ip, struct ethaddr *macaddr,
1324 				  bool is_router, bool local_inactive,
1325 				  bool dp_static)
1326 {
1327 	char buf[ETHER_ADDR_STRLEN];
1328 	char buf2[INET6_ADDRSTRLEN];
1329 	struct zebra_vrf *zvrf;
1330 	zebra_neigh_t *n = NULL;
1331 	zebra_mac_t *zmac = NULL, *old_zmac = NULL;
1332 	uint32_t old_mac_seq = 0, mac_new_seq = 0;
1333 	bool upd_mac_seq = false;
1334 	bool neigh_mac_change = false;
1335 	bool neigh_on_hold = false;
1336 	bool neigh_was_remote = false;
1337 	bool do_dad = false;
1338 	struct in_addr vtep_ip = {.s_addr = 0};
1339 	bool inform_dataplane = false;
1340 	bool created = false;
1341 	bool new_static = false;
1342 	bool old_bgp_ready = false;
1343 	bool new_bgp_ready;
1344 
1345 	/* Check if the MAC exists. */
1346 	zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1347 	if (!zmac) {
1348 		/* create a dummy MAC if the MAC is not already present */
1349 		if (IS_ZEBRA_DEBUG_VXLAN)
1350 			zlog_debug("AUTO MAC %s created for neigh %s on VNI %u",
1351 				   prefix_mac2str(macaddr, buf, sizeof(buf)),
1352 				   ipaddr2str(ip, buf2, sizeof(buf2)),
1353 				   zevpn->vni);
1354 
1355 		zmac = zebra_evpn_mac_add(zevpn, macaddr);
1356 		if (!zmac) {
1357 			zlog_debug("Failed to add MAC %s VNI %u",
1358 				   prefix_mac2str(macaddr, buf, sizeof(buf)),
1359 				   zevpn->vni);
1360 			return -1;
1361 		}
1362 
1363 		memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
1364 		memset(&zmac->flags, 0, sizeof(uint32_t));
1365 		SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
1366 	} else {
1367 		if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1368 			/*
1369 			 * We don't change the MAC to local upon a neighbor
1370 			 * learn event, we wait for the explicit local MAC
1371 			 * learn. However, we have to compute its sequence
1372 			 * number in preparation for when it actually turns
1373 			 * local.
1374 			 */
1375 			upd_mac_seq = true;
1376 		}
1377 	}
1378 
1379 	zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
1380 	if (!zvrf) {
1381 		if (IS_ZEBRA_DEBUG_VXLAN)
1382 			zlog_debug("        Unable to find vrf for: %d",
1383 				   zevpn->vxlan_if->vrf_id);
1384 		return -1;
1385 	}
1386 
1387 	/* Check if the neighbor exists. */
1388 	n = zebra_evpn_neigh_lookup(zevpn, ip);
1389 	if (!n) {
1390 		/* New neighbor - create */
1391 		n = zebra_evpn_neigh_add(zevpn, ip, macaddr, zmac, 0);
1392 		if (!n) {
1393 			flog_err(
1394 				EC_ZEBRA_MAC_ADD_FAILED,
1395 				"Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1396 				ipaddr2str(ip, buf2, sizeof(buf2)),
1397 				prefix_mac2str(macaddr, buf, sizeof(buf)),
1398 				ifp->name, ifp->ifindex, zevpn->vni);
1399 			return -1;
1400 		}
1401 		/* Set "local" forwarding info. */
1402 		SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1403 		n->ifindex = ifp->ifindex;
1404 		created = true;
1405 	} else {
1406 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1407 			bool mac_different;
1408 			bool cur_is_router;
1409 			bool old_local_inactive;
1410 
1411 			old_local_inactive = !!CHECK_FLAG(
1412 				n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1413 
1414 			old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1415 
1416 			/* Note any changes and see if of interest to BGP. */
1417 			mac_different = !!memcmp(&n->emac, macaddr, ETH_ALEN);
1418 			cur_is_router =
1419 				!!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1420 			new_static = zebra_evpn_neigh_is_static(n);
1421 			if (!mac_different && is_router == cur_is_router
1422 			    && old_local_inactive == local_inactive
1423 			    && dp_static != new_static) {
1424 				if (IS_ZEBRA_DEBUG_VXLAN)
1425 					zlog_debug(
1426 						"        Ignoring entry mac is the same and is_router == cur_is_router");
1427 				n->ifindex = ifp->ifindex;
1428 				return 0;
1429 			}
1430 
1431 			old_zmac = n->mac;
1432 			if (!mac_different) {
1433 				/* XXX - cleanup this code duplication */
1434 				bool is_neigh_freezed = false;
1435 
1436 				/* Only the router flag has changed. */
1437 				if (is_router)
1438 					SET_FLAG(n->flags,
1439 						 ZEBRA_NEIGH_ROUTER_FLAG);
1440 				else
1441 					UNSET_FLAG(n->flags,
1442 						   ZEBRA_NEIGH_ROUTER_FLAG);
1443 
1444 				if (local_inactive)
1445 					SET_FLAG(n->flags,
1446 						 ZEBRA_NEIGH_LOCAL_INACTIVE);
1447 				else
1448 					UNSET_FLAG(n->flags,
1449 						   ZEBRA_NEIGH_LOCAL_INACTIVE);
1450 				new_bgp_ready =
1451 					zebra_evpn_neigh_is_ready_for_bgp(n);
1452 
1453 				/* Neigh is in freeze state and freeze action
1454 				 * is enabled, do not send update to client.
1455 				 */
1456 				is_neigh_freezed =
1457 					(zvrf->dup_addr_detect
1458 					 && zvrf->dad_freeze
1459 					 && CHECK_FLAG(n->flags,
1460 						       ZEBRA_NEIGH_DUPLICATE));
1461 
1462 				zebra_evpn_local_neigh_update_log(
1463 					"local", n, is_router, local_inactive,
1464 					old_bgp_ready, new_bgp_ready, false,
1465 					false, "flag-update");
1466 
1467 				/* if the neigh can no longer be advertised
1468 				 * remove it from bgp
1469 				 */
1470 				if (!is_neigh_freezed) {
1471 					zebra_evpn_neigh_send_add_del_to_client(
1472 						n, old_bgp_ready,
1473 						new_bgp_ready);
1474 				} else {
1475 					if (IS_ZEBRA_DEBUG_VXLAN
1476 					    && IS_ZEBRA_NEIGH_ACTIVE(n))
1477 						zlog_debug(
1478 							"        Neighbor active and frozen");
1479 				}
1480 				return 0;
1481 			}
1482 
1483 			/* The MAC has changed, need to issue a delete
1484 			 * first as this means a different MACIP route.
1485 			 * Also, need to do some unlinking/relinking.
1486 			 * We also need to update the MAC's sequence number
1487 			 * in different situations.
1488 			 */
1489 			if (old_bgp_ready) {
1490 				zebra_evpn_neigh_send_del_to_client(
1491 					zevpn->vni, &n->ip, &n->emac, n->flags,
1492 					n->state, false /*force*/);
1493 				old_bgp_ready = false;
1494 			}
1495 			if (old_zmac) {
1496 				old_mac_seq = CHECK_FLAG(old_zmac->flags,
1497 							 ZEBRA_MAC_REMOTE)
1498 						      ? old_zmac->rem_seq
1499 						      : old_zmac->loc_seq;
1500 				neigh_mac_change = upd_mac_seq = true;
1501 				zebra_evpn_local_neigh_deref_mac(
1502 					n, true /* send_mac_update */);
1503 			}
1504 
1505 			/* if mac changes abandon peer flags and tell
1506 			 * dataplane to clear the static flag
1507 			 */
1508 			if (zebra_evpn_neigh_clear_sync_info(n))
1509 				inform_dataplane = true;
1510 			/* Update the forwarding info. */
1511 			n->ifindex = ifp->ifindex;
1512 
1513 			/* Link to new MAC */
1514 			zebra_evpn_local_neigh_ref_mac(
1515 				n, macaddr, zmac, true /* send_mac_update */);
1516 		} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1517 			/*
1518 			 * Neighbor has moved from remote to local. Its
1519 			 * MAC could have also changed as part of the move.
1520 			 */
1521 			if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN)
1522 			    != 0) {
1523 				old_zmac = n->mac;
1524 				if (old_zmac) {
1525 					old_mac_seq =
1526 						CHECK_FLAG(old_zmac->flags,
1527 							   ZEBRA_MAC_REMOTE)
1528 							? old_zmac->rem_seq
1529 							: old_zmac->loc_seq;
1530 					neigh_mac_change = upd_mac_seq = true;
1531 					zebra_evpn_local_neigh_deref_mac(
1532 						n, true /* send_update */);
1533 				}
1534 
1535 				/* Link to new MAC */
1536 				zebra_evpn_local_neigh_ref_mac(
1537 					n, macaddr, zmac, true /*send_update*/);
1538 			}
1539 			/* Based on Mobility event Scenario-B from the
1540 			 * draft, neigh's previous state was remote treat this
1541 			 * event for DAD.
1542 			 */
1543 			neigh_was_remote = true;
1544 			vtep_ip = n->r_vtep_ip;
1545 			/* Mark appropriately */
1546 			UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1547 			n->r_vtep_ip.s_addr = INADDR_ANY;
1548 			SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1549 			n->ifindex = ifp->ifindex;
1550 		}
1551 	}
1552 
1553 	/* If MAC was previously remote, or the neighbor had a different
1554 	 * MAC earlier, recompute the sequence number.
1555 	 */
1556 	if (upd_mac_seq) {
1557 		uint32_t seq1, seq2;
1558 
1559 		seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)
1560 			       ? zmac->rem_seq + 1
1561 			       : zmac->loc_seq;
1562 		seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
1563 		mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ? MAX(seq1, seq2)
1564 							      : zmac->loc_seq;
1565 	}
1566 
1567 	if (local_inactive)
1568 		SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1569 	else
1570 		UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
1571 
1572 	/* Mark Router flag (R-bit) */
1573 	if (is_router)
1574 		SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1575 	else
1576 		UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
1577 
1578 	/* if the dataplane thinks that this is a sync entry but
1579 	 * zebra doesn't we need to re-concile the diff
1580 	 * by re-installing the dataplane entry
1581 	 */
1582 	if (dp_static) {
1583 		new_static = zebra_evpn_neigh_is_static(n);
1584 		if (!new_static)
1585 			inform_dataplane = true;
1586 	}
1587 
1588 	/* Check old and/or new MAC detected as duplicate mark
1589 	 * the neigh as duplicate
1590 	 */
1591 	if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_zmac, zmac, n)) {
1592 		flog_warn(
1593 			EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
1594 			"VNI %u: MAC %s IP %s detected as duplicate during local update, inherit duplicate from MAC",
1595 			zevpn->vni, prefix_mac2str(macaddr, buf, sizeof(buf)),
1596 			ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1597 	}
1598 
1599 	/* For IP Duplicate Address Detection (DAD) is trigger,
1600 	 * when the event is extended mobility based on scenario-B
1601 	 * from the draft, IP/Neigh's MAC binding changed and
1602 	 * neigh's previous state was remote.
1603 	 */
1604 	if (neigh_mac_change && neigh_was_remote)
1605 		do_dad = true;
1606 
1607 	zebra_evpn_dup_addr_detect_for_neigh(zvrf, n, vtep_ip, do_dad,
1608 					     &neigh_on_hold, true);
1609 
1610 	if (inform_dataplane)
1611 		zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
1612 						 false /* force_clear_static */,
1613 						 __func__);
1614 
1615 	/* Before we program this in BGP, we need to check if MAC is locally
1616 	 * learnt. If not, force neighbor to be inactive and reset its seq.
1617 	 */
1618 	if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
1619 		zebra_evpn_local_neigh_update_log(
1620 			"local", n, is_router, local_inactive, false, false,
1621 			inform_dataplane, false, "auto-mac");
1622 		ZEBRA_NEIGH_SET_INACTIVE(n);
1623 		n->loc_seq = 0;
1624 		zmac->loc_seq = mac_new_seq;
1625 		return 0;
1626 	}
1627 
1628 	zebra_evpn_local_neigh_update_log("local", n, is_router, local_inactive,
1629 					  false, false, inform_dataplane, true,
1630 					  created ? "created" : "updated");
1631 
1632 	/* If the MAC's sequence number has changed, inform the MAC and all
1633 	 * neighbors associated with the MAC to BGP, else just inform this
1634 	 * neighbor.
1635 	 */
1636 	if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
1637 		if (IS_ZEBRA_DEBUG_VXLAN)
1638 			zlog_debug(
1639 				"Seq changed for MAC %s VNI %u - old %u new %u",
1640 				prefix_mac2str(macaddr, buf, sizeof(buf)),
1641 				zevpn->vni, zmac->loc_seq, mac_new_seq);
1642 		zmac->loc_seq = mac_new_seq;
1643 		if (zebra_evpn_mac_send_add_to_client(zevpn->vni, macaddr,
1644 						      zmac->flags,
1645 						      zmac->loc_seq, zmac->es))
1646 			return -1;
1647 		zebra_evpn_process_neigh_on_local_mac_change(zevpn, zmac, 1,
1648 							     0 /*es_change*/);
1649 		return 0;
1650 	}
1651 
1652 	n->loc_seq = zmac->loc_seq;
1653 
1654 	if (!neigh_on_hold) {
1655 		ZEBRA_NEIGH_SET_ACTIVE(n);
1656 		new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
1657 		zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
1658 							new_bgp_ready);
1659 	} else {
1660 		if (IS_ZEBRA_DEBUG_VXLAN)
1661 			zlog_debug("        Neighbor on hold not sending");
1662 	}
1663 	return 0;
1664 }
1665 
zebra_evpn_remote_neigh_update(zebra_evpn_t * zevpn,struct interface * ifp,struct ipaddr * ip,struct ethaddr * macaddr,uint16_t state)1666 int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
1667 				   struct ipaddr *ip, struct ethaddr *macaddr,
1668 				   uint16_t state)
1669 {
1670 	char buf[ETHER_ADDR_STRLEN];
1671 	char buf2[INET6_ADDRSTRLEN];
1672 	zebra_neigh_t *n = NULL;
1673 	zebra_mac_t *zmac = NULL;
1674 
1675 	/* If the neighbor is unknown, there is no further action. */
1676 	n = zebra_evpn_neigh_lookup(zevpn, ip);
1677 	if (!n)
1678 		return 0;
1679 
1680 	/* If a remote entry, see if it needs to be refreshed */
1681 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1682 #ifdef GNU_LINUX
1683 		if (state & NUD_STALE)
1684 			zebra_evpn_rem_neigh_install(zevpn, n,
1685 						     false /*was_static*/);
1686 #endif
1687 	} else {
1688 		/* We got a "remote" neighbor notification for an entry
1689 		 * we think is local. This can happen in a multihoming
1690 		 * scenario - but only if the MAC is already "remote".
1691 		 * Just mark our entry as "remote".
1692 		 */
1693 		zmac = zebra_evpn_mac_lookup(zevpn, macaddr);
1694 		if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
1695 			zlog_debug(
1696 				"Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
1697 				ipaddr2str(&n->ip, buf2, sizeof(buf2)),
1698 				prefix_mac2str(macaddr, buf, sizeof(buf)),
1699 				zevpn->vni);
1700 			return -1;
1701 		}
1702 
1703 		UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
1704 		SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1705 		ZEBRA_NEIGH_SET_ACTIVE(n);
1706 		n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
1707 	}
1708 
1709 	return 0;
1710 }
1711 
1712 /* Notify Neighbor entries to the Client, skips the GW entry */
1713 static void
zebra_evpn_send_neigh_hash_entry_to_client(struct hash_bucket * bucket,void * arg)1714 zebra_evpn_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
1715 					   void *arg)
1716 {
1717 	struct mac_walk_ctx *wctx = arg;
1718 	zebra_neigh_t *zn = bucket->data;
1719 	zebra_mac_t *zmac = NULL;
1720 
1721 	if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
1722 		return;
1723 
1724 	if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL)
1725 	    && IS_ZEBRA_NEIGH_ACTIVE(zn)) {
1726 		zmac = zebra_evpn_mac_lookup(wctx->zevpn, &zn->emac);
1727 		if (!zmac)
1728 			return;
1729 
1730 		zebra_evpn_neigh_send_add_to_client(wctx->zevpn->vni, &zn->ip,
1731 						    &zn->emac, zn->mac,
1732 						    zn->flags, zn->loc_seq);
1733 	}
1734 }
1735 
1736 /* Iterator of a specific EVPN */
zebra_evpn_send_neigh_to_client(zebra_evpn_t * zevpn)1737 void zebra_evpn_send_neigh_to_client(zebra_evpn_t *zevpn)
1738 {
1739 	struct neigh_walk_ctx wctx;
1740 
1741 	memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1742 	wctx.zevpn = zevpn;
1743 
1744 	hash_iterate(zevpn->neigh_table,
1745 		     zebra_evpn_send_neigh_hash_entry_to_client, &wctx);
1746 }
1747 
zebra_evpn_clear_dup_neigh_hash(struct hash_bucket * bucket,void * ctxt)1748 void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1749 {
1750 	struct neigh_walk_ctx *wctx = ctxt;
1751 	zebra_neigh_t *nbr;
1752 	zebra_evpn_t *zevpn;
1753 	char buf[INET6_ADDRSTRLEN];
1754 
1755 	nbr = (zebra_neigh_t *)bucket->data;
1756 	if (!nbr)
1757 		return;
1758 
1759 	zevpn = wctx->zevpn;
1760 
1761 	if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
1762 		return;
1763 
1764 	if (IS_ZEBRA_DEBUG_VXLAN) {
1765 		ipaddr2str(&nbr->ip, buf, sizeof(buf));
1766 		zlog_debug("%s: clear neigh %s dup state, flags 0x%x seq %u",
1767 			   __func__, buf, nbr->flags, nbr->loc_seq);
1768 	}
1769 
1770 	UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
1771 	nbr->dad_count = 0;
1772 	nbr->detect_start_time.tv_sec = 0;
1773 	nbr->detect_start_time.tv_usec = 0;
1774 	nbr->dad_dup_detect_time = 0;
1775 	THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
1776 
1777 	if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
1778 		zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
1779 						    &nbr->emac, nbr->mac,
1780 						    nbr->flags, nbr->loc_seq);
1781 	} else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) {
1782 		zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
1783 	}
1784 }
1785 
1786 /*
1787  * Print a specific neighbor entry.
1788  */
zebra_evpn_print_neigh(zebra_neigh_t * n,void * ctxt,json_object * json)1789 void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
1790 {
1791 	struct vty *vty;
1792 	char buf1[ETHER_ADDR_STRLEN];
1793 	char buf2[INET6_ADDRSTRLEN];
1794 	const char *type_str;
1795 	const char *state_str;
1796 	bool flags_present = false;
1797 	struct zebra_vrf *zvrf = NULL;
1798 	struct timeval detect_start_time = {0, 0};
1799 	char timebuf[MONOTIME_STRLEN];
1800 	char thread_buf[THREAD_TIMER_STRLEN];
1801 
1802 	zvrf = zebra_vrf_get_evpn();
1803 	if (!zvrf)
1804 		return;
1805 
1806 	ipaddr2str(&n->ip, buf2, sizeof(buf2));
1807 	prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1808 	type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote";
1809 	state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1810 	vty = (struct vty *)ctxt;
1811 	if (json == NULL) {
1812 		bool sync_info = false;
1813 
1814 		vty_out(vty, "IP: %s\n",
1815 			ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1816 		vty_out(vty, " Type: %s\n", type_str);
1817 		vty_out(vty, " State: %s\n", state_str);
1818 		vty_out(vty, " MAC: %s\n",
1819 			prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
1820 		vty_out(vty, " Sync-info:");
1821 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE)) {
1822 			vty_out(vty, " local-inactive");
1823 			sync_info = true;
1824 		}
1825 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY)) {
1826 			vty_out(vty, " peer-proxy");
1827 			sync_info = true;
1828 		}
1829 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE)) {
1830 			vty_out(vty, " peer-active");
1831 			sync_info = true;
1832 		}
1833 		if (n->hold_timer) {
1834 			vty_out(vty, " (ht: %s)",
1835 				thread_timer_to_hhmmss(thread_buf,
1836 						       sizeof(thread_buf),
1837 						       n->hold_timer));
1838 			sync_info = true;
1839 		}
1840 		if (!sync_info)
1841 			vty_out(vty, " -");
1842 		vty_out(vty, "\n");
1843 	} else {
1844 		json_object_string_add(json, "ip", buf2);
1845 		json_object_string_add(json, "type", type_str);
1846 		json_object_string_add(json, "state", state_str);
1847 		json_object_string_add(json, "mac", buf1);
1848 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
1849 			json_object_boolean_true_add(json, "localInactive");
1850 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY))
1851 			json_object_boolean_true_add(json, "peerProxy");
1852 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE))
1853 			json_object_boolean_true_add(json, "peerActive");
1854 		if (n->hold_timer)
1855 			json_object_string_add(
1856 				json, "peerActiveHold",
1857 				thread_timer_to_hhmmss(thread_buf,
1858 						       sizeof(thread_buf),
1859 						       n->hold_timer));
1860 	}
1861 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1862 		if (n->mac->es) {
1863 			if (json)
1864 				json_object_string_add(json, "remoteEs",
1865 						       n->mac->es->esi_str);
1866 			else
1867 				vty_out(vty, " Remote ES: %s\n",
1868 					n->mac->es->esi_str);
1869 		} else {
1870 			if (json)
1871 				json_object_string_add(json, "remoteVtep",
1872 						       inet_ntoa(n->r_vtep_ip));
1873 			else
1874 				vty_out(vty, " Remote VTEP: %s\n",
1875 					inet_ntoa(n->r_vtep_ip));
1876 		}
1877 	}
1878 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
1879 		if (!json) {
1880 			vty_out(vty, " Flags: Default-gateway");
1881 			flags_present = true;
1882 		} else
1883 			json_object_boolean_true_add(json, "defaultGateway");
1884 	}
1885 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
1886 		if (!json) {
1887 			vty_out(vty,
1888 				flags_present ? " ,Router" : " Flags: Router");
1889 			flags_present = true;
1890 		}
1891 	}
1892 	if (json == NULL) {
1893 		if (flags_present)
1894 			vty_out(vty, "\n");
1895 		vty_out(vty, " Local Seq: %u Remote Seq: %u\n", n->loc_seq,
1896 			n->rem_seq);
1897 
1898 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
1899 			vty_out(vty, " Duplicate, detected at %s",
1900 				time_to_string(n->dad_dup_detect_time,
1901 					       timebuf));
1902 		} else if (n->dad_count) {
1903 			monotime_since(&n->detect_start_time,
1904 				       &detect_start_time);
1905 			if (detect_start_time.tv_sec <= zvrf->dad_time) {
1906 				time_to_string(n->detect_start_time.tv_sec,
1907 					       timebuf);
1908 				vty_out(vty,
1909 					" Duplicate detection started at %s, detection count %u\n",
1910 					timebuf, n->dad_count);
1911 			}
1912 		}
1913 	} else {
1914 		json_object_int_add(json, "localSequence", n->loc_seq);
1915 		json_object_int_add(json, "remoteSequence", n->rem_seq);
1916 		json_object_int_add(json, "detectionCount", n->dad_count);
1917 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1918 			json_object_boolean_true_add(json, "isDuplicate");
1919 		else
1920 			json_object_boolean_false_add(json, "isDuplicate");
1921 	}
1922 }
1923 
zebra_evpn_print_neigh_hdr(struct vty * vty,struct neigh_walk_ctx * wctx)1924 void zebra_evpn_print_neigh_hdr(struct vty *vty, struct neigh_walk_ctx *wctx)
1925 {
1926 	vty_out(vty, "Flags: I=local-inactive, P=peer-active, X=peer-proxy\n");
1927 	vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %s\n", -wctx->addr_width,
1928 		"Neighbor", "Type", "Flags", "State", "MAC", "Remote ES/VTEP",
1929 		"Seq #'s");
1930 }
1931 
zebra_evpn_print_neigh_flags(zebra_neigh_t * n,char * flags_buf,uint32_t flags_buf_sz)1932 static char *zebra_evpn_print_neigh_flags(zebra_neigh_t *n, char *flags_buf,
1933 		uint32_t flags_buf_sz)
1934 {
1935 	snprintf(flags_buf, flags_buf_sz, "%s%s%s",
1936 			(n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE) ?
1937 			"P" : "",
1938 			(n->flags & ZEBRA_NEIGH_ES_PEER_PROXY) ?
1939 			"X" : "",
1940 			(n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) ?
1941 			"I" : "");
1942 
1943 	return flags_buf;
1944 }
1945 
1946 /*
1947  * Print neighbor hash entry - called for display of all neighbors.
1948  */
zebra_evpn_print_neigh_hash(struct hash_bucket * bucket,void * ctxt)1949 void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
1950 {
1951 	struct vty *vty;
1952 	json_object *json_evpn = NULL, *json_row = NULL;
1953 	zebra_neigh_t *n;
1954 	char buf1[ETHER_ADDR_STRLEN];
1955 	char buf2[INET6_ADDRSTRLEN];
1956 	struct neigh_walk_ctx *wctx = ctxt;
1957 	const char *state_str;
1958 	char flags_buf[6];
1959 
1960 	vty = wctx->vty;
1961 	json_evpn = wctx->json;
1962 	n = (zebra_neigh_t *)bucket->data;
1963 
1964 	if (json_evpn)
1965 		json_row = json_object_new_object();
1966 
1967 	prefix_mac2str(&n->emac, buf1, sizeof(buf1));
1968 	ipaddr2str(&n->ip, buf2, sizeof(buf2));
1969 	state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
1970 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1971 		if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
1972 			return;
1973 
1974 		if (json_evpn == NULL) {
1975 			vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
1976 				-wctx->addr_width, buf2, "local",
1977 				zebra_evpn_print_neigh_flags(n, flags_buf,
1978                     sizeof(flags_buf)), state_str, buf1,
1979                     "", n->loc_seq, n->rem_seq);
1980 		} else {
1981 			json_object_string_add(json_row, "type", "local");
1982 			json_object_string_add(json_row, "state", state_str);
1983 			json_object_string_add(json_row, "mac", buf1);
1984 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
1985 				json_object_boolean_true_add(json_row,
1986 							     "defaultGateway");
1987 			json_object_int_add(json_row, "localSequence",
1988 					    n->loc_seq);
1989 			json_object_int_add(json_row, "remoteSequence",
1990 					    n->rem_seq);
1991 			json_object_int_add(json_row, "detectionCount",
1992 					    n->dad_count);
1993 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
1994 				json_object_boolean_true_add(json_row,
1995 							     "isDuplicate");
1996 			else
1997 				json_object_boolean_false_add(json_row,
1998 							      "isDuplicate");
1999 		}
2000 		wctx->count++;
2001 	} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2002 		if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
2003 		    && !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
2004 			return;
2005 
2006 		if (json_evpn == NULL) {
2007 			if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
2008 			    && (wctx->count == 0))
2009 				zebra_evpn_print_neigh_hdr(vty, wctx);
2010 			vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
2011 				-wctx->addr_width, buf2, "remote",
2012 				zebra_evpn_print_neigh_flags(n, flags_buf,
2013 				sizeof(flags_buf)), state_str, buf1,
2014 				n->mac->es ? n->mac->es->esi_str
2015 					   : inet_ntoa(n->r_vtep_ip),
2016 				n->loc_seq, n->rem_seq);
2017 		} else {
2018 			json_object_string_add(json_row, "type", "remote");
2019 			json_object_string_add(json_row, "state", state_str);
2020 			json_object_string_add(json_row, "mac", buf1);
2021 			if (n->mac->es)
2022 				json_object_string_add(json_row, "remoteEs",
2023 						       n->mac->es->esi_str);
2024 			else
2025 				json_object_string_add(json_row, "remoteVtep",
2026 						       inet_ntoa(n->r_vtep_ip));
2027 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
2028 				json_object_boolean_true_add(json_row,
2029 							     "defaultGateway");
2030 			json_object_int_add(json_row, "localSequence",
2031 					    n->loc_seq);
2032 			json_object_int_add(json_row, "remoteSequence",
2033 					    n->rem_seq);
2034 			json_object_int_add(json_row, "detectionCount",
2035 					    n->dad_count);
2036 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
2037 				json_object_boolean_true_add(json_row,
2038 							     "isDuplicate");
2039 			else
2040 				json_object_boolean_false_add(json_row,
2041 							      "isDuplicate");
2042 		}
2043 		wctx->count++;
2044 	}
2045 
2046 	if (json_evpn)
2047 		json_object_object_add(json_evpn, buf2, json_row);
2048 }
2049 
2050 /*
2051  * Print neighbor hash entry in detail - called for display of all neighbors.
2052  */
zebra_evpn_print_neigh_hash_detail(struct hash_bucket * bucket,void * ctxt)2053 void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt)
2054 {
2055 	struct vty *vty;
2056 	json_object *json_evpn = NULL, *json_row = NULL;
2057 	zebra_neigh_t *n;
2058 	char buf[INET6_ADDRSTRLEN];
2059 	struct neigh_walk_ctx *wctx = ctxt;
2060 
2061 	vty = wctx->vty;
2062 	json_evpn = wctx->json;
2063 	n = (zebra_neigh_t *)bucket->data;
2064 	if (!n)
2065 		return;
2066 
2067 	ipaddr2str(&n->ip, buf, sizeof(buf));
2068 	if (json_evpn)
2069 		json_row = json_object_new_object();
2070 
2071 	zebra_evpn_print_neigh(n, vty, json_row);
2072 
2073 	if (json_evpn)
2074 		json_object_object_add(json_evpn, buf, json_row);
2075 }
2076 
zebra_evpn_print_dad_neigh_hash(struct hash_bucket * bucket,void * ctxt)2077 void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt)
2078 {
2079 	zebra_neigh_t *nbr;
2080 
2081 	nbr = (zebra_neigh_t *)bucket->data;
2082 	if (!nbr)
2083 		return;
2084 
2085 	if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2086 		zebra_evpn_print_neigh_hash(bucket, ctxt);
2087 }
2088 
zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket * bucket,void * ctxt)2089 void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
2090 					    void *ctxt)
2091 {
2092 	zebra_neigh_t *nbr;
2093 
2094 	nbr = (zebra_neigh_t *)bucket->data;
2095 	if (!nbr)
2096 		return;
2097 
2098 	if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
2099 		zebra_evpn_print_neigh_hash_detail(bucket, ctxt);
2100 }
2101 
process_neigh_remote_macip_add(zebra_evpn_t * zevpn,struct zebra_vrf * zvrf,struct ipaddr * ipaddr,zebra_mac_t * mac,struct in_addr vtep_ip,uint8_t flags,uint32_t seq)2102 void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
2103 				    struct ipaddr *ipaddr, zebra_mac_t *mac,
2104 				    struct in_addr vtep_ip, uint8_t flags,
2105 				    uint32_t seq)
2106 {
2107 	zebra_neigh_t *n;
2108 	int update_neigh = 0;
2109 	uint32_t tmp_seq;
2110 	char buf[ETHER_ADDR_STRLEN];
2111 	char buf1[INET6_ADDRSTRLEN];
2112 	zebra_mac_t *old_mac = NULL;
2113 	bool old_static = false;
2114 	bool do_dad = false;
2115 	bool is_dup_detect = false;
2116 	bool is_router;
2117 
2118 	assert(mac);
2119 	is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
2120 
2121 	/* Check if the remote neighbor itself is unknown or has a
2122 	 * change. If so, create or update and then install the entry.
2123 	 */
2124 	n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
2125 	if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2126 	    || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
2127 	    || (memcmp(&n->emac, &mac->macaddr, sizeof(struct ethaddr)) != 0)
2128 	    || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) || seq != n->rem_seq)
2129 		update_neigh = 1;
2130 
2131 	if (update_neigh) {
2132 		if (!n) {
2133 			n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr,
2134 						 mac, 0);
2135 			if (!n) {
2136 				zlog_warn(
2137 					"Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2138 					ipaddr2str(ipaddr, buf1, sizeof(buf1)),
2139 					prefix_mac2str(&mac->macaddr, buf,
2140 						       sizeof(buf)),
2141 					zevpn->vni, inet_ntoa(vtep_ip));
2142 				return;
2143 			}
2144 
2145 		} else {
2146 			const char *n_type;
2147 
2148 			/* When host moves but changes its (MAC,IP)
2149 			 * binding, BGP may install a MACIP entry that
2150 			 * corresponds to "older" location of the host
2151 			 * in transient situations (because {IP1,M1}
2152 			 * is a different route from {IP1,M2}). Check
2153 			 * the sequence number and ignore this update
2154 			 * if appropriate.
2155 			 */
2156 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2157 				tmp_seq = n->loc_seq;
2158 				n_type = "local";
2159 			} else {
2160 				tmp_seq = n->rem_seq;
2161 				n_type = "remote";
2162 			}
2163 			if (seq < tmp_seq) {
2164 				if (IS_ZEBRA_DEBUG_VXLAN)
2165 					zlog_debug(
2166 						"Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
2167 						zevpn->vni,
2168 						prefix_mac2str(&mac->macaddr,
2169 							       buf,
2170 							       sizeof(buf)),
2171 						" IP ",
2172 						ipaddr2str(ipaddr, buf1,
2173 							   sizeof(buf1)),
2174 						n_type, tmp_seq);
2175 				return;
2176 			}
2177 			if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2178 				old_static = zebra_evpn_neigh_is_static(n);
2179 				if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2180 					zlog_debug(
2181 						"sync->remote neigh vni %u ip %s mac %s seq %d f0x%x",
2182 						n->zevpn->vni,
2183 						ipaddr2str(&n->ip, buf1,
2184 							   sizeof(buf1)),
2185 						prefix_mac2str(&n->emac, buf,
2186 							       sizeof(buf)),
2187 						seq, n->flags);
2188 				zebra_evpn_neigh_clear_sync_info(n);
2189 				if (IS_ZEBRA_NEIGH_ACTIVE(n))
2190 					zebra_evpn_neigh_send_del_to_client(
2191 						zevpn->vni, &n->ip, &n->emac,
2192 						n->flags, n->state,
2193 						false /*force*/);
2194 			}
2195 			if (memcmp(&n->emac, &mac->macaddr,
2196 				   sizeof(struct ethaddr))
2197 			    != 0) {
2198 				/* update neigh list for macs */
2199 				old_mac =
2200 					zebra_evpn_mac_lookup(zevpn, &n->emac);
2201 				if (old_mac) {
2202 					listnode_delete(old_mac->neigh_list, n);
2203 					n->mac = NULL;
2204 					zebra_evpn_deref_ip2mac(zevpn, old_mac);
2205 				}
2206 				n->mac = mac;
2207 				listnode_add_sort(mac->neigh_list, n);
2208 				memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2209 
2210 				/* Check Neigh's curent state is local
2211 				 * (this is the case where neigh/host has  moved
2212 				 * from L->R) and check previous detction
2213 				 * started via local learning.
2214 				 *
2215 				 * RFC-7432: A PE/VTEP that detects a MAC
2216 				 * mobilit event via local learning starts
2217 				 * an M-second timer.
2218 				 * VTEP-IP or seq. change along is not
2219 				 * considered for dup. detection.
2220 				 *
2221 				 * Mobilty event scenario-B IP-MAC binding
2222 				 * changed.
2223 				 */
2224 				if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
2225 				    && n->dad_count)
2226 					do_dad = true;
2227 			}
2228 		}
2229 
2230 		/* Set "remote" forwarding info. */
2231 		UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
2232 		n->r_vtep_ip = vtep_ip;
2233 		SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2234 
2235 		/* Set router flag (R-bit) to this Neighbor entry */
2236 		if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
2237 			SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2238 		else
2239 			UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2240 
2241 		/* Check old or new MAC detected as duplicate,
2242 		 * inherit duplicate flag to this neigh.
2243 		 */
2244 		if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_mac, mac, n)) {
2245 			flog_warn(
2246 				EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
2247 				"VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
2248 				zevpn->vni,
2249 				prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2250 				ipaddr2str(&n->ip, buf1, sizeof(buf1)));
2251 		}
2252 
2253 		/* Check duplicate address detection for IP */
2254 		zebra_evpn_dup_addr_detect_for_neigh(
2255 			zvrf, n, n->r_vtep_ip, do_dad, &is_dup_detect, false);
2256 		/* Install the entry. */
2257 		if (!is_dup_detect)
2258 			zebra_evpn_rem_neigh_install(zevpn, n, old_static);
2259 	}
2260 
2261 	/* Update seq number. */
2262 	n->rem_seq = seq;
2263 }
2264 
zebra_evpn_neigh_gw_macip_add(struct interface * ifp,zebra_evpn_t * zevpn,struct ipaddr * ip,zebra_mac_t * mac)2265 int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
2266 				  struct ipaddr *ip, zebra_mac_t *mac)
2267 {
2268 	zebra_neigh_t *n;
2269 	char buf[ETHER_ADDR_STRLEN];
2270 	char buf2[INET6_ADDRSTRLEN];
2271 
2272 	assert(mac);
2273 
2274 	n = zebra_evpn_neigh_lookup(zevpn, ip);
2275 	if (!n) {
2276 		n = zebra_evpn_neigh_add(zevpn, ip, &mac->macaddr, mac, 0);
2277 		if (!n) {
2278 			flog_err(
2279 				EC_ZEBRA_MAC_ADD_FAILED,
2280 				"Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2281 				ipaddr2str(ip, buf2, sizeof(buf2)),
2282 				prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2283 				ifp->name, ifp->ifindex, zevpn->vni);
2284 			return -1;
2285 		}
2286 	}
2287 
2288 	/* Set "local" forwarding info. */
2289 	SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2290 	ZEBRA_NEIGH_SET_ACTIVE(n);
2291 	memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
2292 	n->ifindex = ifp->ifindex;
2293 
2294 	/* Only advertise in BGP if the knob is enabled */
2295 	if (advertise_gw_macip_enabled(zevpn)) {
2296 
2297 		SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
2298 		SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
2299 		/* Set Router flag (R-bit) */
2300 		if (ip->ipa_type == IPADDR_V6)
2301 			SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
2302 
2303 		if (IS_ZEBRA_DEBUG_VXLAN)
2304 			zlog_debug(
2305 				"SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
2306 				ifp->name, ifp->ifindex, zevpn->vni,
2307 				prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2308 				ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
2309 
2310 		zebra_evpn_neigh_send_add_to_client(
2311 			zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2312 	} else if (advertise_svi_macip_enabled(zevpn)) {
2313 
2314 		SET_FLAG(n->flags, ZEBRA_NEIGH_SVI_IP);
2315 		if (IS_ZEBRA_DEBUG_VXLAN)
2316 			zlog_debug(
2317 				"SVI %s(%u) L2-VNI %u, sending SVI MAC %s IP %s add to BGP with flags 0x%x",
2318 				ifp->name, ifp->ifindex, zevpn->vni,
2319 				prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
2320 				ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
2321 
2322 		zebra_evpn_neigh_send_add_to_client(
2323 			zevpn->vni, ip, &n->emac, n->mac, n->flags, n->loc_seq);
2324 	}
2325 
2326 	return 0;
2327 }
2328 
zebra_evpn_neigh_remote_uninstall(zebra_evpn_t * zevpn,struct zebra_vrf * zvrf,zebra_neigh_t * n,zebra_mac_t * mac,struct ipaddr * ipaddr)2329 void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn,
2330 				       struct zebra_vrf *zvrf, zebra_neigh_t *n,
2331 				       zebra_mac_t *mac, struct ipaddr *ipaddr)
2332 {
2333 	char buf1[INET6_ADDRSTRLEN];
2334 
2335 	if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)
2336 	    && CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2337 	    && (memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN) == 0)) {
2338 		struct interface *vlan_if;
2339 
2340 		vlan_if = zevpn_map_to_svi(zevpn);
2341 		if (IS_ZEBRA_DEBUG_VXLAN)
2342 			zlog_debug(
2343 				"%s: IP %s (flags 0x%x intf %s) is remote and duplicate, read kernel for local entry",
2344 				__func__,
2345 				ipaddr2str(ipaddr, buf1, sizeof(buf1)),
2346 				n->flags, vlan_if ? vlan_if->name : "Unknown");
2347 		if (vlan_if)
2348 			neigh_read_specific_ip(ipaddr, vlan_if);
2349 	}
2350 
2351 	/* When the MAC changes for an IP, it is possible the
2352 	 * client may update the new MAC before trying to delete the
2353 	 * "old" neighbor (as these are two different MACIP routes).
2354 	 * Do the delete only if the MAC matches.
2355 	 */
2356 	if (!memcmp(n->emac.octet, mac->macaddr.octet, ETH_ALEN)) {
2357 		if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2358 			zebra_evpn_sync_neigh_del(n);
2359 		} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2360 			zebra_evpn_neigh_uninstall(zevpn, n);
2361 			zebra_evpn_neigh_del(zevpn, n);
2362 			zebra_evpn_deref_ip2mac(zevpn, mac);
2363 		}
2364 	}
2365 }
2366 
zebra_evpn_neigh_del_ip(zebra_evpn_t * zevpn,struct ipaddr * ip)2367 int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip)
2368 {
2369 	zebra_neigh_t *n;
2370 	zebra_mac_t *zmac;
2371 	bool old_bgp_ready;
2372 	bool new_bgp_ready;
2373 	char buf[INET6_ADDRSTRLEN];
2374 	char buf2[ETHER_ADDR_STRLEN];
2375 	struct zebra_vrf *zvrf;
2376 
2377 	/* If entry doesn't exist, nothing to do. */
2378 	n = zebra_evpn_neigh_lookup(zevpn, ip);
2379 	if (!n)
2380 		return 0;
2381 
2382 	zmac = zebra_evpn_mac_lookup(zevpn, &n->emac);
2383 	if (!zmac) {
2384 		if (IS_ZEBRA_DEBUG_VXLAN)
2385 			zlog_debug(
2386 				"Trying to del a neigh %s without a mac %s on VNI %u",
2387 				ipaddr2str(ip, buf, sizeof(buf)),
2388 				prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2389 				zevpn->vni);
2390 
2391 		return 0;
2392 	}
2393 
2394 	/* If it is a remote entry, the kernel has aged this out or someone has
2395 	 * deleted it, it needs to be re-installed as Quagga is the owner.
2396 	 */
2397 	if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2398 		zebra_evpn_rem_neigh_install(zevpn, n, false /*was_static*/);
2399 		return 0;
2400 	}
2401 
2402 	/* if this is a sync entry it cannot be dropped re-install it in
2403 	 * the dataplane
2404 	 */
2405 	old_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2406 	if (zebra_evpn_neigh_is_static(n)) {
2407 		if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
2408 			zlog_debug("re-add sync neigh vni %u ip %s mac %s 0x%x",
2409 				   n->zevpn->vni,
2410 				   ipaddr2str(&n->ip, buf, sizeof(buf)),
2411 				   prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2412 				   n->flags);
2413 
2414 		if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE))
2415 			SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL_INACTIVE);
2416 		/* inform-bgp about change in local-activity if any */
2417 		new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n);
2418 		zebra_evpn_neigh_send_add_del_to_client(n, old_bgp_ready,
2419 							new_bgp_ready);
2420 
2421 		/* re-install the entry in the kernel */
2422 		zebra_evpn_sync_neigh_dp_install(n, false /* set_inactive */,
2423 						 false /* force_clear_static */,
2424 						 __func__);
2425 
2426 		return 0;
2427 	}
2428 
2429 	zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
2430 	if (!zvrf) {
2431 		zlog_debug("%s: VNI %u vrf lookup failed.", __func__,
2432 			   zevpn->vni);
2433 		return -1;
2434 	}
2435 
2436 	/* In case of feeze action, if local neigh is in duplicate state,
2437 	 * Mark the Neigh as inactive before sending delete request to BGPd,
2438 	 * If BGPd has remote entry, it will re-install
2439 	 */
2440 	if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
2441 		ZEBRA_NEIGH_SET_INACTIVE(n);
2442 
2443 	/* Remove neighbor from BGP. */
2444 	zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
2445 					    n->flags, n->state,
2446 					    false /* force */);
2447 
2448 	/* Delete this neighbor entry. */
2449 	zebra_evpn_neigh_del(zevpn, n);
2450 
2451 	/* see if the AUTO mac needs to be deleted */
2452 	if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
2453 	    && !listcount(zmac->neigh_list))
2454 		zebra_evpn_mac_del(zevpn, zmac);
2455 
2456 	return 0;
2457 }
2458