Skip to content

net_core: Decide about l2-processing based on l2_processed-flag #93050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/zephyr/net/net_pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ struct net_pkt {
uint8_t chksum_done : 1; /* Checksum has already been computed for
* the packet.
*/
uint8_t loopback : 1; /* Packet is a loop back packet. */
#if defined(CONFIG_NET_IP_FRAGMENT)
uint8_t ip_reassembled : 1; /* Packet is a reassembled IP packet. */
#endif
Expand Down Expand Up @@ -1020,6 +1021,17 @@ static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt,
}
#endif /* CONFIG_NET_IPV6_FRAGMENT */

static inline bool net_pkt_is_loopback(struct net_pkt *pkt)
{
return !!(pkt->loopback);
}

static inline void net_pkt_set_loopback(struct net_pkt *pkt,
bool loopback)
{
pkt->loopback = loopback;
}

#if defined(CONFIG_NET_IP_FRAGMENT)
static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt)
{
Expand Down
4 changes: 2 additions & 2 deletions subsys/net/ip/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ int net_ipv4_parse_hdr_options(struct net_pkt *pkt,
}
#endif

enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback)
enum net_verdict net_ipv4_input(struct net_pkt *pkt)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv4_access, struct net_ipv4_hdr);
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
Expand Down Expand Up @@ -301,7 +301,7 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback)
net_pkt_update_length(pkt, pkt_len);
}

