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