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