2016-04-29 14:52:09 +02:00
|
|
|
/** @file
|
|
|
|
* @brief Network initialization
|
|
|
|
*
|
2016-11-09 17:03:15 +01:00
|
|
|
* Initialize the network IP stack. Create one thread for reading data
|
|
|
|
* from IP stack and passing that data to applications (Rx thread).
|
2016-04-29 14:52:09 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation
|
|
|
|
*
|
2017-01-19 02:01:01 +01:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-04-29 14:52:09 +02:00
|
|
|
*/
|
|
|
|
|
2018-11-30 11:54:56 +01:00
|
|
|
#include <logging/log.h>
|
|
|
|
LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL);
|
2016-04-29 14:52:09 +02:00
|
|
|
|
2016-05-09 13:31:12 +02:00
|
|
|
#include <init.h>
|
2016-11-09 17:03:15 +01:00
|
|
|
#include <kernel.h>
|
2016-04-29 14:52:09 +02:00
|
|
|
#include <toolchain.h>
|
2017-06-17 17:30:47 +02:00
|
|
|
#include <linker/sections.h>
|
2016-04-29 14:52:09 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2016-05-03 09:41:25 +02:00
|
|
|
#include <net/net_if.h>
|
2016-09-21 11:11:47 +02:00
|
|
|
#include <net/net_mgmt.h>
|
2017-04-03 17:14:35 +02:00
|
|
|
#include <net/net_pkt.h>
|
2016-05-09 13:12:14 +02:00
|
|
|
#include <net/net_core.h>
|
2017-03-20 15:44:05 +01:00
|
|
|
#include <net/dns_resolve.h>
|
2018-01-24 13:33:35 +01:00
|
|
|
#include <net/gptp.h>
|
2019-07-31 10:29:34 +02:00
|
|
|
#include <net/websocket.h>
|
2021-03-25 13:21:50 +01:00
|
|
|
#include <net/ethernet.h>
|
2021-03-28 15:19:42 +02:00
|
|
|
#include <net/capture.h>
|
2019-02-26 08:56:06 +01:00
|
|
|
|
|
|
|
#if defined(CONFIG_NET_LLDP)
|
2017-04-06 02:17:12 +02:00
|
|
|
#include <net/lldp.h>
|
2019-02-26 08:56:06 +01:00
|
|
|
#endif
|
2016-05-09 13:12:14 +02:00
|
|
|
|
|
|
|
#include "net_private.h"
|
2016-11-03 13:47:08 +01:00
|
|
|
#include "net_shell.h"
|
2016-05-03 09:41:25 +02:00
|
|
|
|
2016-05-19 11:42:01 +02:00
|
|
|
#include "icmpv6.h"
|
2016-06-16 10:04:07 +02:00
|
|
|
#include "ipv6.h"
|
2016-05-19 11:42:01 +02:00
|
|
|
|
2016-05-19 15:19:59 +02:00
|
|
|
#include "icmpv4.h"
|
|
|
|
|
2017-02-22 13:36:31 +01:00
|
|
|
#include "dhcpv4.h"
|
|
|
|
|
2016-09-19 14:09:37 +02:00
|
|
|
#include "route.h"
|
2016-10-26 12:57:30 +02:00
|
|
|
|
2019-01-31 10:59:54 +01:00
|
|
|
#include "packet_socket.h"
|
2019-01-24 13:13:42 +01:00
|
|
|
#include "canbus_socket.h"
|
2019-01-31 10:59:54 +01:00
|
|
|
|
2016-06-14 09:04:27 +02:00
|
|
|
#include "connection.h"
|
2017-06-30 16:46:01 +02:00
|
|
|
#include "udp_internal.h"
|
2018-03-02 23:20:51 +01:00
|
|
|
#include "tcp_internal.h"
|
2018-07-30 17:28:35 +02:00
|
|
|
#include "ipv4_autoconf_internal.h"
|
2016-06-14 09:04:27 +02:00
|
|
|
|
2016-12-13 12:34:01 +01:00
|
|
|
#include "net_stats.h"
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
static inline enum net_verdict process_data(struct net_pkt *pkt,
|
2016-11-12 12:02:27 +01:00
|
|
|
bool is_loopback)
|
2016-05-09 15:09:36 +02:00
|
|
|
{
|
2016-06-01 15:06:27 +02:00
|
|
|
int ret;
|
2017-03-28 16:43:32 +02:00
|
|
|
bool locally_routed = false;
|
|
|
|
|
2021-03-25 13:21:50 +01:00
|
|
|
ret = net_packet_socket_input(pkt, ETH_P_ALL);
|
2019-01-31 10:59:54 +01:00
|
|
|
if (ret != NET_CONTINUE) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-28 16:43:32 +02:00
|
|
|
#if defined(CONFIG_NET_IPV6_FRAGMENT)
|
|
|
|
/* If the packet is routed back to us when we have reassembled
|
|
|
|
* an IPv6 packet, then do not pass it to L2 as the packet does
|
|
|
|
* not have link layer headers in it.
|
|
|
|
*/
|
2017-04-05 08:37:44 +02:00
|
|
|
if (net_pkt_ipv6_fragment_start(pkt)) {
|
2017-03-28 16:43:32 +02:00
|
|
|
locally_routed = true;
|
|
|
|
}
|
|
|
|
#endif
|
2016-06-01 15:06:27 +02:00
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
/* If there is no data, then drop the packet. */
|
|
|
|
if (!pkt->frags) {
|
|
|
|
NET_DBG("Corrupted packet (frags %p)", pkt->frags);
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_processing_error(net_pkt_iface(pkt));
|
2016-07-12 15:33:33 +02:00
|
|
|
|
2016-05-17 12:03:02 +02:00
|
|
|
return NET_DROP;
|
|
|
|
}
|
|
|
|
|
2017-03-28 16:43:32 +02:00
|
|
|
if (!is_loopback && !locally_routed) {
|
2017-04-05 08:37:44 +02:00
|
|
|
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
|
2016-11-12 12:02:27 +01:00
|
|
|
if (ret != NET_CONTINUE) {
|
|
|
|
if (ret == NET_DROP) {
|
2017-04-05 08:37:44 +02:00
|
|
|
NET_DBG("Packet %p discarded by L2", pkt);
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_processing_error(
|
|
|
|
net_pkt_iface(pkt));
|
2016-11-12 12:02:27 +01:00
|
|
|
}
|
2016-06-01 15:06:27 +02:00
|
|
|
|
2016-11-12 12:02:27 +01:00
|
|
|
return ret;
|
|
|
|
}
|
2016-05-24 16:30:03 +02:00
|
|
|
}
|
|
|
|
|
2021-03-25 13:21:50 +01:00
|
|
|
/* L2 processed, now we can pass IPPROTO_RAW to packet socket: */
|
|
|
|
ret = net_packet_socket_input(pkt, IPPROTO_RAW);
|
|
|
|
if (ret != NET_CONTINUE) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-01-24 13:13:42 +01:00
|
|
|
ret = net_canbus_socket_input(pkt);
|
|
|
|
if (ret != NET_CONTINUE) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-12-12 09:49:06 +01:00
|
|
|
/* L2 has modified the buffer starting point, it is easier
|
|
|
|
* to re-initialize the cursor rather than updating it.
|
|
|
|
*/
|
|
|
|
net_pkt_cursor_init(pkt);
|
|
|
|
|
2016-05-17 12:03:02 +02:00
|
|
|
/* IP version and header length. */
|
2017-04-10 13:03:41 +02:00
|
|
|
switch (NET_IPV6_HDR(pkt)->vtc & 0xf0) {
|
2016-05-17 12:03:02 +02:00
|
|
|
#if defined(CONFIG_NET_IPV6)
|
|
|
|
case 0x60:
|
2018-12-18 09:18:12 +01:00
|
|
|
return net_ipv6_input(pkt, is_loopback);
|
2016-05-17 12:17:15 +02:00
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_IPV4)
|
|
|
|
case 0x40:
|
2018-12-11 11:19:58 +01:00
|
|
|
return net_ipv4_input(pkt);
|
2016-05-17 12:03:02 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-09 21:36:56 +01:00
|
|
|
NET_DBG("Unknown IP family packet (0x%x)",
|
2017-04-10 13:03:41 +02:00
|
|
|
NET_IPV6_HDR(pkt)->vtc & 0xf0);
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_ip_errors_protoerr(net_pkt_iface(pkt));
|
|
|
|
net_stats_update_ip_errors_vhlerr(net_pkt_iface(pkt));
|
2016-07-12 15:33:33 +02:00
|
|
|
|
2016-05-09 15:09:36 +02:00
|
|
|
return NET_DROP;
|
|
|
|
}
|
2016-04-29 14:52:09 +02:00
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
static void processing_data(struct net_pkt *pkt, bool is_loopback)
|
2016-11-12 12:02:27 +01:00
|
|
|
{
|
2021-02-22 16:51:25 +01:00
|
|
|
again:
|
2017-04-05 08:37:44 +02:00
|
|
|
switch (process_data(pkt, is_loopback)) {
|
2021-02-22 16:51:25 +01:00
|
|
|
case NET_CONTINUE:
|
|
|
|
if (IS_ENABLED(CONFIG_NET_L2_VIRTUAL)) {
|
|
|
|
/* If we have a tunneling packet, feed it back
|
|
|
|
* to the stack in this case.
|
|
|
|
*/
|
|
|
|
goto again;
|
|
|
|
} else {
|
|
|
|
NET_DBG("Dropping pkt %p", pkt);
|
|
|
|
net_pkt_unref(pkt);
|
|
|
|
}
|
|
|
|
break;
|
2016-11-12 12:02:27 +01:00
|
|
|
case NET_OK:
|
2017-04-05 08:37:44 +02:00
|
|
|
NET_DBG("Consumed pkt %p", pkt);
|
2016-11-12 12:02:27 +01:00
|
|
|
break;
|
|
|
|
case NET_DROP:
|
|
|
|
default:
|
2017-04-05 08:37:44 +02:00
|
|
|
NET_DBG("Dropping pkt %p", pkt);
|
|
|
|
net_pkt_unref(pkt);
|
2016-11-12 12:02:27 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
/* Things to setup after we are able to RX and TX */
|
|
|
|
static void net_post_init(void)
|
2016-04-29 14:52:09 +02:00
|
|
|
{
|
2017-04-06 02:17:12 +02:00
|
|
|
#if defined(CONFIG_NET_LLDP)
|
|
|
|
net_lldp_init();
|
|
|
|
#endif
|
2018-01-24 13:33:35 +01:00
|
|
|
#if defined(CONFIG_NET_GPTP)
|
|
|
|
net_gptp_init();
|
|
|
|
#endif
|
2018-02-07 14:00:08 +01:00
|
|
|
}
|
2016-05-09 15:09:36 +02:00
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
static void init_rx_queues(void)
|
|
|
|
{
|
2016-06-01 09:35:00 +02:00
|
|
|
/* Starting TX side. The ordering is important here and the TX
|
|
|
|
* can only be started when RX side is ready to receive packets.
|
|
|
|
*/
|
2018-02-07 14:00:08 +01:00
|
|
|
net_if_init();
|
2017-03-13 14:50:57 +01:00
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
net_tc_rx_init();
|
2017-03-13 14:50:57 +01:00
|
|
|
|
|
|
|
/* This will take the interface up and start everything. */
|
|
|
|
net_if_post_init();
|
2016-06-01 09:35:00 +02:00
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
/* Things to init after network interface is working */
|
|
|
|
net_post_init();
|
2016-04-29 14:52:09 +02:00
|
|
|
}
|
|
|
|
|
2017-11-14 16:01:21 +01:00
|
|
|
/* If loopback driver is enabled, then direct packets to it so the address
|
|
|
|
* check is not needed.
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_NET_IP_ADDR_CHECK) && !defined(CONFIG_NET_LOOPBACK)
|
2016-11-12 12:02:27 +01:00
|
|
|
/* Check if the IPv{4|6} addresses are proper. As this can be expensive,
|
|
|
|
* make this optional.
|
|
|
|
*/
|
2017-04-05 08:37:44 +02:00
|
|
|
static inline int check_ip_addr(struct net_pkt *pkt)
|
2016-11-12 12:02:27 +01:00
|
|
|
{
|
|
|
|
#if defined(CONFIG_NET_IPV6)
|
2017-04-05 08:37:44 +02:00
|
|
|
if (net_pkt_family(pkt) == AF_INET6) {
|
2021-10-05 12:23:57 +02:00
|
|
|
if (net_ipv6_addr_cmp((struct in6_addr *)NET_IPV6_HDR(pkt)->dst,
|
2016-11-12 12:02:27 +01:00
|
|
|
net_ipv6_unspecified_address())) {
|
|
|
|
NET_DBG("IPv6 dst address missing");
|
|
|
|
return -EADDRNOTAVAIL;
|
|
|
|
}
|
|
|
|
|
2017-03-27 15:50:10 +02:00
|
|
|
/* If the destination address is our own, then route it
|
|
|
|
* back to us.
|
|
|
|
*/
|
2021-10-05 12:23:57 +02:00
|
|
|
if (net_ipv6_is_addr_loopback(
|
|
|
|
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst) ||
|
|
|
|
net_ipv6_is_my_addr(
|
|
|
|
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
|
2016-11-12 12:02:27 +01:00
|
|
|
struct in6_addr addr;
|
|
|
|
|
|
|
|
/* Swap the addresses so that in receiving side
|
|
|
|
* the packet is accepted.
|
|
|
|
*/
|
2021-10-05 12:23:57 +02:00
|
|
|
net_ipv6_addr_copy_raw((uint8_t *)&addr, NET_IPV6_HDR(pkt)->src);
|
|
|
|
net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->src,
|
|
|
|
NET_IPV6_HDR(pkt)->dst);
|
|
|
|
net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr);
|
2016-11-12 12:02:27 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-11-02 10:38:15 +01:00
|
|
|
/* If the destination address is interface local scope
|
|
|
|
* multicast address, then loop the data back to us.
|
|
|
|
* The FF01:: multicast addresses are only meant to be used
|
|
|
|
* in local host, so this is similar as how ::1 unicast
|
|
|
|
* addresses are handled. See RFC 3513 ch 2.7 for details.
|
|
|
|
*/
|
2021-10-05 12:23:57 +02:00
|
|
|
if (net_ipv6_is_addr_mcast_iface(
|
|
|
|
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
|
2018-11-02 10:38:15 +01:00
|
|
|
NET_DBG("IPv6 interface scope mcast dst address");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-11-12 12:02:27 +01:00
|
|
|
/* The source check must be done after the destination check
|
|
|
|
* as having src ::1 is perfectly ok if dst is ::1 too.
|
|
|
|
*/
|
2021-10-05 12:23:57 +02:00
|
|
|
if (net_ipv6_is_addr_loopback(
|
|
|
|
(struct in6_addr *)NET_IPV6_HDR(pkt)->src)) {
|
2016-11-12 12:02:27 +01:00
|
|
|
NET_DBG("IPv6 loopback src address");
|
|
|
|
return -EADDRNOTAVAIL;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
#endif /* CONFIG_NET_IPV6 */
|
|
|
|
|
|
|
|
#if defined(CONFIG_NET_IPV4)
|
2017-04-05 08:37:44 +02:00
|
|
|
if (net_pkt_family(pkt) == AF_INET) {
|
2021-10-04 14:40:22 +02:00
|
|
|
if (net_ipv4_addr_cmp((struct in_addr *)NET_IPV4_HDR(pkt)->dst,
|
2016-11-12 12:02:27 +01:00
|
|
|
net_ipv4_unspecified_address())) {
|
2017-09-07 21:49:42 +02:00
|
|
|
NET_DBG("IPv4 dst address missing");
|
2016-11-12 12:02:27 +01:00
|
|
|
return -EADDRNOTAVAIL;
|
|
|
|
}
|
|
|
|
|
2017-03-27 15:50:10 +02:00
|
|
|
/* If the destination address is our own, then route it
|
|
|
|
* back to us.
|
|
|
|
*/
|
2021-10-04 14:40:22 +02:00
|
|
|
if (net_ipv4_is_addr_loopback((struct in_addr *)NET_IPV4_HDR(pkt)->dst) ||
|
2018-11-02 15:05:58 +01:00
|
|
|
(net_ipv4_is_addr_bcast(net_pkt_iface(pkt),
|
2021-10-04 14:40:22 +02:00
|
|
|
(struct in_addr *)NET_IPV4_HDR(pkt)->dst) == false &&
|
|
|
|
net_ipv4_is_my_addr((struct in_addr *)NET_IPV4_HDR(pkt)->dst))) {
|
2016-11-12 12:02:27 +01:00
|
|
|
struct in_addr addr;
|
|
|
|
|
|
|
|
/* Swap the addresses so that in receiving side
|
|
|
|
* the packet is accepted.
|
|
|
|
*/
|
2021-10-04 14:40:22 +02:00
|
|
|
net_ipv4_addr_copy_raw((uint8_t *)&addr, NET_IPV4_HDR(pkt)->src);
|
|
|
|
net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->src,
|
|
|
|
NET_IPV4_HDR(pkt)->dst);
|
|
|
|
net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr);
|
2016-11-12 12:02:27 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The source check must be done after the destination check
|
|
|
|
* as having src 127.0.0.0/8 is perfectly ok if dst is in
|
|
|
|
* localhost subnet too.
|
|
|
|
*/
|
2021-10-04 14:40:22 +02:00
|
|
|
if (net_ipv4_is_addr_loopback((struct in_addr *)NET_IPV4_HDR(pkt)->src)) {
|
2016-11-12 12:02:27 +01:00
|
|
|
NET_DBG("IPv4 loopback src address");
|
|
|
|
return -EADDRNOTAVAIL;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
#endif /* CONFIG_NET_IPV4 */
|
|
|
|
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#else
|
2017-04-05 08:37:44 +02:00
|
|
|
#define check_ip_addr(pkt) 0
|
2016-11-12 12:02:27 +01:00
|
|
|
#endif
|
|
|
|
|
2016-05-19 11:12:33 +02:00
|
|
|
/* Called when data needs to be sent to network */
|
2017-04-05 08:37:44 +02:00
|
|
|
int net_send_data(struct net_pkt *pkt)
|
2016-05-19 11:12:33 +02:00
|
|
|
{
|
2016-11-12 12:02:27 +01:00
|
|
|
int status;
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (!pkt || !pkt->frags) {
|
2016-05-19 11:12:33 +02:00
|
|
|
return -ENODATA;
|
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (!net_pkt_iface(pkt)) {
|
2016-05-19 11:12:33 +02:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(CONFIG_NET_STATISTICS)
|
2017-04-05 08:37:44 +02:00
|
|
|
switch (net_pkt_family(pkt)) {
|
2016-05-19 11:12:33 +02:00
|
|
|
case AF_INET:
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_ipv4_sent(net_pkt_iface(pkt));
|
2016-05-19 11:12:33 +02:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_ipv6_sent(net_pkt_iface(pkt));
|
2016-05-19 11:12:33 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-02-11 17:03:17 +01:00
|
|
|
net_pkt_trim_buffer(pkt);
|
2018-12-12 09:49:06 +01:00
|
|
|
net_pkt_cursor_init(pkt);
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
status = check_ip_addr(pkt);
|
2016-11-12 12:02:27 +01:00
|
|
|
if (status < 0) {
|
|
|
|
return status;
|
|
|
|
} else if (status > 0) {
|
|
|
|
/* Packet is destined back to us so send it directly
|
|
|
|
* to RX processing.
|
|
|
|
*/
|
2017-04-19 13:11:52 +02:00
|
|
|
NET_DBG("Loopback pkt %p back to us", pkt);
|
2017-04-05 08:37:44 +02:00
|
|
|
processing_data(pkt, true);
|
2016-11-12 12:02:27 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (net_if_send_data(net_pkt_iface(pkt), pkt) == NET_DROP) {
|
2016-06-03 11:56:49 +02:00
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2016-05-19 11:12:33 +02:00
|
|
|
}
|
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
static void net_rx(struct net_if *iface, struct net_pkt *pkt)
|
|
|
|
{
|
2019-04-05 13:08:39 +02:00
|
|
|
bool is_loopback = false;
|
2018-02-07 14:09:36 +01:00
|
|
|
size_t pkt_len;
|
2018-07-06 10:35:07 +02:00
|
|
|
|
2018-02-07 14:09:36 +01:00
|
|
|
pkt_len = net_pkt_get_len(pkt);
|
2018-02-07 14:00:08 +01:00
|
|
|
|
|
|
|
NET_DBG("Received pkt %p len %zu", pkt, pkt_len);
|
|
|
|
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_bytes_recv(iface, pkt_len);
|
2018-02-07 14:00:08 +01:00
|
|
|
|
2019-04-05 13:08:39 +02:00
|
|
|
if (IS_ENABLED(CONFIG_NET_LOOPBACK)) {
|
|
|
|
#ifdef CONFIG_NET_L2_DUMMY
|
|
|
|
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
|
|
|
|
is_loopback = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
processing_data(pkt, is_loopback);
|
2018-02-07 14:00:08 +01:00
|
|
|
|
|
|
|
net_print_statistics();
|
|
|
|
net_pkt_print();
|
|
|
|
}
|
|
|
|
|
2021-04-29 14:58:54 +02:00
|
|
|
void net_process_rx_packet(struct net_pkt *pkt)
|
2018-02-07 14:00:08 +01:00
|
|
|
{
|
2020-05-13 10:20:30 +02:00
|
|
|
net_pkt_set_rx_stats_tick(pkt, k_cycle_get_32());
|
|
|
|
|
2021-03-28 15:19:42 +02:00
|
|
|
net_capture_pkt(net_pkt_iface(pkt), pkt);
|
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
net_rx(net_pkt_iface(pkt), pkt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt)
|
|
|
|
{
|
2020-05-27 18:26:57 +02:00
|
|
|
uint8_t prio = net_pkt_priority(pkt);
|
|
|
|
uint8_t tc = net_rx_priority2tc(prio);
|
2018-02-07 14:00:08 +01:00
|
|
|
|
2018-02-07 14:09:36 +01:00
|
|
|
#if defined(CONFIG_NET_STATISTICS)
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_tc_recv_pkt(iface, tc);
|
2019-02-21 10:30:13 +01:00
|
|
|
net_stats_update_tc_recv_bytes(iface, tc, net_pkt_get_len(pkt));
|
2018-03-27 10:31:31 +02:00
|
|
|
net_stats_update_tc_recv_priority(iface, tc, prio);
|
2018-02-07 14:09:36 +01:00
|
|
|
#endif
|
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
#if NET_TC_RX_COUNT > 1
|
|
|
|
NET_DBG("TC %d with prio %d pkt %p", tc, prio, pkt);
|
|
|
|
#endif
|
|
|
|
|
2020-12-01 09:23:20 +01:00
|
|
|
if (NET_TC_RX_COUNT == 0) {
|
2021-04-29 14:58:54 +02:00
|
|
|
net_process_rx_packet(pkt);
|
2020-12-01 09:23:20 +01:00
|
|
|
} else {
|
|
|
|
net_tc_submit_to_rx_queue(tc, pkt);
|
|
|
|
}
|
2018-02-07 14:00:08 +01:00
|
|
|
}
|
|
|
|
|
2016-05-03 09:41:25 +02:00
|
|
|
/* Called by driver when an IP packet has been received */
|
2017-04-05 08:37:44 +02:00
|
|
|
int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
|
2016-05-03 09:41:25 +02:00
|
|
|
{
|
2018-03-21 15:39:38 +01:00
|
|
|
if (!pkt || !iface) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2017-03-13 16:23:47 +01:00
|
|
|
|
2020-09-21 13:58:41 +02:00
|
|
|
if (net_pkt_is_empty(pkt)) {
|
2016-05-03 09:41:25 +02:00
|
|
|
return -ENODATA;
|
|
|
|
}
|
|
|
|
|
2019-04-16 09:55:34 +02:00
|
|
|
if (!net_if_flag_is_set(iface, NET_IF_UP)) {
|
2017-03-13 14:57:12 +01:00
|
|
|
return -ENETDOWN;
|
|
|
|
}
|
|
|
|
|
2018-12-05 13:58:58 +01:00
|
|
|
net_pkt_set_overwrite(pkt, true);
|
2018-12-12 09:49:06 +01:00
|
|
|
net_pkt_cursor_init(pkt);
|
2018-12-05 13:58:58 +01:00
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
NET_DBG("prio %d iface %p pkt %p len %zu", net_pkt_priority(pkt),
|
|
|
|
iface, pkt, net_pkt_get_len(pkt));
|
2016-05-09 15:09:36 +02:00
|
|
|
|
2017-08-16 16:13:47 +02:00
|
|
|
if (IS_ENABLED(CONFIG_NET_ROUTING)) {
|
|
|
|
net_pkt_set_orig_iface(pkt, iface);
|
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
net_pkt_set_iface(pkt, iface);
|
2016-05-09 15:09:36 +02:00
|
|
|
|
2021-08-02 21:43:32 +02:00
|
|
|
if (!net_pkt_filter_recv_ok(pkt)) {
|
|
|
|
/* silently drop the packet */
|
|
|
|
net_pkt_unref(pkt);
|
|
|
|
} else {
|
|
|
|
net_queue_rx(iface, pkt);
|
|
|
|
}
|
2016-05-03 09:41:25 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-03 12:01:42 +02:00
|
|
|
static inline void l3_init(void)
|
2016-04-29 14:52:09 +02:00
|
|
|
{
|
2017-03-24 09:14:10 +01:00
|
|
|
net_icmpv4_init();
|
2016-05-19 11:42:01 +02:00
|
|
|
net_icmpv6_init();
|
2016-06-07 15:34:49 +02:00
|
|
|
net_ipv6_init();
|
2016-06-03 12:01:42 +02:00
|
|
|
|
2018-07-30 17:28:35 +02:00
|
|
|
net_ipv4_autoconf_init();
|
|
|
|
|
2019-05-17 13:19:07 +02:00
|
|
|
if (IS_ENABLED(CONFIG_NET_UDP) ||
|
|
|
|
IS_ENABLED(CONFIG_NET_TCP) ||
|
|
|
|
IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) ||
|
|
|
|
IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
|
|
|
|
net_conn_init();
|
|
|
|
}
|
|
|
|
|
2016-08-18 09:08:04 +02:00
|
|
|
net_tcp_init();
|
2016-06-14 09:04:27 +02:00
|
|
|
|
2016-09-19 14:09:37 +02:00
|
|
|
net_route_init();
|
|
|
|
|
2019-04-03 09:04:47 +02:00
|
|
|
NET_DBG("Network L3 init done");
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int services_init(void)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
|
|
|
|
status = net_dhcpv4_init();
|
|
|
|
if (status) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2017-03-20 15:44:05 +01:00
|
|
|
dns_init_resolver();
|
2019-07-31 10:29:34 +02:00
|
|
|
websocket_init();
|
2017-03-20 15:44:05 +01:00
|
|
|
|
2019-09-17 13:42:46 +02:00
|
|
|
net_coap_init();
|
|
|
|
|
2019-04-03 09:04:47 +02:00
|
|
|
net_shell_init();
|
|
|
|
|
|
|
|
return status;
|
2016-06-03 12:01:42 +02:00
|
|
|
}
|
|
|
|
|
2020-04-30 20:33:38 +02:00
|
|
|
static int net_init(const struct device *unused)
|
2016-04-29 14:52:09 +02:00
|
|
|
{
|
2017-09-21 22:30:32 +02:00
|
|
|
net_hostname_init();
|
|
|
|
|
2016-05-09 13:31:12 +02:00
|
|
|
NET_DBG("Priority %d", CONFIG_NET_INIT_PRIO);
|
2016-04-29 14:52:09 +02:00
|
|
|
|
2017-04-03 17:14:35 +02:00
|
|
|
net_pkt_init();
|
2016-05-09 13:12:14 +02:00
|
|
|
|
2016-06-01 09:35:00 +02:00
|
|
|
net_context_init();
|
2016-04-29 14:52:09 +02:00
|
|
|
|
2016-06-03 12:01:42 +02:00
|
|
|
l3_init();
|
2016-05-09 14:47:01 +02:00
|
|
|
|
2016-09-28 17:03:54 +02:00
|
|
|
net_mgmt_event_init();
|
2016-09-21 11:11:47 +02:00
|
|
|
|
2018-02-07 14:00:08 +01:00
|
|
|
init_rx_queues();
|
2016-05-09 14:49:48 +02:00
|
|
|
|
2019-04-03 09:04:47 +02:00
|
|
|
return services_init();
|
2016-04-29 14:52:09 +02:00
|
|
|
}
|
2016-05-09 13:31:12 +02:00
|
|
|
|
2016-11-09 19:47:30 +01:00
|
|
|
SYS_INIT(net_init, POST_KERNEL, CONFIG_NET_INIT_PRIO);
|