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