if (!is_loopback) {
if (!net_pkt_is_loopback(pkt)) {
if (net_ipv4_is_addr_loopback_raw(hdr->dst) ||
net_ipv4_is_addr_loopback_raw(hdr->src)) {
NET_DBG("DROP: localhost packet");
Expand Down
5 changes: 5 additions & 0 deletions subsys/net/ip/ipv4_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ static void reassemble_packet(struct net_ipv4_reassembly *reass)
net_pkt_set_data(pkt, &ipv4_access);
net_pkt_set_ip_reassembled(pkt, true);

/* If the packet is reassembled, then do not pass it to L2 as the
* packet does not have link layer headers in it.
*/
net_pkt_set_l2_processed(pkt, true);

LOG_DBG("New pkt %p IPv4 len is %zd bytes", pkt, net_pkt_get_len(pkt));

/* We need to use the queue when feeding the packet back into the
Expand Down
6 changes: 3 additions & 3 deletions subsys/net/ip/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ static inline bool is_src_non_tentative_itself(const uint8_t *src)
return false;
}

enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
enum net_verdict net_ipv6_input(struct net_pkt *pkt)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
Expand Down Expand Up @@ -537,7 +537,7 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
goto drop;
}

if (!is_loopback) {
if (!net_pkt_is_loopback(pkt)) {
if (net_ipv6_is_addr_loopback_raw(hdr->dst) ||
net_ipv6_is_addr_loopback_raw(hdr->src)) {
NET_DBG("DROP: ::1 packet");
Expand Down Expand Up @@ -631,7 +631,7 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
}

if ((IS_ENABLED(CONFIG_NET_ROUTING) || IS_ENABLED(CONFIG_NET_ROUTE_MCAST)) &&
!is_loopback && is_src_non_tentative_itself(hdr->src)) {
!net_pkt_is_loopback(pkt) && is_src_non_tentative_itself(hdr->src)) {
NET_DBG("DROP: src addr is %s", "mine");
goto drop;
}
Expand Down
5 changes: 5 additions & 0 deletions subsys/net/ip/ipv6_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ static void reassemble_packet(struct net_ipv6_reassembly *reass)
net_pkt_set_data(pkt, &ipv6_access);
net_pkt_set_ip_reassembled(pkt, true);

/* If the packet is reassembled, then do not pass it to L2 as the
* packet does not have link layer headers in it.
*/
net_pkt_set_l2_processed(pkt, true);

NET_DBG("New pkt %p IPv6 len is %d bytes", pkt,
len + NET_IPV6H_LEN);

Expand Down
36 changes: 13 additions & 23 deletions subsys/net/ip/net_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,16 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL);
#include "net_stats.h"

#if defined(CONFIG_NET_NATIVE)
static inline enum net_verdict process_data(struct net_pkt *pkt,
bool is_loopback)
static inline enum net_verdict process_data(struct net_pkt *pkt)
{
int ret;
bool locally_routed = false;

net_pkt_set_l2_processed(pkt, false);

/* Initial call will forward packets to SOCK_RAW packet sockets. */
ret = net_packet_socket_input(pkt, ETH_P_ALL);
if (ret != NET_CONTINUE) {
return ret;
}

/* If the packet is routed back to us when we have reassembled an IPv4 or IPv6 packet,
* then do not pass it to L2 as the packet does not have link layer headers in it.
*/
if (net_pkt_is_ip_reassembled(pkt)) {
locally_routed = true;
}

/* If there is no data, then drop the packet. */
if (!pkt->frags) {
NET_DBG("Corrupted packet (frags %p)", pkt->frags);
Expand All @@ -93,8 +82,9 @@ static inline enum net_verdict process_data(struct net_pkt *pkt,
return NET_DROP;
}

if (!is_loopback && !locally_routed) {
if (!net_pkt_is_l2_processed(pkt)) {
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
net_pkt_set_l2_processed(pkt, true);
if (ret != NET_CONTINUE) {
if (ret == NET_DROP) {
NET_DBG("Packet %p discarded by L2", pkt);
Expand All @@ -106,8 +96,6 @@ static inline enum net_verdict process_data(struct net_pkt *pkt,
}
}

net_pkt_set_l2_processed(pkt, true);

/* L2 has modified the buffer starting point, it is easier
* to re-initialize the cursor rather than updating it.
*/
Expand All @@ -131,9 +119,9 @@ static inline enum net_verdict process_data(struct net_pkt *pkt,
uint8_t vtc_vhl = NET_IPV6_HDR(pkt)->vtc & 0xf0;

if (IS_ENABLED(CONFIG_NET_IPV6) && vtc_vhl == 0x60) {
return net_ipv6_input(pkt, is_loopback);
return net_ipv6_input(pkt);
} else if (IS_ENABLED(CONFIG_NET_IPV4) && vtc_vhl == 0x40) {
return net_ipv4_input(pkt, is_loopback);
return net_ipv4_input(pkt);
}

NET_DBG("Unknown IP family packet (0x%x)", NET_IPV6_HDR(pkt)->vtc & 0xf0);
Expand All @@ -148,10 +136,10 @@ static inline enum net_verdict process_data(struct net_pkt *pkt,
return NET_DROP;
}

static void processing_data(struct net_pkt *pkt, bool is_loopback)
static void processing_data(struct net_pkt *pkt)
{
again:
switch (process_data(pkt, is_loopback)) {
switch (process_data(pkt)) {
case NET_CONTINUE:
if (IS_ENABLED(CONFIG_NET_L2_VIRTUAL)) {
/* If we have a tunneling packet, feed it back
Expand Down Expand Up @@ -421,7 +409,9 @@ int net_try_send_data(struct net_pkt *pkt, k_timeout_t timeout)
* to RX processing.
*/
NET_DBG("Loopback pkt %p back to us", pkt);
processing_data(pkt, true);
net_pkt_set_loopback(pkt, true);
net_pkt_set_l2_processed(pkt, true);
processing_data(pkt);
ret = 0;
goto err;
}
Expand Down Expand Up @@ -481,7 +471,6 @@ int net_try_send_data(struct net_pkt *pkt, k_timeout_t timeout)

static void net_rx(struct net_if *iface, struct net_pkt *pkt)
{
bool is_loopback = false;
size_t pkt_len;

pkt_len = net_pkt_get_len(pkt);
Expand All @@ -493,12 +482,13 @@ static void net_rx(struct net_if *iface, struct net_pkt *pkt)
if (IS_ENABLED(CONFIG_NET_LOOPBACK)) {
#ifdef CONFIG_NET_L2_DUMMY
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
is_loopback = true;
net_pkt_set_loopback(pkt, true);
net_pkt_set_l2_processed(pkt, true);
}
#endif
}

processing_data(pkt, is_loopback);
processing_data(pkt);

net_print_statistics();
net_pkt_print();
Expand Down
1 change: 1 addition & 0 deletions subsys/net/ip/net_pkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,7 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt)
net_pkt_set_rx_timestamping(clone_pkt, net_pkt_is_rx_timestamping(pkt));
net_pkt_set_forwarding(clone_pkt, net_pkt_forwarding(pkt));
net_pkt_set_chksum_done(clone_pkt, net_pkt_is_chksum_done(pkt));
net_pkt_set_loopback(pkt, net_pkt_is_loopback(pkt));
net_pkt_set_ip_reassembled(pkt, net_pkt_is_ip_reassembled(pkt));
net_pkt_set_cooked_mode(clone_pkt, net_pkt_is_cooked_mode(pkt));
net_pkt_set_ipv4_pmtu(clone_pkt, net_pkt_ipv4_pmtu(pkt));
Expand Down
12 changes: 4 additions & 8 deletions subsys/net/ip/net_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,25 +177,21 @@ extern void loopback_enable_address_swap(bool swap_addresses);
#endif /* CONFIG_NET_TEST */

#if defined(CONFIG_NET_NATIVE)
enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
enum net_verdict net_ipv4_input(struct net_pkt *pkt);
enum net_verdict net_ipv6_input(struct net_pkt *pkt);
extern void net_tc_tx_init(void);
extern void net_tc_rx_init(void);
#else
static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
bool is_loopback)
static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt)
{
ARG_UNUSED(pkt);
ARG_UNUSED(is_loopback);

return NET_CONTINUE;
}

static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
bool is_loopback)
static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt)
{
ARG_UNUSED(pkt);
ARG_UNUSED(is_loopback);

return NET_CONTINUE;
}
Expand Down
4 changes: 2 additions & 2 deletions subsys/net/l2/virtual/ipip/ipip.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ static enum net_verdict interface_recv(struct net_if *iface,

net_pkt_cursor_restore(pkt, &hdr_start);

return net_ipv6_input(pkt, false);
return net_ipv6_input(pkt);
}

if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
Expand Down Expand Up @@ -421,7 +421,7 @@ static enum net_verdict interface_recv(struct net_if *iface,

net_pkt_cursor_restore(pkt, &hdr_start);

return net_ipv4_input(pkt, false);
return net_ipv4_input(pkt);
}

return NET_CONTINUE;
Expand Down
20 changes: 10 additions & 10 deletions tests/net/dhcpv6/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ ZTEST(dhcpv6_tests, test_input_reject_client_initiated_messages)
set_generic_client_options);
zassert_not_null(pkt, "Failed to create fake pkt");

result = net_ipv6_input(pkt, false);
result = net_ipv6_input(pkt);
zassert_equal(result, NET_DROP, "Should've drop the message");

net_pkt_unref(pkt);
Expand Down Expand Up @@ -719,7 +719,7 @@ ZTEST(dhcpv6_tests, test_input_advertise)
set_advertise_options);
zassert_not_null(pkt, "Failed to create pkt");

result = net_ipv6_input(pkt, false);
result = net_ipv6_input(pkt);

switch (state) {
case NET_DHCPV6_SOLICITING:
Expand Down Expand Up @@ -826,7 +826,7 @@ ZTEST(dhcpv6_tests, test_input_reply)
set_reply_options);
zassert_not_null(pkt, "Failed to create pkt");

result = net_ipv6_input(pkt, false);
result = net_ipv6_input(pkt);

switch (state) {
case NET_DHCPV6_CONFIRMING:
Expand Down Expand Up @@ -891,7 +891,7 @@ static void test_solicit_expect_request_send_reply(struct net_if *iface,
set_reply_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

/* Verify client state */
Expand Down Expand Up @@ -936,7 +936,7 @@ static void test_solicit_expect_solicit_send_advertise(struct net_if *iface,
set_advertise_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

/* Verify client state */
Expand Down Expand Up @@ -993,7 +993,7 @@ static void expect_request_send_reply(struct net_if *iface, struct net_pkt *pkt)
set_reply_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

k_sem_give(&test_ctx.exchange_complete_sem);
Expand All @@ -1013,7 +1013,7 @@ static void expect_solicit_send_advertise(struct net_if *iface, struct net_pkt *
set_advertise_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");
}

Expand Down Expand Up @@ -1058,7 +1058,7 @@ static void test_confirm_expect_confirm_send_reply(struct net_if *iface,
set_reply_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

/* Verify client state */
Expand Down Expand Up @@ -1127,7 +1127,7 @@ static void test_rebind_expect_rebind_send_reply(struct net_if *iface,
set_reply_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

/* Verify client state */
Expand Down Expand Up @@ -1201,7 +1201,7 @@ static void test_renew_expect_renew_send_reply(struct net_if *iface,
set_reply_options);
zassert_not_null(reply, "Failed to create pkt");

result = net_ipv6_input(reply, false);
result = net_ipv6_input(reply);
zassert_equal(result, NET_OK, "Message should've been processed");

/* Verify client state */
Expand Down
8 changes: 4 additions & 4 deletions tests/net/icmpv4/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ static void icmpv4_send_echo_req(void)
zassert_true(false, "EchoRequest packet prep failed");
}

if (net_ipv4_input(pkt, false)) {
if (net_ipv4_input(pkt)) {
net_pkt_unref(pkt);
zassert_true(false, "Failed to send");
}
Expand All @@ -474,7 +474,7 @@ static void icmpv4_send_echo_rep(void)
zassert_true(false, "EchoReply packet prep failed");
}

if (net_ipv4_input(pkt, false)) {
if (net_ipv4_input(pkt)) {
net_pkt_unref(pkt);
zassert_true(false, "Failed to send");
}
Expand All @@ -494,7 +494,7 @@ ZTEST(net_icmpv4, test_icmpv4_send_echo_req_opt)
zassert_true(false, "EchoRequest with opts packet prep failed");
}

if (net_ipv4_input(pkt, false)) {
if (net_ipv4_input(pkt)) {
net_pkt_unref(pkt);
zassert_true(false, "Failed to send");
}
Expand All @@ -510,7 +510,7 @@ ZTEST(net_icmpv4, test_send_echo_req_bad_opt)
"EchoRequest with bad opts packet prep failed");
}

if (net_ipv4_input(pkt, false)) {
if (net_ipv4_input(pkt)) {
net_pkt_unref(pkt);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/net/igmp/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ static void igmp_send_query(bool is_imgpv3)
pkt = prepare_igmp_query(net_iface, is_imgpv3);
zassert_not_null(pkt, "IGMPv2 query packet prep failed");

zassert_equal(net_ipv4_input(pkt, false), NET_OK, "Failed to send");
zassert_equal(net_ipv4_input(pkt), NET_OK, "Failed to send");

zassert_ok(k_sem_take(&wait_data, K_MSEC(WAIT_TIME)), "Timeout while waiting query event");

Expand Down
Loading
Loading