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