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