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