1 /** @file
2  * @brief IPv6 Neighbor related functions
3  */
4 
5 /*
6  * Copyright (c) 2018 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 /* By default this prints too much data, set the value to 1 to see
12  * neighbor cache contents.
13  */
14 #define NET_DEBUG_NBR 0
15 
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(net_ipv6_nd, CONFIG_NET_IPV6_ND_LOG_LEVEL);
18 
19 #include <errno.h>
20 #include <stdlib.h>
21 #include <zephyr/net/net_core.h>
22 #include <zephyr/net/net_pkt.h>
23 #include <zephyr/net/net_stats.h>
24 #include <zephyr/net/net_context.h>
25 #include <zephyr/net/net_mgmt.h>
26 #include <zephyr/net/dns_resolve.h>
27 #include <zephyr/net/icmp.h>
28 #include "net_private.h"
29 #include "connection.h"
30 #include "icmpv6.h"
31 #include "udp_internal.h"
32 #include "tcp_internal.h"
33 #include "ipv6.h"
34 #include "nbr.h"
35 #include "6lo.h"
36 #include "route.h"
37 #include "net_stats.h"
38 
39 /* Timeout value to be used when allocating net buffer during various
40  * neighbor discovery procedures.
41  */
42 #define ND_NET_BUF_TIMEOUT K_MSEC(100)
43 
44 /* Timeout for various buffer allocations in this file. */
45 #define NET_BUF_TIMEOUT K_MSEC(50)
46 
47 /* Maximum reachable time value specified in RFC 4861 section
48  * 6.2.1. Router Configuration Variables, AdvReachableTime
49  */
50 #define MAX_REACHABLE_TIME 3600000
51 
52 /* IPv6 minimum link MTU specified in RFC 8200 section 5
53  * Packet Size Issues
54  */
55 #define MIN_IPV6_MTU NET_IPV6_MTU
56 #define MAX_IPV6_MTU 0xffff
57 
58 #if defined(CONFIG_NET_IPV6_NBR_CACHE) || defined(CONFIG_NET_IPV6_ND)
59 /* Global stale counter, whenever ipv6 neighbor enters into
60  * stale state, stale counter is incremented by one.
61  * When network stack tries to add new neighbor and if table
62  * is full, oldest (oldest stale counter) neighbor in stale
63  * state will be removed from the table and new entry will be
64  * added.
65  */
66 static uint32_t stale_counter;
67 #endif
68 
69 #if defined(CONFIG_NET_IPV6_ND)
70 static struct k_work_delayable ipv6_nd_reachable_timer;
71 static void ipv6_nd_reachable_timeout(struct k_work *work);
72 static void ipv6_nd_restart_reachable_timer(struct net_nbr *nbr, int64_t time);
73 #endif
74 
75 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
76 
77 /* Protocol constants from RFC 4861 Chapter 10 */
78 #define MAX_MULTICAST_SOLICIT 3
79 #define MAX_UNICAST_SOLICIT   3
80 #define DELAY_FIRST_PROBE_TIME (5 * MSEC_PER_SEC)
81 #define RETRANS_TIMER 1000 /* ms */
82 
83 extern void net_neighbor_remove(struct net_nbr *nbr);
84 extern void net_neighbor_table_clear(struct net_nbr_table *table);
85 
86 /** Neighbor Solicitation reply timer */
87 static struct k_work_delayable ipv6_ns_reply_timer;
88 
89 NET_NBR_POOL_INIT(net_neighbor_pool,
90 		  CONFIG_NET_IPV6_MAX_NEIGHBORS,
91 		  sizeof(struct net_ipv6_nbr_data),
92 		  net_neighbor_remove);
93 
94 NET_NBR_TABLE_INIT(NET_NBR_GLOBAL,
95 		   neighbor,
96 		   net_neighbor_pool,
97 		   net_neighbor_table_clear);
98 
99 static K_MUTEX_DEFINE(nbr_lock);
100 
net_ipv6_nbr_lock(void)101 void net_ipv6_nbr_lock(void)
102 {
103 	(void)k_mutex_lock(&nbr_lock, K_FOREVER);
104 }
105 
net_ipv6_nbr_unlock(void)106 void net_ipv6_nbr_unlock(void)
107 {
108 	k_mutex_unlock(&nbr_lock);
109 }
110 
net_ipv6_nbr_state2str(enum net_ipv6_nbr_state state)111 const char *net_ipv6_nbr_state2str(enum net_ipv6_nbr_state state)
112 {
113 	switch (state) {
114 	case NET_IPV6_NBR_STATE_INCOMPLETE:
115 		return "incomplete";
116 	case NET_IPV6_NBR_STATE_REACHABLE:
117 		return "reachable";
118 	case NET_IPV6_NBR_STATE_STALE:
119 		return "stale";
120 	case NET_IPV6_NBR_STATE_DELAY:
121 		return "delay";
122 	case NET_IPV6_NBR_STATE_PROBE:
123 		return "probe";
124 	case NET_IPV6_NBR_STATE_STATIC:
125 		return "static";
126 	}
127 
128 	return "<invalid state>";
129 }
130 
get_nbr(int idx)131 static inline struct net_nbr *get_nbr(int idx)
132 {
133 	return &net_neighbor_pool[idx].nbr;
134 }
135 
get_nbr_from_data(struct net_ipv6_nbr_data * data)136 static inline struct net_nbr *get_nbr_from_data(struct net_ipv6_nbr_data *data)
137 {
138 	int i;
139 
140 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
141 		struct net_nbr *nbr = get_nbr(i);
142 
143 		if (nbr->data == (uint8_t *)data) {
144 			return nbr;
145 		}
146 	}
147 
148 	return NULL;
149 }
150 
ipv6_nbr_set_state(struct net_nbr * nbr,enum net_ipv6_nbr_state new_state)151 static void ipv6_nbr_set_state(struct net_nbr *nbr,
152 			       enum net_ipv6_nbr_state new_state)
153 {
154 	if (new_state == net_ipv6_nbr_data(nbr)->state ||
155 	    net_ipv6_nbr_data(nbr)->state == NET_IPV6_NBR_STATE_STATIC) {
156 		return;
157 	}
158 
159 	NET_DBG("nbr %p %s -> %s", nbr,
160 		net_ipv6_nbr_state2str(net_ipv6_nbr_data(nbr)->state),
161 		net_ipv6_nbr_state2str(new_state));
162 
163 	net_ipv6_nbr_data(nbr)->state = new_state;
164 
165 	if (net_ipv6_nbr_data(nbr)->state == NET_IPV6_NBR_STATE_STALE) {
166 		if (stale_counter + 1 != UINT32_MAX) {
167 			net_ipv6_nbr_data(nbr)->stale_counter = stale_counter++;
168 		} else {
169 			/* Global stale counter reached UINT32_MAX, reset it and
170 			 * respective neighbors stale counter too.
171 			 */
172 			struct net_nbr *n = NULL;
173 			struct net_ipv6_nbr_data *data = NULL;
174 			int i;
175 
176 			stale_counter = 0U;
177 
178 			for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
179 				n = get_nbr(i);
180 				if (!n || !n->ref) {
181 					continue;
182 				}
183 
184 				data = net_ipv6_nbr_data(nbr);
185 				if (!data) {
186 					continue;
187 				}
188 
189 				if (data->state != NET_IPV6_NBR_STATE_STALE) {
190 					continue;
191 				}
192 
193 				data->stale_counter = stale_counter++;
194 			}
195 		}
196 	}
197 }
198 
199 struct iface_cb_data {
200 	net_nbr_cb_t cb;
201 	void *user_data;
202 };
203 
iface_cb(struct net_if * iface,void * user_data)204 static void iface_cb(struct net_if *iface, void *user_data)
205 {
206 	struct iface_cb_data *data = user_data;
207 	int i;
208 
209 	net_ipv6_nbr_lock();
210 
211 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
212 		struct net_nbr *nbr = get_nbr(i);
213 
214 		if (!nbr->ref || nbr->iface != iface) {
215 			continue;
216 		}
217 
218 		data->cb(nbr, data->user_data);
219 	}
220 
221 	net_ipv6_nbr_unlock();
222 }
223 
net_ipv6_nbr_foreach(net_nbr_cb_t cb,void * user_data)224 void net_ipv6_nbr_foreach(net_nbr_cb_t cb, void *user_data)
225 {
226 	struct iface_cb_data cb_data = {
227 		.cb = cb,
228 		.user_data = user_data,
229 	};
230 
231 	/* Return the neighbors according to network interface. This makes it
232 	 * easier in the callback to use the neighbor information.
233 	 */
234 	net_if_foreach(iface_cb, &cb_data);
235 }
236 
237 #if NET_DEBUG_NBR
nbr_print(void)238 void nbr_print(void)
239 {
240 	int i;
241 
242 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
243 		struct net_nbr *nbr = get_nbr(i);
244 
245 		if (!nbr->ref) {
246 			continue;
247 		}
248 
249 		NET_DBG("[%d] %p %d/%d/%d/%d/%d pending %p iface %p/%d "
250 			"ll %s addr %s",
251 			i, nbr, nbr->ref, net_ipv6_nbr_data(nbr)->ns_count,
252 			net_ipv6_nbr_data(nbr)->is_router,
253 			net_ipv6_nbr_data(nbr)->state,
254 			net_ipv6_nbr_data(nbr)->link_metric,
255 			net_ipv6_nbr_data(nbr)->pending,
256 			nbr->iface, nbr->idx,
257 			nbr->idx == NET_NBR_LLADDR_UNKNOWN ? "?" :
258 			net_sprint_ll_addr(
259 				net_nbr_get_lladdr(nbr->idx)->addr,
260 				net_nbr_get_lladdr(nbr->idx)->len),
261 			net_sprint_ipv6_addr(&net_ipv6_nbr_data(nbr)->addr));
262 	}
263 }
264 #else
265 #define nbr_print(...)
266 #endif
267 
nbr_lookup(struct net_nbr_table * table,struct net_if * iface,const struct in6_addr * addr)268 static struct net_nbr *nbr_lookup(struct net_nbr_table *table,
269 				  struct net_if *iface,
270 				  const struct in6_addr *addr)
271 {
272 	int i;
273 
274 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
275 		struct net_nbr *nbr = get_nbr(i);
276 
277 		if (!nbr->ref) {
278 			continue;
279 		}
280 
281 		if (iface && nbr->iface != iface) {
282 			continue;
283 		}
284 
285 		if (net_ipv6_addr_cmp(&net_ipv6_nbr_data(nbr)->addr, addr)) {
286 			return nbr;
287 		}
288 	}
289 
290 	return NULL;
291 }
292 
nbr_clear_ns_pending(struct net_ipv6_nbr_data * data)293 static inline void nbr_clear_ns_pending(struct net_ipv6_nbr_data *data)
294 {
295 	data->send_ns = 0;
296 
297 	if (data->pending) {
298 		net_pkt_unref(data->pending);
299 		data->pending = NULL;
300 	}
301 }
302 
nbr_free(struct net_nbr * nbr)303 static inline void nbr_free(struct net_nbr *nbr)
304 {
305 	NET_DBG("nbr %p", nbr);
306 
307 	nbr_clear_ns_pending(net_ipv6_nbr_data(nbr));
308 
309 	net_ipv6_nbr_data(nbr)->reachable = 0;
310 	net_ipv6_nbr_data(nbr)->reachable_timeout = 0;
311 
312 	net_nbr_unref(nbr);
313 	net_nbr_unlink(nbr, NULL);
314 }
315 
net_ipv6_nbr_rm(struct net_if * iface,struct in6_addr * addr)316 bool net_ipv6_nbr_rm(struct net_if *iface, struct in6_addr *addr)
317 {
318 	struct net_nbr *nbr;
319 #if defined(CONFIG_NET_MGMT_EVENT_INFO)
320 	struct net_event_ipv6_nbr info;
321 #endif
322 
323 	net_ipv6_nbr_lock();
324 
325 	nbr = nbr_lookup(&net_neighbor.table, iface, addr);
326 	if (!nbr) {
327 		net_ipv6_nbr_unlock();
328 		return false;
329 	}
330 
331 	/* Remove any routes with nbr as nexthop in first place */
332 	net_route_del_by_nexthop(iface, addr);
333 
334 	nbr_free(nbr);
335 
336 #if defined(CONFIG_NET_MGMT_EVENT_INFO)
337 	info.idx = -1;
338 	net_ipaddr_copy(&info.addr, addr);
339 	net_mgmt_event_notify_with_info(NET_EVENT_IPV6_NBR_DEL,
340 					iface, (void *) &info,
341 					sizeof(struct net_event_ipv6_nbr));
342 #else
343 	net_mgmt_event_notify(NET_EVENT_IPV6_NBR_DEL, iface);
344 #endif
345 
346 	net_ipv6_nbr_unlock();
347 	return true;
348 }
349 
350 #define NS_REPLY_TIMEOUT (1 * MSEC_PER_SEC)
351 
ipv6_ns_reply_timeout(struct k_work * work)352 static void ipv6_ns_reply_timeout(struct k_work *work)
353 {
354 	int64_t current = k_uptime_get();
355 	struct net_nbr *nbr = NULL;
356 	struct net_ipv6_nbr_data *data;
357 	int i;
358 
359 	ARG_UNUSED(work);
360 
361 	net_ipv6_nbr_lock();
362 
363 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
364 		int64_t remaining;
365 		nbr = get_nbr(i);
366 
367 		if (!nbr || !nbr->ref) {
368 			continue;
369 		}
370 
371 		data = net_ipv6_nbr_data(nbr);
372 		if (!data) {
373 			continue;
374 		}
375 
376 		if (!data->send_ns) {
377 			continue;
378 		}
379 
380 		remaining = data->send_ns + NS_REPLY_TIMEOUT - current;
381 
382 		if (remaining > 0) {
383 			if (!k_work_delayable_remaining_get(
384 				    &ipv6_ns_reply_timer)) {
385 				k_work_reschedule(&ipv6_ns_reply_timer,
386 						  K_MSEC(remaining));
387 			}
388 
389 			continue;
390 		}
391 
392 		data->send_ns = 0;
393 
394 		/* We did not receive reply to a sent NS */
395 		if (!data->pending) {
396 			/* Silently return, this is not an error as the work
397 			 * cannot be cancelled in certain cases.
398 			 */
399 			continue;
400 		}
401 
402 		NET_DBG("NS nbr %p pending %p timeout to %s", nbr,
403 			data->pending,
404 			net_sprint_ipv6_addr(&NET_IPV6_HDR(data->pending)->dst));
405 
406 		/* To unref when pending variable was set */
407 		net_pkt_unref(data->pending);
408 
409 		/* To unref the original pkt allocation */
410 		net_pkt_unref(data->pending);
411 
412 		data->pending = NULL;
413 
414 		net_nbr_unref(nbr);
415 	}
416 
417 	net_ipv6_nbr_unlock();
418 }
419 
nbr_init(struct net_nbr * nbr,struct net_if * iface,const struct in6_addr * addr,bool is_router,enum net_ipv6_nbr_state state)420 static void nbr_init(struct net_nbr *nbr, struct net_if *iface,
421 		     const struct in6_addr *addr, bool is_router,
422 		     enum net_ipv6_nbr_state state)
423 {
424 	nbr->idx = NET_NBR_LLADDR_UNKNOWN;
425 	nbr->iface = iface;
426 
427 	net_ipaddr_copy(&net_ipv6_nbr_data(nbr)->addr, addr);
428 	ipv6_nbr_set_state(nbr, state);
429 	net_ipv6_nbr_data(nbr)->is_router = is_router;
430 	net_ipv6_nbr_data(nbr)->pending = NULL;
431 	net_ipv6_nbr_data(nbr)->send_ns = 0;
432 
433 #if defined(CONFIG_NET_IPV6_ND)
434 	net_ipv6_nbr_data(nbr)->reachable = 0;
435 	net_ipv6_nbr_data(nbr)->reachable_timeout = 0;
436 #endif
437 }
438 
nbr_new(struct net_if * iface,const struct in6_addr * addr,bool is_router,enum net_ipv6_nbr_state state)439 static struct net_nbr *nbr_new(struct net_if *iface,
440 			       const struct in6_addr *addr, bool is_router,
441 			       enum net_ipv6_nbr_state state)
442 {
443 	struct net_nbr *nbr = net_nbr_get(&net_neighbor.table);
444 
445 	if (!nbr) {
446 		return NULL;
447 	}
448 
449 	nbr_init(nbr, iface, addr, is_router, state);
450 
451 	NET_DBG("nbr %p iface %p/%d state %d IPv6 %s",
452 		nbr, iface, net_if_get_by_iface(iface), state,
453 		net_sprint_ipv6_addr(addr));
454 
455 	return nbr;
456 }
457 
dbg_update_neighbor_lladdr(const struct net_linkaddr * new_lladdr,const struct net_linkaddr_storage * old_lladdr,const struct in6_addr * addr)458 static void dbg_update_neighbor_lladdr(const struct net_linkaddr *new_lladdr,
459 				       const struct net_linkaddr_storage *old_lladdr,
460 				       const struct in6_addr *addr)
461 {
462 	char out[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
463 
464 	snprintk(out, sizeof(out), "%s",
465 		 net_sprint_ll_addr(old_lladdr->addr, old_lladdr->len));
466 
467 	NET_DBG("Updating neighbor %s lladdr %s (was %s)",
468 		net_sprint_ipv6_addr(addr),
469 		net_sprint_ll_addr(new_lladdr->addr, new_lladdr->len),
470 		out);
471 }
472 
dbg_update_neighbor_lladdr_raw(uint8_t * new_lladdr,struct net_linkaddr_storage * old_lladdr,struct in6_addr * addr)473 static void dbg_update_neighbor_lladdr_raw(uint8_t *new_lladdr,
474 				       struct net_linkaddr_storage *old_lladdr,
475 				       struct in6_addr *addr)
476 {
477 	struct net_linkaddr lladdr = {
478 		.len = old_lladdr->len,
479 		.addr = new_lladdr,
480 	};
481 
482 	dbg_update_neighbor_lladdr(&lladdr, old_lladdr, addr);
483 }
484 
485 #define dbg_addr(action, pkt_str, src, dst, pkt)			\
486 	do {								\
487 		NET_DBG("%s %s from %s to %s iface %p/%d",		\
488 			action, pkt_str,				\
489 			net_sprint_ipv6_addr(src),		\
490 			net_sprint_ipv6_addr(dst),		\
491 			net_pkt_iface(pkt),				\
492 			net_if_get_by_iface(net_pkt_iface(pkt)));	\
493 	} while (false)
494 
495 #define dbg_addr_recv(pkt_str, src, dst, pkt)	\
496 	dbg_addr("Received", pkt_str, src, dst, pkt)
497 
498 #define dbg_addr_sent(pkt_str, src, dst, pkt)	\
499 	dbg_addr("Sent", pkt_str, src, dst, pkt)
500 
501 #define dbg_addr_with_tgt(action, pkt_str, src, dst, target, pkt)	\
502 	do {								\
503 		NET_DBG("%s %s from %s to %s, target %s iface %p/%d",	\
504 			action,						\
505 			pkt_str,                                        \
506 			net_sprint_ipv6_addr(src),		\
507 			net_sprint_ipv6_addr(dst),		\
508 			net_sprint_ipv6_addr(target),	\
509 			net_pkt_iface(pkt),				\
510 			net_if_get_by_iface(net_pkt_iface(pkt)));	\
511 	} while (false)
512 
513 #define dbg_addr_recv_tgt(pkt_str, src, dst, tgt, pkt)		\
514 	dbg_addr_with_tgt("Received", pkt_str, src, dst, tgt, pkt)
515 
516 #define dbg_addr_sent_tgt(pkt_str, src, dst, tgt, pkt)		\
517 	dbg_addr_with_tgt("Sent", pkt_str, src, dst, tgt, pkt)
518 
ipv6_nd_remove_old_stale_nbr(void)519 static void ipv6_nd_remove_old_stale_nbr(void)
520 {
521 	struct net_nbr *nbr = NULL;
522 	struct net_ipv6_nbr_data *data = NULL;
523 	int nbr_idx = -1;
524 	uint32_t oldest = UINT32_MAX;
525 	int i;
526 
527 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
528 		nbr = get_nbr(i);
529 		if (!nbr || !nbr->ref) {
530 			continue;
531 		}
532 
533 		data = net_ipv6_nbr_data(nbr);
534 		if (!data || data->is_router ||
535 		    data->state != NET_IPV6_NBR_STATE_STALE) {
536 			continue;
537 		}
538 
539 		if (nbr_idx == -1) {
540 			nbr_idx = i;
541 			oldest = data->stale_counter;
542 			continue;
543 		}
544 
545 		if (oldest == MIN(oldest, data->stale_counter)) {
546 			continue;
547 		}
548 
549 		nbr_idx = i;
550 		oldest = data->stale_counter;
551 	}
552 
553 	if (nbr_idx != -1) {
554 		nbr = get_nbr(nbr_idx);
555 		if (!nbr) {
556 			return;
557 		}
558 
559 		net_ipv6_nbr_rm(nbr->iface,
560 				&net_ipv6_nbr_data(nbr)->addr);
561 	}
562 }
563 
add_nbr(struct net_if * iface,const struct in6_addr * addr,bool is_router,enum net_ipv6_nbr_state state)564 static struct net_nbr *add_nbr(struct net_if *iface,
565 			       const struct in6_addr *addr,
566 			       bool is_router,
567 			       enum net_ipv6_nbr_state state)
568 {
569 	struct net_nbr *nbr;
570 
571 	nbr = nbr_lookup(&net_neighbor.table, iface, addr);
572 	if (nbr) {
573 		return nbr;
574 	}
575 
576 	nbr = nbr_new(iface, addr, is_router, state);
577 	if (nbr) {
578 		return nbr;
579 	}
580 
581 	/* Check if there are any stale neighbors, delete the oldest
582 	 * one and try to add new neighbor.
583 	 */
584 	ipv6_nd_remove_old_stale_nbr();
585 
586 	nbr = nbr_new(iface, addr, is_router, state);
587 	if (!nbr) {
588 		return NULL;
589 	}
590 
591 	return nbr;
592 }
593 
net_ipv6_nbr_add(struct net_if * iface,const struct in6_addr * addr,const struct net_linkaddr * lladdr,bool is_router,enum net_ipv6_nbr_state state)594 struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
595 				 const struct in6_addr *addr,
596 				 const struct net_linkaddr *lladdr,
597 				 bool is_router,
598 				 enum net_ipv6_nbr_state state)
599 {
600 	struct net_nbr *nbr;
601 	int ret;
602 #if defined(CONFIG_NET_MGMT_EVENT_INFO)
603 	struct net_event_ipv6_nbr info;
604 #endif
605 
606 	net_ipv6_nbr_lock();
607 
608 	nbr = add_nbr(iface, addr, is_router, state);
609 	if (!nbr) {
610 		NET_ERR("Could not add router neighbor %s [%s]",
611 			net_sprint_ipv6_addr(addr),
612 			lladdr ? net_sprint_ll_addr(lladdr->addr, lladdr->len) : "unknown");
613 		goto out;
614 	}
615 
616 	if (lladdr && net_nbr_link(nbr, iface, lladdr) == -EALREADY &&
617 	    net_ipv6_nbr_data(nbr)->state != NET_IPV6_NBR_STATE_STATIC) {
618 		/* Update the lladdr if the node was already known */
619 		struct net_linkaddr_storage *cached_lladdr;
620 
621 		cached_lladdr = net_nbr_get_lladdr(nbr->idx);
622 
623 		if (memcmp(cached_lladdr->addr, lladdr->addr, lladdr->len)) {
624 			dbg_update_neighbor_lladdr(lladdr, cached_lladdr, addr);
625 
626 			net_linkaddr_set(cached_lladdr, lladdr->addr,
627 					 lladdr->len);
628 
629 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_STALE);
630 		} else if (net_ipv6_nbr_data(nbr)->state ==
631 			   NET_IPV6_NBR_STATE_INCOMPLETE) {
632 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_STALE);
633 		}
634 	}
635 
636 	if (net_ipv6_nbr_data(nbr)->state == NET_IPV6_NBR_STATE_INCOMPLETE) {
637 		/* Send NS so that we can verify that the neighbor is
638 		 * reachable.
639 		 */
640 		ret = net_ipv6_send_ns(iface, NULL, NULL, NULL, addr, false);
641 		if (ret < 0) {
642 			NET_DBG("Cannot send NS (%d)", ret);
643 		}
644 	}
645 
646 	NET_DBG("[%d] nbr %p state %d router %d IPv6 %s ll %s iface %p/%d",
647 		nbr->idx, nbr, state, is_router,
648 		net_sprint_ipv6_addr(addr),
649 		lladdr ? net_sprint_ll_addr(lladdr->addr, lladdr->len) : "[unknown]",
650 		nbr->iface, net_if_get_by_iface(nbr->iface));
651 
652 #if defined(CONFIG_NET_MGMT_EVENT_INFO)
653 	info.idx = nbr->idx;
654 	net_ipaddr_copy(&info.addr, addr);
655 	net_mgmt_event_notify_with_info(NET_EVENT_IPV6_NBR_ADD,
656 					iface, (void *) &info,
657 					sizeof(struct net_event_ipv6_nbr));
658 #else
659 	net_mgmt_event_notify(NET_EVENT_IPV6_NBR_ADD, iface);
660 #endif
661 
662 out:
663 	net_ipv6_nbr_unlock();
664 	return nbr;
665 }
666 
net_neighbor_remove(struct net_nbr * nbr)667 void net_neighbor_remove(struct net_nbr *nbr)
668 {
669 	NET_DBG("Neighbor %p removed", nbr);
670 
671 	return;
672 }
673 
net_neighbor_table_clear(struct net_nbr_table * table)674 void net_neighbor_table_clear(struct net_nbr_table *table)
675 {
676 	NET_DBG("Neighbor table %p cleared", table);
677 }
678 
net_ipv6_nbr_lookup_by_index(struct net_if * iface,uint8_t idx)679 struct in6_addr *net_ipv6_nbr_lookup_by_index(struct net_if *iface,
680 					      uint8_t idx)
681 {
682 	int i;
683 
684 	if (idx == NET_NBR_LLADDR_UNKNOWN) {
685 		return NULL;
686 	}
687 
688 	net_ipv6_nbr_lock();
689 
690 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
691 		struct net_nbr *nbr = get_nbr(i);
692 
693 		if (!nbr->ref) {
694 			continue;
695 		}
696 
697 		if (iface && nbr->iface != iface) {
698 			continue;
699 		}
700 
701 		if (nbr->idx == idx) {
702 			net_ipv6_nbr_unlock();
703 			return &net_ipv6_nbr_data(nbr)->addr;
704 		}
705 	}
706 
707 	net_ipv6_nbr_unlock();
708 	return NULL;
709 }
710 #else
net_ipv6_nbr_state2str(enum net_ipv6_nbr_state state)711 const char *net_ipv6_nbr_state2str(enum net_ipv6_nbr_state state)
712 {
713 	return "<unknown state>";
714 }
715 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
716 
717 #if defined(CONFIG_NET_IPV6_DAD)
net_ipv6_start_dad(struct net_if * iface,struct net_if_addr * ifaddr)718 int net_ipv6_start_dad(struct net_if *iface, struct net_if_addr *ifaddr)
719 {
720 	return net_ipv6_send_ns(iface, NULL, NULL, NULL,
721 				&ifaddr->address.in6_addr, true);
722 }
723 
dad_failed(struct net_if * iface,struct in6_addr * addr)724 static inline bool dad_failed(struct net_if *iface, struct in6_addr *addr)
725 {
726 	if (net_ipv6_is_ll_addr(addr)) {
727 		NET_ERR("DAD failed, no ll IPv6 address!");
728 		return false;
729 	}
730 
731 	net_if_ipv6_dad_failed(iface, addr);
732 
733 	return true;
734 }
735 #endif /* CONFIG_NET_IPV6_DAD */
736 
737 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
check_route(struct net_if * iface,struct in6_addr * dst,bool * try_route)738 static struct in6_addr *check_route(struct net_if *iface,
739 				    struct in6_addr *dst,
740 				    bool *try_route)
741 {
742 	struct in6_addr *nexthop = NULL;
743 	struct net_route_entry *route;
744 	struct net_if_router *router;
745 
746 	route = net_route_lookup(iface, dst);
747 	if (route) {
748 		nexthop = net_route_get_nexthop(route);
749 
750 		NET_DBG("Route %p nexthop %s iface %p/%d",
751 			route,
752 			nexthop ? net_sprint_ipv6_addr(nexthop) :
753 			"<unknown>",
754 			iface, net_if_get_by_iface(iface));
755 
756 		if (!nexthop) {
757 			net_route_del(route);
758 
759 			NET_DBG("No route to host %s",
760 				net_sprint_ipv6_addr(dst));
761 
762 			return NULL;
763 		}
764 	} else {
765 		/* No specific route to this host, use the default
766 		 * route instead.
767 		 */
768 		router = net_if_ipv6_router_find_default(NULL, dst);
769 		if (!router) {
770 			NET_DBG("No default route to %s",
771 				net_sprint_ipv6_addr(dst));
772 
773 			/* Try to send the packet anyway */
774 			nexthop = dst;
775 			if (try_route) {
776 				*try_route = true;
777 			}
778 
779 			return nexthop;
780 		}
781 
782 		nexthop = &router->address.in6_addr;
783 
784 		NET_DBG("Router %p nexthop %s", router,
785 			net_sprint_ipv6_addr(nexthop));
786 	}
787 
788 	return nexthop;
789 }
790 
net_ipv6_prepare_for_send(struct net_pkt * pkt)791 enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt)
792 {
793 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
794 	struct in6_addr *nexthop = NULL;
795 	struct net_if *iface = NULL;
796 	struct net_ipv6_hdr *ip_hdr;
797 	struct net_nbr *nbr;
798 	int ret;
799 
800 	NET_ASSERT(pkt && pkt->buffer);
801 
802 	ip_hdr = (struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);
803 	if (!ip_hdr) {
804 		return NET_DROP;
805 	}
806 
807 #if defined(CONFIG_NET_IPV6_FRAGMENT)
808 	/* If we have already fragmented the packet, the fragment id will
809 	 * contain a proper value and we can skip other checks.
810 	 */
811 	if (net_pkt_ipv6_fragment_id(pkt) == 0U) {
812 		uint16_t mtu = net_if_get_mtu(net_pkt_iface(pkt));
813 		size_t pkt_len = net_pkt_get_len(pkt);
814 
815 		mtu = MAX(NET_IPV6_MTU, mtu);
816 		if (mtu < pkt_len) {
817 			ret = net_ipv6_send_fragmented_pkt(net_pkt_iface(pkt),
818 							   pkt, pkt_len);
819 			if (ret < 0) {
820 				NET_DBG("Cannot fragment IPv6 pkt (%d)", ret);
821 
822 				if (ret == -ENOMEM) {
823 					/* Try to send the packet if we could
824 					 * not allocate enough network packets
825 					 * and hope the original large packet
826 					 * can be sent ok.
827 					 */
828 					goto ignore_frag_error;
829 				}
830 			}
831 
832 			/* We need to unref here because we simulate the packet
833 			 * sending.
834 			 */
835 			net_pkt_unref(pkt);
836 
837 			/* No need to continue with the sending as the packet
838 			 * is now split and its fragments will be sent
839 			 * separately to network.
840 			 */
841 			return NET_CONTINUE;
842 		}
843 	}
844 ignore_frag_error:
845 #endif /* CONFIG_NET_IPV6_FRAGMENT */
846 
847 	/* If the IPv6 destination address is not link local, then try to get
848 	 * the next hop from routing table if we have multi interface routing
849 	 * enabled. The reason for this is that the neighbor cache will not
850 	 * contain public IPv6 address information so in that case we should
851 	 * not enter this branch.
852 	 */
853 	if ((net_pkt_lladdr_dst(pkt)->addr &&
854 	     ((IS_ENABLED(CONFIG_NET_ROUTING) &&
855 	      net_ipv6_is_ll_addr((struct in6_addr *)ip_hdr->dst)) ||
856 	      !IS_ENABLED(CONFIG_NET_ROUTING))) ||
857 	    net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->dst) ||
858 	    /* Workaround Linux bug, see:
859 	     * https://github.com/zephyrproject-rtos/zephyr/issues/3111
860 	     */
861 	    net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_POINTOPOINT) ||
862 	    net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_IPV6_NO_ND)) {
863 		return NET_OK;
864 	}
865 
866 	if (net_if_ipv6_addr_onlink(&iface, (struct in6_addr *)ip_hdr->dst)) {
867 		nexthop = (struct in6_addr *)ip_hdr->dst;
868 		net_pkt_set_iface(pkt, iface);
869 	} else if (net_ipv6_is_ll_addr((struct in6_addr *)ip_hdr->dst)) {
870 		nexthop = (struct in6_addr *)ip_hdr->dst;
871 	} else {
872 		/* We need to figure out where the destination
873 		 * host is located.
874 		 */
875 		bool try_route = false;
876 
877 		nexthop = check_route(NULL, (struct in6_addr *)ip_hdr->dst,
878 				      &try_route);
879 		if (!nexthop) {
880 			return NET_DROP;
881 		}
882 
883 		if (try_route) {
884 			goto try_send;
885 		}
886 	}
887 
888 	if (!iface) {
889 		/* This means that the dst was not onlink, so try to
890 		 * figure out the interface using nexthop instead.
891 		 */
892 		if (net_if_ipv6_addr_onlink(&iface, nexthop)) {
893 			net_pkt_set_iface(pkt, iface);
894 		} else {
895 			/* nexthop might be the nbr list, e.g. a link-local
896 			 * address of a connected peer.
897 			 */
898 			nbr = net_ipv6_nbr_lookup(NULL, nexthop);
899 			if (nbr) {
900 				iface = nbr->iface;
901 				net_pkt_set_iface(pkt, iface);
902 			} else {
903 				iface = net_pkt_iface(pkt);
904 			}
905 		}
906 
907 		/* If the above check returns null, we try to send
908 		 * the packet and hope for the best.
909 		 */
910 	}
911 
912 try_send:
913 	net_ipv6_nbr_lock();
914 
915 	nbr = nbr_lookup(&net_neighbor.table, iface, nexthop);
916 
917 	NET_DBG("Neighbor lookup %p (%d) iface %p/%d addr %s state %s", nbr,
918 		nbr ? nbr->idx : NET_NBR_LLADDR_UNKNOWN,
919 		iface, net_if_get_by_iface(iface),
920 		net_sprint_ipv6_addr(nexthop),
921 		nbr ? net_ipv6_nbr_state2str(net_ipv6_nbr_data(nbr)->state) :
922 		"-");
923 
924 	if (nbr && nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
925 		struct net_linkaddr_storage *lladdr;
926 
927 		lladdr = net_nbr_get_lladdr(nbr->idx);
928 
929 		net_pkt_lladdr_dst(pkt)->addr = lladdr->addr;
930 		net_pkt_lladdr_dst(pkt)->len = lladdr->len;
931 
932 		NET_DBG("Neighbor %p addr %s", nbr,
933 			net_sprint_ll_addr(lladdr->addr, lladdr->len));
934 
935 		/* Start the NUD if we are in STALE state.
936 		 * See RFC 4861 ch 7.3.3 for details.
937 		 */
938 #if defined(CONFIG_NET_IPV6_ND)
939 		if (net_ipv6_nbr_data(nbr)->state == NET_IPV6_NBR_STATE_STALE) {
940 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_DELAY);
941 
942 			ipv6_nd_restart_reachable_timer(nbr,
943 							DELAY_FIRST_PROBE_TIME);
944 		}
945 #endif
946 		net_ipv6_nbr_unlock();
947 		return NET_OK;
948 	}
949 
950 	net_ipv6_nbr_unlock();
951 
952 #if defined(CONFIG_NET_IPV6_ND)
953 	/* We need to send NS and wait for NA before sending the packet. If the packet was
954 	 * forwarded from another interface do not use the original source address.
955 	 */
956 	ret = net_ipv6_send_ns(net_pkt_iface(pkt), pkt,
957 			       net_pkt_forwarding(pkt) ? NULL : (struct in6_addr *)ip_hdr->src,
958 			       NULL, nexthop, false);
959 	if (ret < 0) {
960 		/* In case of an error, the NS send function will unref
961 		 * the pkt.
962 		 */
963 		NET_DBG("Cannot send NS (%d) iface %p/%d",
964 			ret, net_pkt_iface(pkt),
965 			net_if_get_by_iface(net_pkt_iface(pkt)));
966 	}
967 
968 	NET_DBG("pkt %p (buffer %p) will be sent later to iface %p/%d",
969 		pkt, pkt->buffer, net_pkt_iface(pkt),
970 		net_if_get_by_iface(net_pkt_iface(pkt)));
971 
972 	return NET_CONTINUE;
973 #else
974 	ARG_UNUSED(ret);
975 
976 	NET_DBG("pkt %p (buffer %p) cannot be sent to iface %p/%d, "
977 		"dropping it.", pkt, pkt->buffer,
978 		net_pkt_iface(pkt), net_if_get_by_iface(net_pkt_iface(pkt)));
979 
980 	return NET_DROP;
981 #endif /* CONFIG_NET_IPV6_ND */
982 }
983 
net_ipv6_nbr_lookup(struct net_if * iface,struct in6_addr * addr)984 struct net_nbr *net_ipv6_nbr_lookup(struct net_if *iface,
985 				    struct in6_addr *addr)
986 {
987 	struct net_nbr *nbr;
988 
989 	net_ipv6_nbr_lock();
990 	nbr = nbr_lookup(&net_neighbor.table, iface, addr);
991 	net_ipv6_nbr_unlock();
992 
993 	return nbr;
994 }
995 
net_ipv6_get_nbr(struct net_if * iface,uint8_t idx)996 struct net_nbr *net_ipv6_get_nbr(struct net_if *iface, uint8_t idx)
997 {
998 	struct net_nbr *ret = NULL;
999 	int i;
1000 
1001 	if (idx == NET_NBR_LLADDR_UNKNOWN) {
1002 		return NULL;
1003 	}
1004 
1005 	net_ipv6_nbr_lock();
1006 
1007 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
1008 		struct net_nbr *nbr = get_nbr(i);
1009 
1010 		if (nbr->ref) {
1011 			if (iface && nbr->iface != iface) {
1012 				continue;
1013 			}
1014 
1015 			if (nbr->idx == idx) {
1016 				ret = nbr;
1017 				break;
1018 			}
1019 		}
1020 	}
1021 
1022 	net_ipv6_nbr_unlock();
1023 	return ret;
1024 }
1025 
get_llao_len(struct net_if * iface)1026 static inline uint8_t get_llao_len(struct net_if *iface)
1027 {
1028 	uint8_t total_len = net_if_get_link_addr(iface)->len +
1029 			 sizeof(struct net_icmpv6_nd_opt_hdr);
1030 
1031 	return ROUND_UP(total_len, 8U);
1032 }
1033 
set_llao(struct net_pkt * pkt,struct net_linkaddr * lladdr,uint8_t llao_len,uint8_t type)1034 static inline bool set_llao(struct net_pkt *pkt,
1035 			    struct net_linkaddr *lladdr,
1036 			    uint8_t llao_len, uint8_t type)
1037 {
1038 	struct net_icmpv6_nd_opt_hdr opt_hdr = {
1039 		.type = type,
1040 		.len  = llao_len >> 3,
1041 	};
1042 
1043 	if (net_pkt_write(pkt, &opt_hdr,
1044 			  sizeof(struct net_icmpv6_nd_opt_hdr)) ||
1045 	    net_pkt_write(pkt, lladdr->addr, lladdr->len) ||
1046 	    net_pkt_memset(pkt, 0, llao_len - lladdr->len - 2)) {
1047 		return false;
1048 	}
1049 
1050 	return true;
1051 }
1052 
read_llao(struct net_pkt * pkt,uint8_t len,struct net_linkaddr_storage * llstorage)1053 static bool read_llao(struct net_pkt *pkt,
1054 		      uint8_t len,
1055 		      struct net_linkaddr_storage *llstorage)
1056 {
1057 	uint8_t padding;
1058 
1059 	llstorage->len = NET_LINK_ADDR_MAX_LENGTH;
1060 	if (net_pkt_lladdr_src(pkt)->len < llstorage->len) {
1061 		llstorage->len = net_pkt_lladdr_src(pkt)->len;
1062 	}
1063 
1064 	if (net_pkt_read(pkt, llstorage->addr, llstorage->len)) {
1065 		return false;
1066 	}
1067 
1068 	padding = len * 8U - 2 - llstorage->len;
1069 	if (padding) {
1070 		if (net_pkt_skip(pkt, padding)) {
1071 			return false;
1072 		}
1073 	}
1074 
1075 	return true;
1076 }
1077 
net_ipv6_send_na(struct net_if * iface,const struct in6_addr * src,const struct in6_addr * dst,const struct in6_addr * tgt,uint8_t flags)1078 int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
1079 		     const struct in6_addr *dst, const struct in6_addr *tgt,
1080 		     uint8_t flags)
1081 {
1082 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(na_access,
1083 					      struct net_icmpv6_na_hdr);
1084 	int ret = -ENOBUFS;
1085 	struct net_icmpv6_na_hdr *na_hdr;
1086 	struct net_pkt *pkt;
1087 	uint8_t llao_len;
1088 
1089 	llao_len = get_llao_len(iface);
1090 
1091 	pkt = net_pkt_alloc_with_buffer(iface,
1092 					sizeof(struct net_icmpv6_na_hdr) +
1093 					llao_len,
1094 					AF_INET6, IPPROTO_ICMPV6,
1095 					ND_NET_BUF_TIMEOUT);
1096 	if (!pkt) {
1097 		return -ENOMEM;
1098 	}
1099 
1100 	net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_ND_HOP_LIMIT);
1101 
1102 	if (net_ipv6_create(pkt, src, dst) ||
1103 	    net_icmpv6_create(pkt, NET_ICMPV6_NA, 0)) {
1104 		goto drop;
1105 	}
1106 
1107 	na_hdr = (struct net_icmpv6_na_hdr *)net_pkt_get_data(pkt, &na_access);
1108 	if (!na_hdr) {
1109 		goto drop;
1110 	}
1111 
1112 	/* Let's make sure reserved part is full of 0 */
1113 	memset(na_hdr, 0, sizeof(struct net_icmpv6_na_hdr));
1114 
1115 	na_hdr->flags = flags;
1116 	net_ipv6_addr_copy_raw(na_hdr->tgt, (uint8_t *)tgt);
1117 
1118 	if (net_pkt_set_data(pkt, &na_access)) {
1119 		goto drop;
1120 	}
1121 
1122 	if (!set_llao(pkt, net_if_get_link_addr(iface),
1123 		      llao_len, NET_ICMPV6_ND_OPT_TLLAO)) {
1124 		goto drop;
1125 	}
1126 
1127 	net_pkt_cursor_init(pkt);
1128 	net_ipv6_finalize(pkt, IPPROTO_ICMPV6);
1129 
1130 	dbg_addr_sent_tgt("Neighbor Advertisement", src, dst, &na_hdr->tgt,
1131 			  pkt);
1132 
1133 	if (net_send_data(pkt) < 0) {
1134 		net_stats_update_ipv6_nd_drop(iface);
1135 		ret = -EINVAL;
1136 
1137 		goto drop;
1138 	}
1139 
1140 	net_stats_update_icmp_sent(net_pkt_iface(pkt));
1141 	net_stats_update_ipv6_nd_sent(iface);
1142 
1143 	return 0;
1144 
1145 drop:
1146 	net_pkt_unref(pkt);
1147 
1148 	return ret;
1149 }
1150 
ns_routing_info(struct net_pkt * pkt,struct in6_addr * nexthop,struct in6_addr * tgt)1151 static void ns_routing_info(struct net_pkt *pkt,
1152 			    struct in6_addr *nexthop,
1153 			    struct in6_addr *tgt)
1154 {
1155 	if (CONFIG_NET_IPV6_LOG_LEVEL >= LOG_LEVEL_DBG) {
1156 		char out[NET_IPV6_ADDR_LEN];
1157 
1158 		snprintk(out, sizeof(out), "%s",
1159 			 net_sprint_ipv6_addr(nexthop));
1160 
1161 		if (net_ipv6_addr_cmp(nexthop, tgt)) {
1162 			NET_DBG("Routing to %s iface %p/%d",
1163 				out,
1164 				net_pkt_iface(pkt),
1165 				net_if_get_by_iface(net_pkt_iface(pkt)));
1166 		} else {
1167 			NET_DBG("Routing to %s via %s iface %p/%d",
1168 				net_sprint_ipv6_addr(tgt),
1169 				out,
1170 				net_pkt_iface(pkt),
1171 				net_if_get_by_iface(net_pkt_iface(pkt)));
1172 		}
1173 	}
1174 }
1175 
handle_ns_input(struct net_icmp_ctx * ctx,struct net_pkt * pkt,struct net_icmp_ip_hdr * hdr,struct net_icmp_hdr * icmp_hdr,void * user_data)1176 static int handle_ns_input(struct net_icmp_ctx *ctx,
1177 			   struct net_pkt *pkt,
1178 			   struct net_icmp_ip_hdr *hdr,
1179 			   struct net_icmp_hdr *icmp_hdr,
1180 			   void *user_data)
1181 {
1182 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ns_access,
1183 					      struct net_icmpv6_ns_hdr);
1184 	NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr);
1185 	struct net_ipv6_hdr *ip_hdr = hdr->ipv6;
1186 	uint16_t length = net_pkt_get_len(pkt);
1187 	uint8_t flags = 0U;
1188 	bool routing = false;
1189 	struct net_icmpv6_nd_opt_hdr *nd_opt_hdr;
1190 	struct net_icmpv6_ns_hdr *ns_hdr;
1191 	struct net_if_addr *ifaddr;
1192 	const struct in6_addr *na_src;
1193 	const struct in6_addr *na_dst;
1194 	struct in6_addr *tgt;
1195 	struct net_linkaddr_storage src_lladdr_s;
1196 	struct net_linkaddr src_lladdr;
1197 
1198 	src_lladdr.len = 0;
1199 
1200 	if (net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_IPV6_NO_ND)) {
1201 		goto drop;
1202 	}
1203 
1204 	ns_hdr = (struct net_icmpv6_ns_hdr *)net_pkt_get_data(pkt, &ns_access);
1205 	if (!ns_hdr) {
1206 		NET_ERR("DROP: NULL NS header");
1207 		goto drop;
1208 	}
1209 
1210 	dbg_addr_recv_tgt("Neighbor Solicitation",
1211 			  &ip_hdr->src, &ip_hdr->dst, &ns_hdr->tgt, pkt);
1212 
1213 	net_stats_update_ipv6_nd_recv(net_pkt_iface(pkt));
1214 
1215 	if (((length < (sizeof(struct net_ipv6_hdr) +
1216 			  sizeof(struct net_icmp_hdr) +
1217 			  sizeof(struct net_icmpv6_ns_hdr))) ||
1218 	    (ip_hdr->hop_limit != NET_IPV6_ND_HOP_LIMIT)) &&
1219 	    (net_ipv6_is_addr_mcast((struct in6_addr *)ns_hdr->tgt) &&
1220 	     icmp_hdr->code != 0U)) {
1221 		goto drop;
1222 	}
1223 
1224 	net_pkt_acknowledge_data(pkt, &ns_access);
1225 
1226 	net_pkt_set_ipv6_ext_opt_len(pkt, sizeof(struct net_icmpv6_ns_hdr));
1227 	length -= (sizeof(struct net_ipv6_hdr) + sizeof(struct net_icmp_hdr));
1228 
1229 	nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
1230 				net_pkt_get_data(pkt, &nd_access);
1231 
1232 	while (nd_opt_hdr && nd_opt_hdr->len > 0 &&
1233 	       net_pkt_ipv6_ext_opt_len(pkt) < length) {
1234 		uint8_t prev_opt_len;
1235 
1236 		net_pkt_acknowledge_data(pkt, &nd_access);
1237 
1238 		switch (nd_opt_hdr->type) {
1239 		case NET_ICMPV6_ND_OPT_SLLAO:
1240 			if (net_ipv6_is_addr_unspecified(
1241 					(struct in6_addr *)ip_hdr->src)) {
1242 				goto drop;
1243 			}
1244 
1245 			if (!read_llao(pkt, nd_opt_hdr->len, &src_lladdr_s)) {
1246 				NET_ERR("DROP: failed to read LLAO");
1247 				goto drop;
1248 			}
1249 
1250 			src_lladdr.len = src_lladdr_s.len;
1251 			src_lladdr.addr = src_lladdr_s.addr;
1252 
1253 			break;
1254 		default:
1255 			NET_DBG("Unknown ND option 0x%x", nd_opt_hdr->type);
1256 			break;
1257 		}
1258 
1259 		prev_opt_len = net_pkt_ipv6_ext_opt_len(pkt);
1260 
1261 		net_pkt_set_ipv6_ext_opt_len(pkt,
1262 					     net_pkt_ipv6_ext_opt_len(pkt) +
1263 					     (nd_opt_hdr->len << 3));
1264 
1265 		if (prev_opt_len >= net_pkt_ipv6_ext_opt_len(pkt)) {
1266 			NET_ERR("DROP: Corrupted NS message");
1267 			goto drop;
1268 		}
1269 
1270 		nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
1271 					net_pkt_get_data(pkt, &nd_access);
1272 	}
1273 
1274 	if (IS_ENABLED(CONFIG_NET_ROUTING)) {
1275 		ifaddr = net_if_ipv6_addr_lookup((struct in6_addr *)ns_hdr->tgt,
1276 						 NULL);
1277 	} else {
1278 		ifaddr = net_if_ipv6_addr_lookup_by_iface(
1279 			    net_pkt_iface(pkt), (struct in6_addr *)ns_hdr->tgt);
1280 	}
1281 
1282 	if (!ifaddr) {
1283 		if (IS_ENABLED(CONFIG_NET_ROUTING)) {
1284 			struct in6_addr *nexthop;
1285 
1286 			nexthop = check_route(NULL,
1287 					      (struct in6_addr *)ns_hdr->tgt,
1288 					      NULL);
1289 			if (nexthop) {
1290 				ns_routing_info(pkt, nexthop,
1291 						(struct in6_addr *)ns_hdr->tgt);
1292 				na_dst = (struct in6_addr *)ip_hdr->dst;
1293 				/* Note that the target is not the address of
1294 				 * the "nethop" as that is a link-local address
1295 				 * which is not routable.
1296 				 */
1297 				tgt = (struct in6_addr *)ns_hdr->tgt;
1298 
1299 				/* Source address must be one of our real
1300 				 * interface address where the packet was
1301 				 * received.
1302 				 */
1303 				na_src = net_if_ipv6_select_src_addr(
1304 						net_pkt_iface(pkt),
1305 						(struct in6_addr *)ip_hdr->src);
1306 				if (!na_src) {
1307 					NET_DBG("DROP: No interface address "
1308 						"for dst %s iface %p/%d",
1309 						net_sprint_ipv6_addr(&ip_hdr->src),
1310 						net_pkt_iface(pkt),
1311 						net_if_get_by_iface(
1312 							net_pkt_iface(pkt)));
1313 					goto drop;
1314 				}
1315 
1316 				routing = true;
1317 				goto nexthop_found;
1318 			}
1319 		}
1320 
1321 		NET_DBG("DROP: No such interface address %s",
1322 			net_sprint_ipv6_addr(&ns_hdr->tgt));
1323 		goto drop;
1324 	} else {
1325 		tgt = &ifaddr->address.in6_addr;
1326 		na_src = (struct in6_addr *)ip_hdr->dst;
1327 	}
1328 
1329 nexthop_found:
1330 
1331 #if !defined(CONFIG_NET_IPV6_DAD)
1332 	if (net_ipv6_is_addr_unspecified((struct in6_addr *)ip_hdr->src)) {
1333 		goto drop;
1334 	}
1335 
1336 #else /* CONFIG_NET_IPV6_DAD */
1337 
1338 	/* Do DAD */
1339 	if (net_ipv6_is_addr_unspecified((struct in6_addr *)ip_hdr->src)) {
1340 
1341 		if (!net_ipv6_is_addr_solicited_node((struct in6_addr *)ip_hdr->dst)) {
1342 			NET_DBG("DROP: Not solicited node addr %s",
1343 				net_sprint_ipv6_addr(&ip_hdr->dst));
1344 			goto drop;
1345 		}
1346 
1347 		if (ifaddr->addr_state == NET_ADDR_TENTATIVE) {
1348 			NET_DBG("DROP: DAD failed for %s iface %p/%d",
1349 				net_sprint_ipv6_addr(&ifaddr->address.in6_addr),
1350 				net_pkt_iface(pkt),
1351 				net_if_get_by_iface(net_pkt_iface(pkt)));
1352 
1353 			dad_failed(net_pkt_iface(pkt),
1354 				   &ifaddr->address.in6_addr);
1355 			goto drop;
1356 		}
1357 
1358 		/* We reuse the received packet for the NA addresses*/
1359 		net_ipv6_addr_create_ll_allnodes_mcast(
1360 					(struct in6_addr *)ip_hdr->dst);
1361 		net_ipaddr_copy((struct in6_addr *)ip_hdr->src,
1362 				net_if_ipv6_select_src_addr(
1363 					net_pkt_iface(pkt),
1364 					(struct in6_addr *)ip_hdr->dst));
1365 
1366 		na_src = (struct in6_addr *)ip_hdr->src;
1367 		na_dst = (struct in6_addr *)ip_hdr->dst;
1368 		flags = NET_ICMPV6_NA_FLAG_OVERRIDE;
1369 		goto send_na;
1370 	}
1371 #endif /* CONFIG_NET_IPV6_DAD */
1372 
1373 	if (net_ipv6_is_my_addr((struct in6_addr *)ip_hdr->src)) {
1374 		NET_DBG("DROP: Duplicate IPv6 %s address",
1375 			net_sprint_ipv6_addr(&ip_hdr->src));
1376 		goto drop;
1377 	}
1378 
1379 	/* Address resolution */
1380 	if (net_ipv6_is_addr_solicited_node((struct in6_addr *)ip_hdr->dst)) {
1381 		na_src = (struct in6_addr *)ns_hdr->tgt;
1382 		na_dst = (struct in6_addr *)ip_hdr->src;
1383 		flags = NET_ICMPV6_NA_FLAG_SOLICITED |
1384 			NET_ICMPV6_NA_FLAG_OVERRIDE;
1385 		goto send_na;
1386 	}
1387 
1388 	if (routing) {
1389 		/* No need to do NUD here when the target is being routed. */
1390 		goto send_na;
1391 	}
1392 
1393 	/* Neighbor Unreachability Detection (NUD) */
1394 	if (IS_ENABLED(CONFIG_NET_ROUTING)) {
1395 		ifaddr = net_if_ipv6_addr_lookup((struct in6_addr *)ip_hdr->dst,
1396 						 NULL);
1397 	} else {
1398 		ifaddr = net_if_ipv6_addr_lookup_by_iface(
1399 						net_pkt_iface(pkt),
1400 						(struct in6_addr *)ip_hdr->dst);
1401 	}
1402 
1403 	if (ifaddr) {
1404 		na_src = (struct in6_addr *)ns_hdr->tgt;
1405 		na_dst = (struct in6_addr *)ip_hdr->src;
1406 		tgt = &ifaddr->address.in6_addr;
1407 		flags = NET_ICMPV6_NA_FLAG_SOLICITED |
1408 			NET_ICMPV6_NA_FLAG_OVERRIDE;
1409 		goto send_na;
1410 	} else {
1411 		NET_DBG("DROP: NUD failed");
1412 		goto drop;
1413 	}
1414 
1415 send_na:
1416 	if (src_lladdr.len) {
1417 		if (!net_ipv6_nbr_add(net_pkt_iface(pkt),
1418 				      (struct in6_addr *)ip_hdr->src,
1419 				      &src_lladdr, false,
1420 				      NET_IPV6_NBR_STATE_INCOMPLETE)) {
1421 			goto drop;
1422 		}
1423 	}
1424 
1425 	if (!net_ipv6_send_na(net_pkt_iface(pkt), na_src,
1426 			      na_dst, tgt, flags)) {
1427 		return 0;
1428 	}
1429 
1430 	NET_DBG("DROP: Cannot send NA");
1431 
1432 	return -EIO;
1433 
1434 drop:
1435 	net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt));
1436 
1437 	return -EIO;
1438 }
1439 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
1440 
1441 #if defined(CONFIG_NET_IPV6_ND)
ipv6_nd_restart_reachable_timer(struct net_nbr * nbr,int64_t time)1442 static void ipv6_nd_restart_reachable_timer(struct net_nbr *nbr, int64_t time)
1443 {
1444 	int64_t remaining;
1445 
1446 	if (nbr) {
1447 		net_ipv6_nbr_data(nbr)->reachable = k_uptime_get();
1448 		net_ipv6_nbr_data(nbr)->reachable_timeout = time;
1449 	}
1450 
1451 	remaining = k_ticks_to_ms_ceil32(
1452 		k_work_delayable_remaining_get(&ipv6_nd_reachable_timer));
1453 	if (!remaining || remaining > time) {
1454 		k_work_reschedule(&ipv6_nd_reachable_timer, K_MSEC(time));
1455 	}
1456 }
1457 
ipv6_nd_reachable_timeout(struct k_work * work)1458 static void ipv6_nd_reachable_timeout(struct k_work *work)
1459 {
1460 	int64_t current = k_uptime_get();
1461 	struct net_nbr *nbr = NULL;
1462 	struct net_ipv6_nbr_data *data = NULL;
1463 	int ret;
1464 	int i;
1465 
1466 	net_ipv6_nbr_lock();
1467 
1468 	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
1469 		int64_t remaining;
1470 
1471 		nbr = get_nbr(i);
1472 		if (!nbr || !nbr->ref) {
1473 			continue;
1474 		}
1475 
1476 		data = net_ipv6_nbr_data(nbr);
1477 		if (!data) {
1478 			continue;
1479 		}
1480 
1481 		if (!data->reachable) {
1482 			continue;
1483 		}
1484 
1485 		remaining = data->reachable + data->reachable_timeout - current;
1486 		if (remaining > 0) {
1487 			ipv6_nd_restart_reachable_timer(NULL, remaining);
1488 			continue;
1489 		}
1490 
1491 		data->reachable = 0;
1492 
1493 		switch (data->state) {
1494 		case NET_IPV6_NBR_STATE_STATIC:
1495 			NET_ASSERT(false, "Static entry shall never timeout");
1496 			break;
1497 
1498 		case NET_IPV6_NBR_STATE_INCOMPLETE:
1499 			if (data->ns_count >= MAX_MULTICAST_SOLICIT) {
1500 				net_ipv6_nbr_rm(nbr->iface, &data->addr);
1501 			} else {
1502 				data->ns_count++;
1503 
1504 				NET_DBG("nbr %p incomplete count %u", nbr,
1505 					data->ns_count);
1506 
1507 				ret = net_ipv6_send_ns(nbr->iface, NULL, NULL,
1508 						       NULL, &data->addr,
1509 						       false);
1510 				if (ret < 0) {
1511 					NET_DBG("Cannot send NS (%d)", ret);
1512 				}
1513 			}
1514 			break;
1515 
1516 		case NET_IPV6_NBR_STATE_REACHABLE:
1517 			data->state = NET_IPV6_NBR_STATE_STALE;
1518 
1519 			NET_DBG("nbr %p moving %s state to STALE (%d)",
1520 				nbr,
1521 				net_sprint_ipv6_addr(&data->addr),
1522 				data->state);
1523 			break;
1524 
1525 		case NET_IPV6_NBR_STATE_STALE:
1526 			NET_DBG("nbr %p removing stale address %s",
1527 				nbr,
1528 				net_sprint_ipv6_addr(&data->addr));
1529 			net_ipv6_nbr_rm(nbr->iface, &data->addr);
1530 			break;
1531 
1532 		case NET_IPV6_NBR_STATE_DELAY:
1533 			data->state = NET_IPV6_NBR_STATE_PROBE;
1534 			data->ns_count = 0U;
1535 
1536 			NET_DBG("nbr %p moving %s state to PROBE (%d)",
1537 				nbr,
1538 				net_sprint_ipv6_addr(&data->addr),
1539 				data->state);
1540 
1541 			/* Intentionally continuing to probe state */
1542 			__fallthrough;
1543 
1544 		case NET_IPV6_NBR_STATE_PROBE:
1545 			if (data->ns_count >= MAX_UNICAST_SOLICIT) {
1546 				net_ipv6_nbr_rm(nbr->iface, &data->addr);
1547 			} else {
1548 				data->ns_count++;
1549 
1550 				NET_DBG("nbr %p probe count %u", nbr,
1551 					data->ns_count);
1552 
1553 				ret = net_ipv6_send_ns(nbr->iface, NULL, NULL,
1554 						       NULL, &data->addr,
1555 						       false);
1556 				if (ret < 0) {
1557 					NET_DBG("Cannot send NS (%d)", ret);
1558 				}
1559 
1560 				ipv6_nd_restart_reachable_timer(nbr,
1561 								RETRANS_TIMER);
1562 			}
1563 			break;
1564 		}
1565 	}
1566 
1567 	net_ipv6_nbr_unlock();
1568 }
1569 
net_ipv6_nbr_set_reachable_timer(struct net_if * iface,struct net_nbr * nbr)1570 void net_ipv6_nbr_set_reachable_timer(struct net_if *iface,
1571 				      struct net_nbr *nbr)
1572 {
1573 	uint32_t time;
1574 
1575 	time = net_if_ipv6_get_reachable_time(iface);
1576 
1577 	NET_ASSERT(time, "Zero reachable timeout!");
1578 
1579 	NET_DBG("Starting reachable timer nbr %p data %p time %d ms",
1580 		nbr, net_ipv6_nbr_data(nbr), time);
1581 
1582 	ipv6_nd_restart_reachable_timer(nbr, time);
1583 }
1584 
net_ipv6_nbr_reachability_hint(struct net_if * iface,const struct in6_addr * ipv6_addr)1585 void net_ipv6_nbr_reachability_hint(struct net_if *iface,
1586 				    const struct in6_addr *ipv6_addr)
1587 {
1588 	struct net_nbr *nbr = NULL;
1589 
1590 	net_ipv6_nbr_lock();
1591 
1592 	nbr = nbr_lookup(&net_neighbor.table, iface, ipv6_addr);
1593 
1594 	NET_DBG("nbr %p got rechability hint", nbr);
1595 
1596 	if (nbr && net_ipv6_nbr_data(nbr)->state != NET_IPV6_NBR_STATE_INCOMPLETE &&
1597 	    net_ipv6_nbr_data(nbr)->state != NET_IPV6_NBR_STATE_STATIC) {
1598 		ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_REACHABLE);
1599 
1600 		/* We might have active timer from PROBE */
1601 		net_ipv6_nbr_data(nbr)->reachable = 0;
1602 		net_ipv6_nbr_data(nbr)->reachable_timeout = 0;
1603 
1604 		net_ipv6_nbr_set_reachable_timer(iface, nbr);
1605 	}
1606 
1607 	net_ipv6_nbr_unlock();
1608 }
1609 #endif /* CONFIG_NET_IPV6_ND */
1610 
1611 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
handle_na_neighbor(struct net_pkt * pkt,struct net_icmpv6_na_hdr * na_hdr,uint16_t tllao_offset)1612 static inline bool handle_na_neighbor(struct net_pkt *pkt,
1613 				      struct net_icmpv6_na_hdr *na_hdr,
1614 				      uint16_t tllao_offset)
1615 {
1616 	struct net_linkaddr_storage lladdr = { 0 };
1617 	bool lladdr_changed = false;
1618 	struct net_linkaddr_storage *cached_lladdr;
1619 	struct net_pkt *pending;
1620 	struct net_nbr *nbr;
1621 
1622 	net_ipv6_nbr_lock();
1623 
1624 	nbr = nbr_lookup(&net_neighbor.table, net_pkt_iface(pkt),
1625 			 (struct in6_addr *)na_hdr->tgt);
1626 
1627 	NET_DBG("Neighbor lookup %p iface %p/%d addr %s", nbr,
1628 		net_pkt_iface(pkt), net_if_get_by_iface(net_pkt_iface(pkt)),
1629 		net_sprint_ipv6_addr(&na_hdr->tgt));
1630 
1631 	if (!nbr) {
1632 		nbr_print();
1633 
1634 		NET_DBG("No such neighbor found, msg discarded");
1635 		goto err;
1636 	}
1637 
1638 	if (tllao_offset) {
1639 		lladdr.len = net_pkt_lladdr_src(pkt)->len;
1640 
1641 		net_pkt_cursor_init(pkt);
1642 
1643 		if (net_pkt_skip(pkt, tllao_offset) ||
1644 		    net_pkt_read(pkt, lladdr.addr, lladdr.len)) {
1645 			goto err;
1646 		}
1647 	}
1648 
1649 	if (nbr->idx == NET_NBR_LLADDR_UNKNOWN) {
1650 		struct net_linkaddr nbr_lladdr;
1651 
1652 		if (!tllao_offset) {
1653 			NET_DBG("No target link layer address.");
1654 			goto err;
1655 		}
1656 
1657 		nbr_lladdr.len = lladdr.len;
1658 		nbr_lladdr.addr = lladdr.addr;
1659 
1660 		if (net_nbr_link(nbr, net_pkt_iface(pkt), &nbr_lladdr)) {
1661 			nbr_free(nbr);
1662 			goto err;
1663 		}
1664 
1665 		NET_DBG("[%d] nbr %p state %d IPv6 %s ll %s",
1666 			nbr->idx, nbr, net_ipv6_nbr_data(nbr)->state,
1667 			net_sprint_ipv6_addr(&na_hdr->tgt),
1668 			net_sprint_ll_addr(nbr_lladdr.addr, nbr_lladdr.len));
1669 	}
1670 
1671 	cached_lladdr = net_nbr_get_lladdr(nbr->idx);
1672 	if (!cached_lladdr) {
1673 		NET_DBG("No lladdr but index defined");
1674 		goto err;
1675 	}
1676 
1677 	if (tllao_offset) {
1678 		lladdr_changed = memcmp(lladdr.addr,
1679 					cached_lladdr->addr,
1680 					cached_lladdr->len);
1681 	}
1682 
1683 	/* Update the cached address if we do not yet known it */
1684 	if (net_ipv6_nbr_data(nbr)->state == NET_IPV6_NBR_STATE_INCOMPLETE) {
1685 		if (!tllao_offset) {
1686 			goto err;
1687 		}
1688 
1689 		if (lladdr_changed) {
1690 			dbg_update_neighbor_lladdr_raw(
1691 				lladdr.addr, cached_lladdr,
1692 				(struct in6_addr *)na_hdr->tgt);
1693 
1694 			net_linkaddr_set(cached_lladdr, lladdr.addr,
1695 					 cached_lladdr->len);
1696 		}
1697 
1698 		if (na_hdr->flags & NET_ICMPV6_NA_FLAG_SOLICITED) {
1699 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_REACHABLE);
1700 			net_ipv6_nbr_data(nbr)->ns_count = 0U;
1701 
1702 			/* We might have active timer from PROBE */
1703 			net_ipv6_nbr_data(nbr)->reachable = 0;
1704 			net_ipv6_nbr_data(nbr)->reachable_timeout = 0;
1705 
1706 			net_ipv6_nbr_set_reachable_timer(net_pkt_iface(pkt),
1707 							 nbr);
1708 		} else {
1709 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_STALE);
1710 		}
1711 
1712 		net_ipv6_nbr_data(nbr)->is_router =
1713 			(na_hdr->flags & NET_ICMPV6_NA_FLAG_ROUTER);
1714 
1715 		goto send_pending;
1716 	}
1717 
1718 	/* We do not update the address if override bit is not set
1719 	 * and we have a valid address in the cache.
1720 	 */
1721 	if (!(na_hdr->flags & NET_ICMPV6_NA_FLAG_OVERRIDE) && lladdr_changed) {
1722 		if (net_ipv6_nbr_data(nbr)->state ==
1723 		    NET_IPV6_NBR_STATE_REACHABLE) {
1724 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_STALE);
1725 		}
1726 
1727 		goto err;
1728 	}
1729 
1730 	if (na_hdr->flags & NET_ICMPV6_NA_FLAG_OVERRIDE ||
1731 	    (!(na_hdr->flags & NET_ICMPV6_NA_FLAG_OVERRIDE) &&
1732 	     tllao_offset && !lladdr_changed)) {
1733 
1734 		if (lladdr_changed) {
1735 			dbg_update_neighbor_lladdr_raw(
1736 				lladdr.addr, cached_lladdr,
1737 				(struct in6_addr *)na_hdr->tgt);
1738 
1739 			net_linkaddr_set(cached_lladdr, lladdr.addr,
1740 					 cached_lladdr->len);
1741 		}
1742 
1743 		if (na_hdr->flags & NET_ICMPV6_NA_FLAG_SOLICITED) {
1744 			ipv6_nbr_set_state(nbr, NET_IPV6_NBR_STATE_REACHABLE);
1745 
1746 			/* We might have active timer from PROBE */
1747 			net_ipv6_nbr_data(nbr)->reachable = 0;
1748 			net_ipv6_nbr_data(nbr)->reachable_timeout = 0;
1749 
1750 			net_ipv6_nbr_set_reachable_timer(net_pkt_iface(pkt),
1751 							 nbr);
1752 		} else {
1753 			if (lladdr_changed) {
1754 				ipv6_nbr_set_state(nbr,
1755 						   NET_IPV6_NBR_STATE_STALE);
1756 			}
1757 		}
1758 	}
1759 
1760 	if (net_ipv6_nbr_data(nbr)->is_router &&
1761 	    !(na_hdr->flags & NET_ICMPV6_NA_FLAG_ROUTER)) {
1762 		/* Update the routing if the peer is no longer
1763 		 * a router.
1764 		 */
1765 		/* FIXME */
1766 	}
1767 
1768 	net_ipv6_nbr_data(nbr)->is_router =
1769 		(na_hdr->flags & NET_ICMPV6_NA_FLAG_ROUTER);
1770 
1771 send_pending:
1772 	/* Next send any pending messages to the peer. */
1773 	pending = net_ipv6_nbr_data(nbr)->pending;
1774 	if (pending) {
1775 		NET_DBG("Sending pending %p to lladdr %s", pending,
1776 			net_sprint_ll_addr(cached_lladdr->addr, cached_lladdr->len));
1777 
1778 		if (net_send_data(pending) < 0) {
1779 			nbr_clear_ns_pending(net_ipv6_nbr_data(nbr));
1780 		} else {
1781 			net_ipv6_nbr_data(nbr)->pending = NULL;
1782 		}
1783 
1784 		net_pkt_unref(pending);
1785 	}
1786 
1787 	net_ipv6_nbr_unlock();
1788 	return true;
1789 
1790 err:
1791 	net_ipv6_nbr_unlock();
1792 	return false;
1793 }
1794 
handle_na_input(struct net_icmp_ctx * ctx,struct net_pkt * pkt,struct net_icmp_ip_hdr * hdr,struct net_icmp_hdr * icmp_hdr,void * user_data)1795 static int handle_na_input(struct net_icmp_ctx *ctx,
1796 			   struct net_pkt *pkt,
1797 			   struct net_icmp_ip_hdr *hdr,
1798 			   struct net_icmp_hdr *icmp_hdr,
1799 			   void *user_data)
1800 {
1801 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(na_access,
1802 					      struct net_icmpv6_na_hdr);
1803 	NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr);
1804 	struct net_ipv6_hdr *ip_hdr = hdr->ipv6;
1805 	uint16_t length = net_pkt_get_len(pkt);
1806 	uint16_t tllao_offset = 0U;
1807 	struct net_icmpv6_nd_opt_hdr *nd_opt_hdr;
1808 	struct net_icmpv6_na_hdr *na_hdr;
1809 	struct net_if_addr *ifaddr;
1810 
1811 	if (net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_IPV6_NO_ND)) {
1812 		goto drop;
1813 	}
1814 
1815 	na_hdr = (struct net_icmpv6_na_hdr *)net_pkt_get_data(pkt, &na_access);
1816 	if (!na_hdr) {
1817 		NET_ERR("DROP: NULL NA header");
1818 		goto drop;
1819 	}
1820 
1821 	dbg_addr_recv_tgt("Neighbor Advertisement",
1822 			  &ip_hdr->src, &ip_hdr->dst, &na_hdr->tgt, pkt);
1823 
1824 	net_stats_update_ipv6_nd_recv(net_pkt_iface(pkt));
1825 
1826 	if (((length < (sizeof(struct net_ipv6_hdr) +
1827 			sizeof(struct net_icmp_hdr) +
1828 			sizeof(struct net_icmpv6_na_hdr) +
1829 			sizeof(struct net_icmpv6_nd_opt_hdr))) ||
1830 	     (ip_hdr->hop_limit != NET_IPV6_ND_HOP_LIMIT) ||
1831 	     net_ipv6_is_addr_mcast((struct in6_addr *)na_hdr->tgt) ||
1832 	     (na_hdr->flags & NET_ICMPV6_NA_FLAG_SOLICITED &&
1833 	      net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->dst))) &&
1834 	    (icmp_hdr->code != 0U)) {
1835 		goto drop;
1836 	}
1837 
1838 	net_pkt_acknowledge_data(pkt, &na_access);
1839 
1840 	net_pkt_set_ipv6_ext_opt_len(pkt, sizeof(struct net_icmpv6_na_hdr));
1841 	length -= (sizeof(struct net_ipv6_hdr) + sizeof(struct net_icmp_hdr));
1842 
1843 	nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
1844 				net_pkt_get_data(pkt, &nd_access);
1845 
1846 	while (nd_opt_hdr && nd_opt_hdr->len &&
1847 	       net_pkt_ipv6_ext_opt_len(pkt) < length) {
1848 		uint8_t prev_opt_len;
1849 
1850 		switch (nd_opt_hdr->type) {
1851 		case NET_ICMPV6_ND_OPT_TLLAO:
1852 			tllao_offset = net_pkt_ip_hdr_len(pkt) +
1853 				net_pkt_ipv6_ext_len(pkt) +
1854 				sizeof(struct net_icmp_hdr) +
1855 				net_pkt_ipv6_ext_opt_len(pkt) + 1 + 1;
1856 			break;
1857 
1858 		default:
1859 			NET_DBG("Unknown ND option 0x%x", nd_opt_hdr->type);
1860 			break;
1861 		}
1862 
1863 		prev_opt_len = net_pkt_ipv6_ext_opt_len(pkt);
1864 
1865 		net_pkt_set_ipv6_ext_opt_len(pkt,
1866 					     net_pkt_ipv6_ext_opt_len(pkt) +
1867 					     (nd_opt_hdr->len << 3));
1868 
1869 		if (prev_opt_len >= net_pkt_ipv6_ext_opt_len(pkt)) {
1870 			NET_ERR("DROP: Corrupted NA message");
1871 			goto drop;
1872 		}
1873 
1874 		net_pkt_acknowledge_data(pkt, &nd_access);
1875 		nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
1876 					net_pkt_get_data(pkt, &nd_access);
1877 	}
1878 
1879 	ifaddr = net_if_ipv6_addr_lookup_by_iface(net_pkt_iface(pkt),
1880 						  (struct in6_addr *)na_hdr->tgt);
1881 	if (ifaddr) {
1882 		NET_DBG("Interface %p/%d already has address %s",
1883 			net_pkt_iface(pkt),
1884 			net_if_get_by_iface(net_pkt_iface(pkt)),
1885 			net_sprint_ipv6_addr(&na_hdr->tgt));
1886 
1887 #if defined(CONFIG_NET_IPV6_DAD)
1888 		if (ifaddr->addr_state == NET_ADDR_TENTATIVE) {
1889 			dad_failed(net_pkt_iface(pkt),
1890 				   (struct in6_addr *)na_hdr->tgt);
1891 		}
1892 #endif /* CONFIG_NET_IPV6_DAD */
1893 
1894 		goto drop;
1895 	}
1896 
1897 	if (!handle_na_neighbor(pkt, na_hdr, tllao_offset)) {
1898 		/* Update the statistics but silently drop NA msg if the sender
1899 		 * is not known or if there was an error in the message.
1900 		 * Returning <0 will cause error message to be printed which
1901 		 * is too much for this non error.
1902 		 */
1903 		net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt));
1904 	}
1905 
1906 	return 0;
1907 
1908 drop:
1909 	net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt));
1910 
1911 	return -EIO;
1912 }
1913 
net_ipv6_send_ns(struct net_if * iface,struct net_pkt * pending,const struct in6_addr * src,const struct in6_addr * dst,const struct in6_addr * tgt,bool is_my_address)1914 int net_ipv6_send_ns(struct net_if *iface,
1915 		     struct net_pkt *pending,
1916 		     const struct in6_addr *src,
1917 		     const struct in6_addr *dst,
1918 		     const struct in6_addr *tgt,
1919 		     bool is_my_address)
1920 {
1921 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ns_access,
1922 					      struct net_icmpv6_ns_hdr);
1923 	struct net_pkt *pkt = NULL;
1924 	int ret = -ENOBUFS;
1925 	struct net_icmpv6_ns_hdr *ns_hdr;
1926 	struct in6_addr node_dst;
1927 	struct net_nbr *nbr;
1928 	uint8_t llao_len;
1929 
1930 	if (!dst) {
1931 		net_ipv6_addr_create_solicited_node(tgt, &node_dst);
1932 		dst = &node_dst;
1933 	}
1934 
1935 	llao_len = get_llao_len(iface);
1936 
1937 	if (is_my_address) {
1938 		src = net_ipv6_unspecified_address();
1939 		llao_len = 0U;
1940 	} else {
1941 		if (!src) {
1942 			src = net_if_ipv6_select_src_addr(iface, tgt);
1943 		}
1944 
1945 		if (net_ipv6_is_addr_unspecified(src)) {
1946 			NET_DBG("No source address for NS (tgt %s)",
1947 				net_sprint_ipv6_addr(tgt));
1948 			ret = -EINVAL;
1949 
1950 			goto drop;
1951 		}
1952 	}
1953 
1954 	pkt = net_pkt_alloc_with_buffer(iface,
1955 					sizeof(struct net_icmpv6_ns_hdr) +
1956 					llao_len,
1957 					AF_INET6, IPPROTO_ICMPV6,
1958 					ND_NET_BUF_TIMEOUT);
1959 	if (!pkt) {
1960 		ret = -ENOMEM;
1961 		goto drop;
1962 	}
1963 
1964 	/* Avoid recursive loop with network packet capturing */
1965 	if (IS_ENABLED(CONFIG_NET_CAPTURE) && pending) {
1966 		net_pkt_set_captured(pkt, net_pkt_is_captured(pending));
1967 	}
1968 
1969 	net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_ND_HOP_LIMIT);
1970 
1971 	if (net_ipv6_create(pkt, src, dst) ||
1972 	    net_icmpv6_create(pkt, NET_ICMPV6_NS, 0)) {
1973 		goto drop;
1974 	}
1975 
1976 	ns_hdr = (struct net_icmpv6_ns_hdr *)net_pkt_get_data(pkt, &ns_access);
1977 	if (!ns_hdr) {
1978 		goto drop;
1979 	}
1980 
1981 	ns_hdr->reserved = 0U;
1982 	net_ipv6_addr_copy_raw(ns_hdr->tgt, (uint8_t *)tgt);
1983 
1984 	if (net_pkt_set_data(pkt, &ns_access)) {
1985 		goto drop;
1986 	}
1987 
1988 	if (!is_my_address) {
1989 		if (!set_llao(pkt, net_if_get_link_addr(iface),
1990 			      llao_len, NET_ICMPV6_ND_OPT_SLLAO)) {
1991 			goto drop;
1992 		}
1993 	}
1994 
1995 	net_pkt_cursor_init(pkt);
1996 	net_ipv6_finalize(pkt, IPPROTO_ICMPV6);
1997 
1998 	net_ipv6_nbr_lock();
1999 	nbr = add_nbr(iface, tgt, false,
2000 		      NET_IPV6_NBR_STATE_INCOMPLETE);
2001 	if (!nbr) {
2002 		NET_DBG("Could not create new neighbor %s",
2003 			net_sprint_ipv6_addr(&ns_hdr->tgt));
2004 		net_ipv6_nbr_unlock();
2005 		goto drop;
2006 	}
2007 
2008 	if (pending) {
2009 		if (!net_ipv6_nbr_data(nbr)->pending) {
2010 			net_ipv6_nbr_data(nbr)->pending = net_pkt_ref(pending);
2011 		} else {
2012 			NET_DBG("Packet %p already pending for "
2013 				"operation. Discarding pending %p and pkt %p",
2014 				net_ipv6_nbr_data(nbr)->pending, pending, pkt);
2015 			net_ipv6_nbr_unlock();
2016 			goto drop;
2017 		}
2018 
2019 		NET_DBG("Setting timeout %d for NS", NS_REPLY_TIMEOUT);
2020 
2021 		net_ipv6_nbr_data(nbr)->send_ns = k_uptime_get();
2022 
2023 		/* Let's start the timer if necessary */
2024 		if (!k_work_delayable_remaining_get(&ipv6_ns_reply_timer)) {
2025 			k_work_reschedule(&ipv6_ns_reply_timer,
2026 					  K_MSEC(NS_REPLY_TIMEOUT));
2027 		}
2028 	}
2029 
2030 	dbg_addr_sent_tgt("Neighbor Solicitation", src, dst, &ns_hdr->tgt,
2031 			  pkt);
2032 
2033 	if (net_send_data(pkt) < 0) {
2034 		NET_DBG("Cannot send NS %p (pending %p)", pkt, pending);
2035 
2036 		if (pending) {
2037 			nbr_clear_ns_pending(net_ipv6_nbr_data(nbr));
2038 			pending = NULL;
2039 		}
2040 
2041 		net_ipv6_nbr_unlock();
2042 		goto drop;
2043 	}
2044 
2045 	net_ipv6_nbr_unlock();
2046 
2047 	net_stats_update_icmp_sent(net_pkt_iface(pkt));
2048 	net_stats_update_ipv6_nd_sent(iface);
2049 
2050 	return 0;
2051 
2052 drop:
2053 	if (pending) {
2054 		net_pkt_unref(pending);
2055 	}
2056 
2057 	if (pkt) {
2058 		net_pkt_unref(pkt);
2059 	}
2060 
2061 	net_stats_update_ipv6_nd_drop(iface);
2062 
2063 	return ret;
2064 }
2065 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
2066 
2067 #if defined(CONFIG_NET_IPV6_ND)
net_ipv6_send_rs(struct net_if * iface)2068 int net_ipv6_send_rs(struct net_if *iface)
2069 {
2070 	uint8_t llao_len = 0U;
2071 	int ret = -ENOBUFS;
2072 	const struct in6_addr *src;
2073 	struct in6_addr dst;
2074 	struct net_pkt *pkt;
2075 
2076 	net_ipv6_addr_create_ll_allrouters_mcast(&dst);
2077 	src = net_if_ipv6_select_src_addr(iface, &dst);
2078 
2079 	if (!net_ipv6_is_addr_unspecified(src)) {
2080 		llao_len = get_llao_len(iface);
2081 	}
2082 
2083 	pkt = net_pkt_alloc_with_buffer(iface,
2084 					sizeof(struct net_icmpv6_rs_hdr) +
2085 					llao_len,
2086 					AF_INET6, IPPROTO_ICMPV6,
2087 					ND_NET_BUF_TIMEOUT);
2088 	if (!pkt) {
2089 		return -ENOMEM;
2090 	}
2091 
2092 	net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_ND_HOP_LIMIT);
2093 
2094 	if (net_ipv6_create(pkt, src, &dst) ||
2095 	    net_icmpv6_create(pkt, NET_ICMPV6_RS, 0) ||
2096 	    net_pkt_memset(pkt, 0, sizeof(struct net_icmpv6_rs_hdr))) {
2097 		goto drop;
2098 	}
2099 
2100 	if (llao_len > 0) {
2101 		if (!set_llao(pkt, net_if_get_link_addr(iface),
2102 			      llao_len, NET_ICMPV6_ND_OPT_SLLAO)) {
2103 			goto drop;
2104 		}
2105 	}
2106 
2107 	net_pkt_cursor_init(pkt);
2108 	net_ipv6_finalize(pkt, IPPROTO_ICMPV6);
2109 
2110 	dbg_addr_sent("Router Solicitation", src, &dst, pkt);
2111 
2112 	if (net_send_data(pkt) < 0) {
2113 		net_stats_update_ipv6_nd_drop(iface);
2114 		ret = -EINVAL;
2115 
2116 		goto drop;
2117 	}
2118 
2119 	net_stats_update_icmp_sent(net_pkt_iface(pkt));
2120 	net_stats_update_ipv6_nd_sent(iface);
2121 
2122 	return 0;
2123 
2124 drop:
2125 	net_pkt_unref(pkt);
2126 
2127 	return ret;
2128 }
2129 
net_ipv6_start_rs(struct net_if * iface)2130 int net_ipv6_start_rs(struct net_if *iface)
2131 {
2132 	return net_ipv6_send_rs(iface);
2133 }
2134 
handle_ra_neighbor(struct net_pkt * pkt,uint8_t len)2135 static inline struct net_nbr *handle_ra_neighbor(struct net_pkt *pkt, uint8_t len)
2136 {
2137 	struct net_linkaddr lladdr;
2138 	struct net_linkaddr_storage llstorage;
2139 
2140 	if (!read_llao(pkt, len, &llstorage)) {
2141 		return NULL;
2142 	}
2143 
2144 	lladdr.len = llstorage.len;
2145 	lladdr.addr = llstorage.addr;
2146 
2147 	return net_ipv6_nbr_add(net_pkt_iface(pkt),
2148 				(struct in6_addr *)NET_IPV6_HDR(pkt)->src,
2149 				&lladdr, true,
2150 				NET_IPV6_NBR_STATE_STALE);
2151 }
2152 
handle_prefix_onlink(struct net_pkt * pkt,struct net_icmpv6_nd_opt_prefix_info * prefix_info)2153 static inline void handle_prefix_onlink(struct net_pkt *pkt,
2154 			struct net_icmpv6_nd_opt_prefix_info *prefix_info)
2155 {
2156 	struct net_if_ipv6_prefix *prefix;
2157 
2158 	prefix = net_if_ipv6_prefix_lookup(net_pkt_iface(pkt),
2159 					   (struct in6_addr *)prefix_info->prefix,
2160 					   prefix_info->prefix_len);
2161 	if (!prefix) {
2162 		if (!prefix_info->valid_lifetime) {
2163 			return;
2164 		}
2165 
2166 		prefix = net_if_ipv6_prefix_add(net_pkt_iface(pkt),
2167 						(struct in6_addr *)prefix_info->prefix,
2168 						prefix_info->prefix_len,
2169 						prefix_info->valid_lifetime);
2170 		if (prefix) {
2171 			NET_DBG("Interface %p/%d add prefix %s/%d lifetime %u",
2172 				net_pkt_iface(pkt),
2173 				net_if_get_by_iface(net_pkt_iface(pkt)),
2174 				net_sprint_ipv6_addr(&prefix_info->prefix),
2175 				prefix_info->prefix_len,
2176 				prefix_info->valid_lifetime);
2177 		} else {
2178 			NET_ERR("Prefix %s/%d could not be added to "
2179 				"iface %p/%d",
2180 				net_sprint_ipv6_addr(&prefix_info->prefix),
2181 				prefix_info->prefix_len,
2182 				net_pkt_iface(pkt),
2183 				net_if_get_by_iface(net_pkt_iface(pkt)));
2184 
2185 			return;
2186 		}
2187 	}
2188 
2189 	switch (prefix_info->valid_lifetime) {
2190 	case 0:
2191 		NET_DBG("Interface %p/%d delete prefix %s/%d",
2192 			net_pkt_iface(pkt),
2193 			net_if_get_by_iface(net_pkt_iface(pkt)),
2194 			net_sprint_ipv6_addr(&prefix_info->prefix),
2195 			prefix_info->prefix_len);
2196 
2197 		net_if_ipv6_prefix_rm(net_pkt_iface(pkt),
2198 				      &prefix->prefix,
2199 				      prefix->len);
2200 		break;
2201 
2202 	case NET_IPV6_ND_INFINITE_LIFETIME:
2203 		NET_DBG("Interface %p/%d prefix %s/%d infinite",
2204 			net_pkt_iface(pkt),
2205 			net_if_get_by_iface(net_pkt_iface(pkt)),
2206 			net_sprint_ipv6_addr(&prefix->prefix),
2207 			prefix->len);
2208 
2209 		net_if_ipv6_prefix_set_lf(prefix, true);
2210 		break;
2211 
2212 	default:
2213 		NET_DBG("Interface %p/%d update prefix %s/%u lifetime %u",
2214 			net_pkt_iface(pkt),
2215 			net_if_get_by_iface(net_pkt_iface(pkt)),
2216 			net_sprint_ipv6_addr(&prefix_info->prefix),
2217 			prefix_info->prefix_len, prefix_info->valid_lifetime);
2218 
2219 		net_if_ipv6_prefix_set_lf(prefix, false);
2220 		net_if_ipv6_prefix_set_timer(prefix,
2221 					     prefix_info->valid_lifetime);
2222 		break;
2223 	}
2224 }
2225 
2226 #define TWO_HOURS (2 * 60 * 60)
2227 
remaining_lifetime(struct net_if_addr * ifaddr)2228 static inline uint32_t remaining_lifetime(struct net_if_addr *ifaddr)
2229 {
2230 	return net_timeout_remaining(&ifaddr->lifetime, k_uptime_get_32());
2231 }
2232 
handle_prefix_autonomous(struct net_pkt * pkt,struct net_icmpv6_nd_opt_prefix_info * prefix_info)2233 static inline void handle_prefix_autonomous(struct net_pkt *pkt,
2234 			struct net_icmpv6_nd_opt_prefix_info *prefix_info)
2235 {
2236 	struct net_if *iface = net_pkt_iface(pkt);
2237 	struct in6_addr addr = { };
2238 	struct net_if_addr *ifaddr;
2239 
2240 	/* Create IPv6 address using the given prefix and iid. We first
2241 	 * setup link local address, and then copy prefix over first 8
2242 	 * bytes of that address.
2243 	 */
2244 	net_ipv6_addr_create_iid(&addr, net_if_get_link_addr(iface));
2245 	memcpy(&addr, prefix_info->prefix, sizeof(struct in6_addr) / 2);
2246 
2247 	ifaddr = net_if_ipv6_addr_lookup(&addr, NULL);
2248 	if (ifaddr && ifaddr->addr_type == NET_ADDR_AUTOCONF) {
2249 		if (prefix_info->valid_lifetime ==
2250 		    NET_IPV6_ND_INFINITE_LIFETIME) {
2251 			net_if_addr_set_lf(ifaddr, true);
2252 			return;
2253 		}
2254 
2255 		/* RFC 4862 ch 5.5.3 */
2256 		if ((prefix_info->valid_lifetime > TWO_HOURS) ||
2257 		    (prefix_info->valid_lifetime >
2258 		     remaining_lifetime(ifaddr))) {
2259 			NET_DBG("Timer updating for address %s "
2260 				"long lifetime %u secs",
2261 				net_sprint_ipv6_addr(&addr),
2262 				prefix_info->valid_lifetime);
2263 
2264 			net_if_ipv6_addr_update_lifetime(
2265 				ifaddr, prefix_info->valid_lifetime);
2266 		} else {
2267 			NET_DBG("Timer updating for address %s "
2268 				"lifetime %u secs",
2269 				net_sprint_ipv6_addr(&addr),
2270 				TWO_HOURS);
2271 
2272 			net_if_ipv6_addr_update_lifetime(ifaddr, TWO_HOURS);
2273 		}
2274 
2275 		net_if_addr_set_lf(ifaddr, false);
2276 	} else {
2277 		if (prefix_info->valid_lifetime ==
2278 		    NET_IPV6_ND_INFINITE_LIFETIME) {
2279 			net_if_ipv6_addr_add(iface, &addr,
2280 					     NET_ADDR_AUTOCONF, 0);
2281 		} else {
2282 			net_if_ipv6_addr_add(iface, &addr, NET_ADDR_AUTOCONF,
2283 					     prefix_info->valid_lifetime);
2284 		}
2285 	}
2286 
2287 	/* If privacy extensions are enabled, then start the procedure for that
2288 	 * too.
2289 	 */
2290 	if (IS_ENABLED(CONFIG_NET_IPV6_PE) && iface->pe_enabled) {
2291 		net_ipv6_pe_start(iface,
2292 				  (const struct in6_addr *)prefix_info->prefix,
2293 				  prefix_info->valid_lifetime,
2294 				  prefix_info->preferred_lifetime);
2295 	}
2296 }
2297 
handle_ra_prefix(struct net_pkt * pkt)2298 static inline bool handle_ra_prefix(struct net_pkt *pkt)
2299 {
2300 	NET_PKT_DATA_ACCESS_DEFINE(rapfx_access,
2301 				   struct net_icmpv6_nd_opt_prefix_info);
2302 	struct net_icmpv6_nd_opt_prefix_info *pfx_info;
2303 	uint32_t valid_lifetime, preferred_lifetime;
2304 
2305 	pfx_info = (struct net_icmpv6_nd_opt_prefix_info *)
2306 				net_pkt_get_data(pkt, &rapfx_access);
2307 	if (!pfx_info) {
2308 		return false;
2309 	}
2310 
2311 	net_pkt_acknowledge_data(pkt, &rapfx_access);
2312 
2313 	valid_lifetime = ntohl(pfx_info->valid_lifetime);
2314 	preferred_lifetime = ntohl(pfx_info->preferred_lifetime);
2315 
2316 	if (valid_lifetime >= preferred_lifetime &&
2317 	    !net_ipv6_is_ll_addr((struct in6_addr *)pfx_info->prefix)) {
2318 		if (pfx_info->flags & NET_ICMPV6_RA_FLAG_ONLINK) {
2319 			handle_prefix_onlink(pkt, pfx_info);
2320 		}
2321 
2322 		if ((pfx_info->flags & NET_ICMPV6_RA_FLAG_AUTONOMOUS) &&
2323 		    valid_lifetime &&
2324 		    (pfx_info->prefix_len == NET_IPV6_DEFAULT_PREFIX_LEN)) {
2325 			handle_prefix_autonomous(pkt, pfx_info);
2326 		}
2327 	}
2328 
2329 	return true;
2330 }
2331 
2332 #if defined(CONFIG_NET_6LO_CONTEXT)
2333 /* 6lowpan Context Option RFC 6775, 4.2 */
handle_ra_6co(struct net_pkt * pkt,uint8_t len)2334 static inline bool handle_ra_6co(struct net_pkt *pkt, uint8_t len)
2335 {
2336 	NET_PKT_DATA_ACCESS_DEFINE(ctx_access, struct net_icmpv6_nd_opt_6co);
2337 	struct net_icmpv6_nd_opt_6co *context;
2338 
2339 	context = (struct net_icmpv6_nd_opt_6co *)
2340 				net_pkt_get_data(pkt, &ctx_access);
2341 	if (!context) {
2342 		return false;
2343 	}
2344 
2345 	/* RFC 6775, 4.2
2346 	 * Context Length: 8-bit unsigned integer.  The number of leading
2347 	 * bits in the Context Prefix field that are valid.  The value ranges
2348 	 * from 0 to 128.  If it is more than 64, then the Length MUST be 3.
2349 	 */
2350 	if ((context->context_len > 64 && len != 3U) ||
2351 	    (context->context_len <= 64U && len != 2U)) {
2352 		return false;
2353 	}
2354 
2355 	context->context_len = context->context_len / 8U;
2356 
2357 	/* context_len: The number of leading bits in the Context Prefix
2358 	 * field that are valid. Rest must be set to 0 by the sender and
2359 	 * ignored by the receiver. But since there is no way to make sure
2360 	 * the sender followed the rule, let's make sure rest is set to 0.
2361 	 */
2362 	if (context->context_len != sizeof(context->prefix)) {
2363 		(void)memset(context->prefix + context->context_len, 0,
2364 			     sizeof(context->prefix) - context->context_len);
2365 	}
2366 
2367 	net_6lo_set_context(net_pkt_iface(pkt), context);
2368 
2369 	return true;
2370 }
2371 #endif
2372 
handle_ra_route_info(struct net_pkt * pkt,uint8_t len)2373 static inline bool handle_ra_route_info(struct net_pkt *pkt, uint8_t len)
2374 {
2375 	NET_PKT_DATA_ACCESS_DEFINE(routeinfo_access,
2376 				   struct net_icmpv6_nd_opt_route_info);
2377 	struct net_icmpv6_nd_opt_route_info *route_info;
2378 	struct net_route_entry *route;
2379 	struct in6_addr prefix_buf = { 0 };
2380 	uint8_t prefix_field_len = (len - 1) * 8;
2381 	uint32_t route_lifetime;
2382 	uint8_t prefix_len;
2383 	uint8_t preference;
2384 	int ret;
2385 
2386 	route_info = (struct net_icmpv6_nd_opt_route_info *)
2387 				net_pkt_get_data(pkt, &routeinfo_access);
2388 	if (!route_info) {
2389 		return false;
2390 	}
2391 
2392 	ret = net_pkt_acknowledge_data(pkt, &routeinfo_access);
2393 	if (ret < 0) {
2394 		return false;
2395 	}
2396 
2397 	prefix_len = route_info->prefix_len;
2398 	route_lifetime = ntohl(route_info->route_lifetime);
2399 	preference = route_info->flags.prf;
2400 
2401 	ret = net_pkt_read(pkt, &prefix_buf, prefix_field_len);
2402 	if (ret < 0) {
2403 		NET_ERR("Error reading prefix, %d", ret);
2404 		return false;
2405 	}
2406 
2407 	if (route_lifetime == 0) {
2408 		route = net_route_lookup(net_pkt_orig_iface(pkt), &prefix_buf);
2409 		if (route != NULL) {
2410 			ret = net_route_del(route);
2411 			if (ret < 0) {
2412 				NET_DBG("Failed to delete route");
2413 			}
2414 		}
2415 	} else {
2416 		route = net_route_add(net_pkt_orig_iface(pkt),
2417 				      &prefix_buf,
2418 				      prefix_len,
2419 				      (struct in6_addr *)NET_IPV6_HDR(pkt)->src,
2420 				      route_lifetime,
2421 				      preference);
2422 		if (route == NULL) {
2423 			NET_DBG("Failed to add route");
2424 		}
2425 	}
2426 
2427 	return true;
2428 }
2429 
2430 #if defined(CONFIG_NET_IPV6_RA_RDNSS)
handle_ra_rdnss(struct net_pkt * pkt,uint8_t len)2431 static inline bool handle_ra_rdnss(struct net_pkt *pkt, uint8_t len)
2432 {
2433 	NET_PKT_DATA_ACCESS_DEFINE(rdnss_access, struct net_icmpv6_nd_opt_rdnss);
2434 	struct net_icmpv6_nd_opt_rdnss *rdnss;
2435 	struct dns_resolve_context *ctx;
2436 	struct sockaddr_in6 dns = {
2437 		.sin6_family = AF_INET6
2438 	};
2439 	const struct sockaddr *dns_servers[] = {
2440 		(struct sockaddr *)&dns, NULL
2441 	};
2442 	size_t rdnss_size;
2443 	int ret;
2444 
2445 	rdnss = (struct net_icmpv6_nd_opt_rdnss *) net_pkt_get_data(pkt, &rdnss_access);
2446 	if (!rdnss) {
2447 		return false;
2448 	}
2449 
2450 	ret = net_pkt_acknowledge_data(pkt, &rdnss_access);
2451 	if (ret < 0) {
2452 		return false;
2453 	}
2454 
2455 	rdnss_size = len * 8U - 2 - sizeof(struct net_icmpv6_nd_opt_rdnss);
2456 	if ((rdnss_size % NET_IPV6_ADDR_SIZE) != 0) {
2457 		return false;
2458 	}
2459 
2460 	/* Recursive DNS servers option may present 1 or more addresses,
2461 	 * each 16 bytes in length. DNS servers should be listed in order
2462 	 * of preference, choose the first and skip the rest.
2463 	 */
2464 	ret = net_pkt_read(pkt, dns.sin6_addr.s6_addr, NET_IPV6_ADDR_SIZE);
2465 	if (ret < 0) {
2466 		NET_ERR("Failed to read RDNSS address, %d", ret);
2467 		return false;
2468 	}
2469 
2470 	/* Skip the rest of the DNS servers. */
2471 	if (net_pkt_skip(pkt, rdnss_size - NET_IPV6_ADDR_SIZE)) {
2472 		NET_ERR("Failed to skip RDNSS address, %d", ret);
2473 		return false;
2474 	}
2475 
2476 	/* TODO: Handle lifetime. */
2477 	ctx = dns_resolve_get_default();
2478 	ret = dns_resolve_reconfigure(ctx, NULL, dns_servers);
2479 	if (ret < 0) {
2480 		NET_DBG("Failed to set RDNSS resolve address: %d", ret);
2481 	}
2482 
2483 	return true;
2484 }
2485 #endif
2486 
handle_ra_input(struct net_icmp_ctx * ctx,struct net_pkt * pkt,struct net_icmp_ip_hdr * hdr,struct net_icmp_hdr * icmp_hdr,void * user_data)2487 static int handle_ra_input(struct net_icmp_ctx *ctx,
2488 			   struct net_pkt *pkt,
2489 			   struct net_icmp_ip_hdr *hdr,
2490 			   struct net_icmp_hdr *icmp_hdr,
2491 			   void *user_data)
2492 {
2493 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ra_access,
2494 					      struct net_icmpv6_ra_hdr);
2495 	NET_PKT_DATA_ACCESS_DEFINE(nd_access, struct net_icmpv6_nd_opt_hdr);
2496 	struct net_ipv6_hdr *ip_hdr = hdr->ipv6;
2497 	uint16_t length = net_pkt_get_len(pkt);
2498 	struct net_nbr *nbr = NULL;
2499 	struct net_icmpv6_nd_opt_hdr *nd_opt_hdr;
2500 	struct net_icmpv6_ra_hdr *ra_hdr;
2501 	struct net_if_router *router;
2502 	uint32_t mtu, reachable_time, retrans_timer;
2503 	uint16_t router_lifetime;
2504 
2505 	ARG_UNUSED(user_data);
2506 
2507 	if (net_if_flag_is_set(net_pkt_iface(pkt), NET_IF_IPV6_NO_ND)) {
2508 		goto drop;
2509 	}
2510 
2511 	ra_hdr = (struct net_icmpv6_ra_hdr *)net_pkt_get_data(pkt, &ra_access);
2512 	if (!ra_hdr) {
2513 		NET_ERR("DROP: NULL RA header");
2514 		goto drop;
2515 	}
2516 
2517 	dbg_addr_recv("Router Advertisement", &ip_hdr->src, &ip_hdr->dst, pkt);
2518 
2519 	net_stats_update_ipv6_nd_recv(net_pkt_iface(pkt));
2520 
2521 	if (((length < (sizeof(struct net_ipv6_hdr) +
2522 			sizeof(struct net_icmp_hdr) +
2523 			sizeof(struct net_icmpv6_ra_hdr) +
2524 			sizeof(struct net_icmpv6_nd_opt_hdr))) ||
2525 	     (ip_hdr->hop_limit != NET_IPV6_ND_HOP_LIMIT) ||
2526 	     !net_ipv6_is_ll_addr((struct in6_addr *)ip_hdr->src)) &&
2527 		icmp_hdr->code != 0U) {
2528 		goto drop;
2529 	}
2530 
2531 	net_pkt_acknowledge_data(pkt, &ra_access);
2532 
2533 	router_lifetime = ntohs(ra_hdr->router_lifetime);
2534 	reachable_time = ntohl(ra_hdr->reachable_time);
2535 	retrans_timer = ntohl(ra_hdr->retrans_timer);
2536 
2537 	if (ra_hdr->cur_hop_limit) {
2538 		net_if_ipv6_set_hop_limit(net_pkt_iface(pkt),
2539 					  ra_hdr->cur_hop_limit);
2540 		NET_DBG("New hop limit %d",
2541 			net_if_ipv6_get_hop_limit(net_pkt_iface(pkt)));
2542 	}
2543 
2544 	if (reachable_time && reachable_time <= MAX_REACHABLE_TIME &&
2545 	    (net_if_ipv6_get_reachable_time(net_pkt_iface(pkt)) !=
2546 	     reachable_time)) {
2547 		net_if_ipv6_set_base_reachable_time(net_pkt_iface(pkt),
2548 						    reachable_time);
2549 		net_if_ipv6_set_reachable_time(
2550 			net_pkt_iface(pkt)->config.ip.ipv6);
2551 	}
2552 
2553 	if (retrans_timer) {
2554 		net_if_ipv6_set_retrans_timer(net_pkt_iface(pkt),
2555 					      ra_hdr->retrans_timer);
2556 	}
2557 
2558 	net_pkt_set_ipv6_ext_opt_len(pkt, sizeof(struct net_icmpv6_ra_hdr));
2559 	length -= (sizeof(struct net_ipv6_hdr) + sizeof(struct net_icmp_hdr));
2560 
2561 	nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
2562 				net_pkt_get_data(pkt, &nd_access);
2563 
2564 	/* Add neighbor cache entry using link local address, regardless of link layer address
2565 	 * presence in Router Advertisement.
2566 	 */
2567 	nbr = net_ipv6_nbr_add(net_pkt_iface(pkt), (struct in6_addr *)NET_IPV6_HDR(pkt)->src, NULL,
2568 				true, NET_IPV6_NBR_STATE_INCOMPLETE);
2569 
2570 	while (nd_opt_hdr) {
2571 		net_pkt_acknowledge_data(pkt, &nd_access);
2572 
2573 		switch (nd_opt_hdr->type) {
2574 		case NET_ICMPV6_ND_OPT_SLLAO:
2575 			/* Update existing neighbor cache entry with link layer address. */
2576 			nbr = handle_ra_neighbor(pkt, nd_opt_hdr->len);
2577 			if (!nbr) {
2578 				goto drop;
2579 			}
2580 
2581 			break;
2582 		case NET_ICMPV6_ND_OPT_MTU:
2583 			/* MTU has reserved 2 bytes, so skip it. */
2584 			if (net_pkt_skip(pkt, 2) ||
2585 			    net_pkt_read_be32(pkt, &mtu)) {
2586 				goto drop;
2587 			}
2588 
2589 			if (mtu < MIN_IPV6_MTU || mtu > MAX_IPV6_MTU) {
2590 				NET_ERR("DROP: Unsupported MTU %u, min is %u, "
2591 					"max is %u",
2592 					mtu, MIN_IPV6_MTU, MAX_IPV6_MTU);
2593 				goto drop;
2594 			}
2595 
2596 			net_if_set_mtu(net_pkt_iface(pkt), mtu);
2597 
2598 			break;
2599 		case NET_ICMPV6_ND_OPT_PREFIX_INFO:
2600 			if (nd_opt_hdr->len != 4) {
2601 				NET_ERR("DROP: Invalid %s length (%d)",
2602 					"prefix opt", nd_opt_hdr->len);
2603 				goto drop;
2604 			}
2605 
2606 			if (!handle_ra_prefix(pkt)) {
2607 				goto drop;
2608 			}
2609 
2610 			break;
2611 #if defined(CONFIG_NET_6LO_CONTEXT)
2612 		case NET_ICMPV6_ND_OPT_6CO:
2613 			/* RFC 6775, 4.2 (Length)*/
2614 			if (!(nd_opt_hdr->len == 2U || nd_opt_hdr->len == 3U)) {
2615 				NET_ERR("DROP: Invalid %s length %d",
2616 					"6CO", nd_opt_hdr->len);
2617 				goto drop;
2618 			}
2619 
2620 			if (!handle_ra_6co(pkt, nd_opt_hdr->len)) {
2621 				goto drop;
2622 			}
2623 
2624 			break;
2625 #endif
2626 		case NET_ICMPV6_ND_OPT_ROUTE:
2627 			if (!IS_ENABLED(CONFIG_NET_ROUTE)) {
2628 				NET_DBG("Route option skipped");
2629 				goto skip;
2630 			}
2631 
2632 			/* RFC 4191, ch. 2.3 */
2633 			if (nd_opt_hdr->len == 0U || nd_opt_hdr->len > 3U) {
2634 				NET_ERR("DROP: Invalid %s length (%d)",
2635 					"route info opt", nd_opt_hdr->len);
2636 				goto drop;
2637 			}
2638 
2639 			if (!handle_ra_route_info(pkt, nd_opt_hdr->len)) {
2640 				goto drop;
2641 			}
2642 
2643 			break;
2644 #if defined(CONFIG_NET_IPV6_RA_RDNSS)
2645 		case NET_ICMPV6_ND_OPT_RDNSS:
2646 			if (!handle_ra_rdnss(pkt, nd_opt_hdr->len)) {
2647 				goto drop;
2648 			}
2649 			break;
2650 #endif
2651 
2652 		case NET_ICMPV6_ND_OPT_DNSSL:
2653 			NET_DBG("DNSSL option skipped");
2654 			goto skip;
2655 
2656 		default:
2657 			NET_DBG("Unknown ND option 0x%x", nd_opt_hdr->type);
2658 		skip:
2659 			if (net_pkt_skip(pkt, nd_opt_hdr->len * 8U - 2)) {
2660 				goto drop;
2661 			}
2662 
2663 			break;
2664 		}
2665 
2666 		nd_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
2667 					net_pkt_get_data(pkt, &nd_access);
2668 	}
2669 
2670 	router = net_if_ipv6_router_lookup(net_pkt_iface(pkt),
2671 					   (struct in6_addr *)ip_hdr->src);
2672 	if (router) {
2673 		if (!router_lifetime) {
2674 			/* TODO: Start rs_timer on iface if no routers
2675 			 * at all available on iface.
2676 			 */
2677 			net_if_ipv6_router_rm(router);
2678 		} else {
2679 			if (nbr) {
2680 				net_ipv6_nbr_data(nbr)->is_router = true;
2681 			}
2682 
2683 			net_if_ipv6_router_update_lifetime(
2684 					router, router_lifetime);
2685 		}
2686 	} else {
2687 		net_if_ipv6_router_add(net_pkt_iface(pkt),
2688 				       (struct in6_addr *)ip_hdr->src,
2689 				       router_lifetime);
2690 	}
2691 
2692 	net_ipv6_nbr_lock();
2693 	if (nbr && net_ipv6_nbr_data(nbr)->pending) {
2694 		NET_DBG("Sending pending pkt %p to %s",
2695 			net_ipv6_nbr_data(nbr)->pending,
2696 			net_sprint_ipv6_addr(&NET_IPV6_HDR(net_ipv6_nbr_data(nbr)->pending)->dst));
2697 
2698 		if (net_send_data(net_ipv6_nbr_data(nbr)->pending) < 0) {
2699 			net_pkt_unref(net_ipv6_nbr_data(nbr)->pending);
2700 		}
2701 
2702 		nbr_clear_ns_pending(net_ipv6_nbr_data(nbr));
2703 	}
2704 	net_ipv6_nbr_unlock();
2705 
2706 	/* Cancel the RS timer on iface */
2707 	net_if_stop_rs(net_pkt_iface(pkt));
2708 
2709 	return 0;
2710 
2711 drop:
2712 	net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt));
2713 
2714 	return -EIO;
2715 }
2716 #endif /* CONFIG_NET_IPV6_ND */
2717 
2718 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
2719 static struct net_icmp_ctx ns_ctx;
2720 static struct net_icmp_ctx na_ctx;
2721 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
2722 
2723 #if defined(CONFIG_NET_IPV6_ND)
2724 static struct net_icmp_ctx ra_ctx;
2725 #endif /* CONFIG_NET_IPV6_ND */
2726 
net_ipv6_nbr_init(void)2727 void net_ipv6_nbr_init(void)
2728 {
2729 	int ret;
2730 
2731 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
2732 	ret = net_icmp_init_ctx(&ns_ctx, NET_ICMPV6_NS, 0, handle_ns_input);
2733 	if (ret < 0) {
2734 		NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_NS),
2735 			ret);
2736 	}
2737 
2738 	ret = net_icmp_init_ctx(&na_ctx, NET_ICMPV6_NA, 0, handle_na_input);
2739 	if (ret < 0) {
2740 		NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_NA),
2741 			ret);
2742 	}
2743 
2744 	k_work_init_delayable(&ipv6_ns_reply_timer, ipv6_ns_reply_timeout);
2745 #endif
2746 #if defined(CONFIG_NET_IPV6_ND)
2747 	ret = net_icmp_init_ctx(&ra_ctx, NET_ICMPV6_RA, 0, handle_ra_input);
2748 	if (ret < 0) {
2749 		NET_ERR("Cannot register %s handler (%d)", STRINGIFY(NET_ICMPV6_RA),
2750 			ret);
2751 	}
2752 
2753 	k_work_init_delayable(&ipv6_nd_reachable_timer,
2754 			      ipv6_nd_reachable_timeout);
2755 #endif
2756 
2757 	ARG_UNUSED(ret);
2758 }
2759