1 /** @file
2 * @brief Network initialization
3 *
4 * Initialize the network IP stack. Create one thread for reading data
5 * from IP stack and passing that data to applications (Rx thread).
6 */
7
8 /*
9 * Copyright (c) 2016 Intel Corporation
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 */
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL);
16
17 #include <zephyr/init.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/tracing/tracing.h>
20 #include <zephyr/toolchain.h>
21 #include <zephyr/linker/sections.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #include <zephyr/net/ipv4_autoconf.h>
26 #include <zephyr/net/net_if.h>
27 #include <zephyr/net/net_mgmt.h>
28 #include <zephyr/net/net_pkt.h>
29 #include <zephyr/net/net_core.h>
30 #include <zephyr/net/dns_resolve.h>
31 #include <zephyr/net/gptp.h>
32 #include <zephyr/net/websocket.h>
33 #include <zephyr/net/ethernet.h>
34 #include <zephyr/net/capture.h>
35
36 #if defined(CONFIG_NET_LLDP)
37 #include <zephyr/net/lldp.h>
38 #endif
39
40 #include "net_private.h"
41 #include "shell/net_shell.h"
42
43 #include "pmtu.h"
44
45 #include "icmpv6.h"
46 #include "ipv6.h"
47
48 #include "icmpv4.h"
49 #include "ipv4.h"
50
51 #include "dhcpv4/dhcpv4_internal.h"
52 #include "dhcpv6/dhcpv6_internal.h"
53
54 #include "route.h"
55
56 #include "packet_socket.h"
57 #include "canbus_socket.h"
58
59 #include "connection.h"
60 #include "udp_internal.h"
61 #include "tcp_internal.h"
62
63 #include "net_stats.h"
64
65 #if defined(CONFIG_NET_NATIVE)
process_data(struct net_pkt * pkt,bool is_loopback)66 static inline enum net_verdict process_data(struct net_pkt *pkt,
67 bool is_loopback)
68 {
69 int ret;
70 bool locally_routed = false;
71
72 net_pkt_set_l2_processed(pkt, false);
73
74 /* Initial call will forward packets to SOCK_RAW packet sockets. */
75 ret = net_packet_socket_input(pkt, ETH_P_ALL);
76 if (ret != NET_CONTINUE) {
77 return ret;
78 }
79
80 /* If the packet is routed back to us when we have reassembled an IPv4 or IPv6 packet,
81 * then do not pass it to L2 as the packet does not have link layer headers in it.
82 */
83 if (net_pkt_is_ip_reassembled(pkt)) {
84 locally_routed = true;
85 }
86
87 /* If there is no data, then drop the packet. */
88 if (!pkt->frags) {
89 NET_DBG("Corrupted packet (frags %p)", pkt->frags);
90 net_stats_update_processing_error(net_pkt_iface(pkt));
91
92 return NET_DROP;
93 }
94
95 if (!is_loopback && !locally_routed) {
96 ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
97 if (ret != NET_CONTINUE) {
98 if (ret == NET_DROP) {
99 NET_DBG("Packet %p discarded by L2", pkt);
100 net_stats_update_processing_error(
101 net_pkt_iface(pkt));
102 }
103
104 return ret;
105 }
106 }
107
108 net_pkt_set_l2_processed(pkt, true);
109
110 /* L2 has modified the buffer starting point, it is easier
111 * to re-initialize the cursor rather than updating it.
112 */
113 net_pkt_cursor_init(pkt);
114
115 if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM)) {
116 /* Consecutive call will forward packets to SOCK_DGRAM packet sockets
117 * (after L2 removed header).
118 */
119 ret = net_packet_socket_input(pkt, ETH_P_ALL);
120 if (ret != NET_CONTINUE) {
121 return ret;
122 }
123 }
124
125 uint8_t family = net_pkt_family(pkt);
126
127 if (IS_ENABLED(CONFIG_NET_IP) && (family == AF_INET || family == AF_INET6 ||
128 family == AF_UNSPEC || family == AF_PACKET)) {
129 /* L2 processed, now we can pass IPPROTO_RAW to packet socket:
130 */
131 ret = net_packet_socket_input(pkt, IPPROTO_RAW);
132 if (ret != NET_CONTINUE) {
133 return ret;
134 }
135
136 /* IP version and header length. */
137 uint8_t vtc_vhl = NET_IPV6_HDR(pkt)->vtc & 0xf0;
138
139 if (IS_ENABLED(CONFIG_NET_IPV6) && vtc_vhl == 0x60) {
140 return net_ipv6_input(pkt, is_loopback);
141 } else if (IS_ENABLED(CONFIG_NET_IPV4) && vtc_vhl == 0x40) {
142 return net_ipv4_input(pkt, is_loopback);
143 }
144
145 NET_DBG("Unknown IP family packet (0x%x)", NET_IPV6_HDR(pkt)->vtc & 0xf0);
146 net_stats_update_ip_errors_protoerr(net_pkt_iface(pkt));
147 net_stats_update_ip_errors_vhlerr(net_pkt_iface(pkt));
148 return NET_DROP;
149 } else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
150 return net_canbus_socket_input(pkt);
151 }
152
153 NET_DBG("Unknown protocol family packet (0x%x)", family);
154 return NET_DROP;
155 }
156
processing_data(struct net_pkt * pkt,bool is_loopback)157 static void processing_data(struct net_pkt *pkt, bool is_loopback)
158 {
159 again:
160 switch (process_data(pkt, is_loopback)) {
161 case NET_CONTINUE:
162 if (IS_ENABLED(CONFIG_NET_L2_VIRTUAL)) {
163 /* If we have a tunneling packet, feed it back
164 * to the stack in this case.
165 */
166 goto again;
167 } else {
168 NET_DBG("Dropping pkt %p", pkt);
169 net_pkt_unref(pkt);
170 }
171 break;
172 case NET_OK:
173 NET_DBG("Consumed pkt %p", pkt);
174 break;
175 case NET_DROP:
176 default:
177 NET_DBG("Dropping pkt %p", pkt);
178 net_pkt_unref(pkt);
179 break;
180 }
181 }
182
183 /* Things to setup after we are able to RX and TX */
net_post_init(void)184 static void net_post_init(void)
185 {
186 #if defined(CONFIG_NET_LLDP)
187 net_lldp_init();
188 #endif
189 #if defined(CONFIG_NET_GPTP)
190 net_gptp_init();
191 #endif
192 }
193
copy_ll_addr(struct net_pkt * pkt)194 static inline void copy_ll_addr(struct net_pkt *pkt)
195 {
196 memcpy(net_pkt_lladdr_src(pkt), net_pkt_lladdr_if(pkt),
197 sizeof(struct net_linkaddr));
198 memcpy(net_pkt_lladdr_dst(pkt), net_pkt_lladdr_if(pkt),
199 sizeof(struct net_linkaddr));
200 }
201
202 /* Check if the IPv{4|6} addresses are proper. As this can be expensive,
203 * make this optional. We still check the IPv4 TTL and IPv6 hop limit
204 * if the corresponding protocol family is enabled.
205 */
check_ip(struct net_pkt * pkt)206 static inline int check_ip(struct net_pkt *pkt)
207 {
208 uint8_t family;
209 int ret;
210
211 if (!IS_ENABLED(CONFIG_NET_IP)) {
212 return 0;
213 }
214
215 family = net_pkt_family(pkt);
216 ret = 0;
217
218 if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
219 /* Drop IPv6 packet if hop limit is 0 */
220 if (NET_IPV6_HDR(pkt)->hop_limit == 0) {
221 NET_DBG("DROP: IPv6 hop limit");
222 ret = -ENOMSG; /* silently drop the pkt, not an error */
223 goto drop;
224 }
225
226 if (!IS_ENABLED(CONFIG_NET_IP_ADDR_CHECK)) {
227 return 0;
228 }
229
230 #if defined(CONFIG_NET_LOOPBACK)
231 /* If loopback driver is enabled, then send packets to it
232 * as the address check is not needed.
233 */
234 if (net_if_l2(net_pkt_iface(pkt)) == &NET_L2_GET_NAME(DUMMY)) {
235 return 0;
236 }
237 #endif
238 if (net_ipv6_addr_cmp((struct in6_addr *)NET_IPV6_HDR(pkt)->dst,
239 net_ipv6_unspecified_address())) {
240 NET_DBG("DROP: IPv6 dst address missing");
241 ret = -EADDRNOTAVAIL;
242 goto drop;
243 }
244
245 /* If the destination address is our own, then route it
246 * back to us (if it is not already forwarded).
247 */
248 if ((net_ipv6_is_addr_loopback(
249 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst) ||
250 net_ipv6_is_my_addr(
251 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) &&
252 !net_pkt_forwarding(pkt)) {
253 struct in6_addr addr;
254
255 /* Swap the addresses so that in receiving side
256 * the packet is accepted.
257 */
258 net_ipv6_addr_copy_raw((uint8_t *)&addr, NET_IPV6_HDR(pkt)->src);
259 net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->src,
260 NET_IPV6_HDR(pkt)->dst);
261 net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr);
262
263 net_pkt_set_ll_proto_type(pkt, ETH_P_IPV6);
264 copy_ll_addr(pkt);
265
266 return 1;
267 }
268
269 /* If the destination address is interface local scope
270 * multicast address, then loop the data back to us.
271 * The FF01:: multicast addresses are only meant to be used
272 * in local host, so this is similar as how ::1 unicast
273 * addresses are handled. See RFC 3513 ch 2.7 for details.
274 */
275 if (net_ipv6_is_addr_mcast_iface(
276 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
277 NET_DBG("IPv6 interface scope mcast dst address");
278 return 1;
279 }
280
281 /* The source check must be done after the destination check
282 * as having src ::1 is perfectly ok if dst is ::1 too.
283 */
284 if (net_ipv6_is_addr_loopback(
285 (struct in6_addr *)NET_IPV6_HDR(pkt)->src)) {
286 NET_DBG("DROP: IPv6 loopback src address");
287 ret = -EADDRNOTAVAIL;
288 goto drop;
289 }
290
291 } else if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
292 /* Drop IPv4 packet if ttl is 0 */
293 if (NET_IPV4_HDR(pkt)->ttl == 0) {
294 NET_DBG("DROP: IPv4 ttl");
295 ret = -ENOMSG; /* silently drop the pkt, not an error */
296 goto drop;
297 }
298
299 if (!IS_ENABLED(CONFIG_NET_IP_ADDR_CHECK)) {
300 return 0;
301 }
302
303 #if defined(CONFIG_NET_LOOPBACK)
304 /* If loopback driver is enabled, then send packets to it
305 * as the address check is not needed.
306 */
307 if (net_if_l2(net_pkt_iface(pkt)) == &NET_L2_GET_NAME(DUMMY)) {
308 return 0;
309 }
310 #endif
311 if (net_ipv4_addr_cmp((struct in_addr *)NET_IPV4_HDR(pkt)->dst,
312 net_ipv4_unspecified_address())) {
313 NET_DBG("DROP: IPv4 dst address missing");
314 ret = -EADDRNOTAVAIL;
315 goto drop;
316 }
317
318 /* If the destination address is our own, then route it
319 * back to us.
320 */
321 if (net_ipv4_is_addr_loopback((struct in_addr *)NET_IPV4_HDR(pkt)->dst) ||
322 (net_ipv4_is_addr_bcast(net_pkt_iface(pkt),
323 (struct in_addr *)NET_IPV4_HDR(pkt)->dst) == false &&
324 net_ipv4_is_my_addr((struct in_addr *)NET_IPV4_HDR(pkt)->dst))) {
325 struct in_addr addr;
326
327 /* Swap the addresses so that in receiving side
328 * the packet is accepted.
329 */
330 net_ipv4_addr_copy_raw((uint8_t *)&addr, NET_IPV4_HDR(pkt)->src);
331 net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->src,
332 NET_IPV4_HDR(pkt)->dst);
333 net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr);
334
335 net_pkt_set_ll_proto_type(pkt, ETH_P_IP);
336 copy_ll_addr(pkt);
337
338 return 1;
339 }
340
341 /* The source check must be done after the destination check
342 * as having src 127.0.0.0/8 is perfectly ok if dst is in
343 * localhost subnet too.
344 */
345 if (net_ipv4_is_addr_loopback((struct in_addr *)NET_IPV4_HDR(pkt)->src)) {
346 NET_DBG("DROP: IPv4 loopback src address");
347 ret = -EADDRNOTAVAIL;
348 goto drop;
349 }
350 }
351
352 return ret;
353
354 drop:
355 if (IS_ENABLED(CONFIG_NET_STATISTICS)) {
356 if (family == AF_INET6) {
357 net_stats_update_ipv6_drop(net_pkt_iface(pkt));
358 } else {
359 net_stats_update_ipv4_drop(net_pkt_iface(pkt));
360 }
361 }
362
363 return ret;
364 }
365
366 /* Called when data needs to be sent to network */
net_send_data(struct net_pkt * pkt)367 int net_send_data(struct net_pkt *pkt)
368 {
369 int status;
370 int ret;
371
372 SYS_PORT_TRACING_FUNC_ENTER(net, send_data, pkt);
373
374 if (!pkt || !pkt->frags) {
375 ret = -ENODATA;
376 goto err;
377 }
378
379 if (!net_pkt_iface(pkt)) {
380 ret = -EINVAL;
381 goto err;
382 }
383
384 net_pkt_trim_buffer(pkt);
385 net_pkt_cursor_init(pkt);
386
387 status = check_ip(pkt);
388 if (status < 0) {
389 /* Special handling for ENOMSG which is returned if packet
390 * TTL is 0 or hop limit is 0. This is not an error as it is
391 * perfectly valid case to set the limit to 0. In this case
392 * we just silently drop the packet by returning 0.
393 */
394 if (status == -ENOMSG) {
395 ret = 0;
396 goto err;
397 }
398
399 return status;
400 } else if (status > 0) {
401 /* Packet is destined back to us so send it directly
402 * to RX processing.
403 */
404 NET_DBG("Loopback pkt %p back to us", pkt);
405 processing_data(pkt, true);
406 ret = 0;
407 goto err;
408 }
409
410 if (net_if_send_data(net_pkt_iface(pkt), pkt) == NET_DROP) {
411 ret = -EIO;
412 goto err;
413 }
414
415 if (IS_ENABLED(CONFIG_NET_STATISTICS)) {
416 switch (net_pkt_family(pkt)) {
417 case AF_INET:
418 net_stats_update_ipv4_sent(net_pkt_iface(pkt));
419 break;
420 case AF_INET6:
421 net_stats_update_ipv6_sent(net_pkt_iface(pkt));
422 break;
423 }
424 }
425
426 ret = 0;
427
428 err:
429 SYS_PORT_TRACING_FUNC_EXIT(net, send_data, pkt, ret);
430
431 return ret;
432 }
433
net_rx(struct net_if * iface,struct net_pkt * pkt)434 static void net_rx(struct net_if *iface, struct net_pkt *pkt)
435 {
436 bool is_loopback = false;
437 size_t pkt_len;
438
439 pkt_len = net_pkt_get_len(pkt);
440
441 NET_DBG("Received pkt %p len %zu", pkt, pkt_len);
442
443 net_stats_update_bytes_recv(iface, pkt_len);
444
445 if (IS_ENABLED(CONFIG_NET_LOOPBACK)) {
446 #ifdef CONFIG_NET_L2_DUMMY
447 if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
448 is_loopback = true;
449 }
450 #endif
451 }
452
453 processing_data(pkt, is_loopback);
454
455 net_print_statistics();
456 net_pkt_print();
457 }
458
net_process_rx_packet(struct net_pkt * pkt)459 void net_process_rx_packet(struct net_pkt *pkt)
460 {
461 net_pkt_set_rx_stats_tick(pkt, k_cycle_get_32());
462
463 net_capture_pkt(net_pkt_iface(pkt), pkt);
464
465 net_rx(net_pkt_iface(pkt), pkt);
466 }
467
net_queue_rx(struct net_if * iface,struct net_pkt * pkt)468 static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt)
469 {
470 uint8_t prio = net_pkt_priority(pkt);
471 uint8_t tc = net_rx_priority2tc(prio);
472
473 #if defined(CONFIG_NET_STATISTICS)
474 net_stats_update_tc_recv_pkt(iface, tc);
475 net_stats_update_tc_recv_bytes(iface, tc, net_pkt_get_len(pkt));
476 net_stats_update_tc_recv_priority(iface, tc, prio);
477 #endif
478
479 #if NET_TC_RX_COUNT > 1
480 NET_DBG("TC %d with prio %d pkt %p", tc, prio, pkt);
481 #endif
482
483 if (NET_TC_RX_COUNT == 0) {
484 net_process_rx_packet(pkt);
485 } else {
486 net_tc_submit_to_rx_queue(tc, pkt);
487 }
488 }
489
490 /* Called by driver when a packet has been received */
net_recv_data(struct net_if * iface,struct net_pkt * pkt)491 int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
492 {
493 int ret;
494
495 SYS_PORT_TRACING_FUNC_ENTER(net, recv_data, iface, pkt);
496
497 if (!pkt || !iface) {
498 ret = -EINVAL;
499 goto err;
500 }
501
502 if (net_pkt_is_empty(pkt)) {
503 ret = -ENODATA;
504 goto err;
505 }
506
507 if (!net_if_flag_is_set(iface, NET_IF_UP)) {
508 ret = -ENETDOWN;
509 goto err;
510 }
511
512 net_pkt_set_overwrite(pkt, true);
513 net_pkt_cursor_init(pkt);
514
515 NET_DBG("prio %d iface %p pkt %p len %zu", net_pkt_priority(pkt),
516 iface, pkt, net_pkt_get_len(pkt));
517
518 if (IS_ENABLED(CONFIG_NET_ROUTING)) {
519 net_pkt_set_orig_iface(pkt, iface);
520 }
521
522 net_pkt_set_iface(pkt, iface);
523
524 if (!net_pkt_filter_recv_ok(pkt)) {
525 /* silently drop the packet */
526 net_pkt_unref(pkt);
527 } else {
528 net_queue_rx(iface, pkt);
529 }
530
531 ret = 0;
532
533 err:
534 SYS_PORT_TRACING_FUNC_EXIT(net, recv_data, iface, pkt, ret);
535
536 return ret;
537 }
538
l3_init(void)539 static inline void l3_init(void)
540 {
541 net_pmtu_init();
542 net_icmpv4_init();
543 net_icmpv6_init();
544 net_ipv4_init();
545 net_ipv6_init();
546
547 net_ipv4_autoconf_init();
548
549 if (IS_ENABLED(CONFIG_NET_UDP) ||
550 IS_ENABLED(CONFIG_NET_TCP) ||
551 IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) ||
552 IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
553 net_conn_init();
554 }
555
556 net_tcp_init();
557
558 net_route_init();
559
560 NET_DBG("Network L3 init done");
561 }
562 #else /* CONFIG_NET_NATIVE */
563 #define l3_init(...)
564 #define net_post_init(...)
net_send_data(struct net_pkt * pkt)565 int net_send_data(struct net_pkt *pkt)
566 {
567 ARG_UNUSED(pkt);
568
569 return -ENOTSUP;
570 }
net_recv_data(struct net_if * iface,struct net_pkt * pkt)571 int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
572 {
573 ARG_UNUSED(iface);
574 ARG_UNUSED(pkt);
575
576 return -ENOTSUP;
577 }
578 #endif /* CONFIG_NET_NATIVE */
579
init_rx_queues(void)580 static void init_rx_queues(void)
581 {
582 /* Starting TX side. The ordering is important here and the TX
583 * can only be started when RX side is ready to receive packets.
584 */
585 net_if_init();
586
587 net_tc_rx_init();
588
589 /* This will take the interface up and start everything. */
590 net_if_post_init();
591
592 /* Things to init after network interface is working */
593 net_post_init();
594 }
595
services_init(void)596 static inline int services_init(void)
597 {
598 int status;
599
600 socket_service_init();
601
602 status = net_dhcpv4_init();
603 if (status) {
604 return status;
605 }
606
607 status = net_dhcpv6_init();
608 if (status != 0) {
609 return status;
610 }
611
612 net_dhcpv4_server_init();
613
614 dns_dispatcher_init();
615 dns_init_resolver();
616 mdns_init_responder();
617
618 websocket_init();
619
620 net_coap_init();
621
622 net_shell_init();
623
624 return status;
625 }
626
net_init(void)627 static int net_init(void)
628 {
629 net_hostname_init();
630
631 NET_DBG("Priority %d", CONFIG_NET_INIT_PRIO);
632
633 net_pkt_init();
634
635 net_context_init();
636
637 l3_init();
638
639 net_mgmt_event_init();
640
641 init_rx_queues();
642
643 return services_init();
644 }
645
646 SYS_INIT(net_init, POST_KERNEL, CONFIG_NET_INIT_PRIO);
647