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