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