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