From dadb7bf935d145a9c8d1d635480f2407eb961da4 Mon Sep 17 00:00:00 2001 From: Cla Mattia Galliard Date: Tue, 15 Jul 2025 06:46:30 +0200 Subject: [PATCH 1/3] net_pkt: Store `is_loopback` info in packet meta-data Store the flag in the packet meta-data so that processing may be deferred if necessary. Signed-off-by: Cla Mattia Galliard --- include/zephyr/net/net_pkt.h | 12 ++++++++++++ subsys/net/ip/ipv4.c | 4 ++-- subsys/net/ip/ipv6.c | 6 +++--- subsys/net/ip/net_core.c | 21 ++++++++++----------- subsys/net/ip/net_pkt.c | 1 + subsys/net/ip/net_private.h | 12 ++++-------- subsys/net/l2/virtual/ipip/ipip.c | 4 ++-- tests/net/dhcpv6/src/main.c | 20 ++++++++++---------- tests/net/icmpv4/src/main.c | 8 ++++---- tests/net/igmp/src/main.c | 2 +- tests/net/ipv6/src/main.c | 2 +- tests/net/virtual/src/main.c | 4 ++-- 12 files changed, 52 insertions(+), 44 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 9f9df111f02c..e6abfcc8db64 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -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 @@ -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) { diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 9e7d7a900f6a..1e902bf47153 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -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); @@ -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"); diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 7cf8f7d58dcb..e481f2ed8420 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -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); @@ -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"); @@ -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; } diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index e090e38aa468..23083575d613 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -64,8 +64,7 @@ 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; @@ -93,7 +92,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt, return NET_DROP; } - if (!is_loopback && !locally_routed) { + if (!net_pkt_is_loopback(pkt) && !locally_routed) { ret = net_if_recv_data(net_pkt_iface(pkt), pkt); if (ret != NET_CONTINUE) { if (ret == NET_DROP) { @@ -131,9 +130,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); @@ -148,10 +147,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 @@ -421,7 +420,8 @@ 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); + processing_data(pkt); ret = 0; goto err; } @@ -481,7 +481,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); @@ -493,12 +492,12 @@ 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); } #endif } - processing_data(pkt, is_loopback); + processing_data(pkt); net_print_statistics(); net_pkt_print(); diff --git a/subsys/net/ip/net_pkt.c b/subsys/net/ip/net_pkt.c index b169223f3202..b0fa157f0349 100644 --- a/subsys/net/ip/net_pkt.c +++ b/subsys/net/ip/net_pkt.c @@ -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)); diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 4ed66f386a81..7a341c21d902 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -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; } diff --git a/subsys/net/l2/virtual/ipip/ipip.c b/subsys/net/l2/virtual/ipip/ipip.c index 44b7c51c8c47..7a9014623edd 100644 --- a/subsys/net/l2/virtual/ipip/ipip.c +++ b/subsys/net/l2/virtual/ipip/ipip.c @@ -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) { @@ -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; diff --git a/tests/net/dhcpv6/src/main.c b/tests/net/dhcpv6/src/main.c index a7c396cc0788..396718c3aee7 100644 --- a/tests/net/dhcpv6/src/main.c +++ b/tests/net/dhcpv6/src/main.c @@ -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); @@ -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: @@ -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: @@ -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 */ @@ -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 */ @@ -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); @@ -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"); } @@ -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 */ @@ -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 */ @@ -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 */ diff --git a/tests/net/icmpv4/src/main.c b/tests/net/icmpv4/src/main.c index 36e9436065db..caddef589c4c 100644 --- a/tests/net/icmpv4/src/main.c +++ b/tests/net/icmpv4/src/main.c @@ -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"); } @@ -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"); } @@ -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"); } @@ -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); } } diff --git a/tests/net/igmp/src/main.c b/tests/net/igmp/src/main.c index e2f201dd4eee..ad25ff55eeb5 100644 --- a/tests/net/igmp/src/main.c +++ b/tests/net/igmp/src/main.c @@ -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"); diff --git a/tests/net/ipv6/src/main.c b/tests/net/ipv6/src/main.c index 92615fc03f87..da7ef9afc878 100644 --- a/tests/net/ipv6/src/main.c +++ b/tests/net/ipv6/src/main.c @@ -1642,7 +1642,7 @@ static enum net_verdict recv_msg(struct in6_addr *src, struct in6_addr *dst) /* We by-pass the normal packet receiving flow in this case in order * to simplify the testing. */ - return net_ipv6_input(pkt, false); + return net_ipv6_input(pkt); } static int send_msg(struct in6_addr *src, struct in6_addr *dst) diff --git a/tests/net/virtual/src/main.c b/tests/net/virtual/src/main.c index 618b80d2c267..218f805c980a 100644 --- a/tests/net/virtual/src/main.c +++ b/tests/net/virtual/src/main.c @@ -1067,9 +1067,9 @@ static void test_virtual_recv_data_from_tunnel(int remote_ip, net_pkt_cursor_init(outer); if (peer_addr.sa_family == AF_INET) { - verdict = net_ipv4_input(outer, false); + verdict = net_ipv4_input(outer); } else { - verdict = net_ipv6_input(outer, false); + verdict = net_ipv6_input(outer); } if (expected_ok) { From 542688a970c70dd86c8fba99c9afd2d761bfeb5f Mon Sep 17 00:00:00 2001 From: Cla Mattia Galliard Date: Tue, 15 Jul 2025 06:47:01 +0200 Subject: [PATCH 2/3] net_core: Decide about l2-processing based on l2_processed-flag Use the l2_processed-flag to decide whether a network packet needs to be processed by an L2-handler. This could be used in the future to requeue packets for later processing by a different traffic class queue. Signed-off-by: Cla Mattia Galliard --- subsys/net/ip/ipv4_fragment.c | 4 ++-- subsys/net/ip/ipv6_fragment.c | 4 ++-- subsys/net/ip/net_core.c | 15 ++------------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/subsys/net/ip/ipv4_fragment.c b/subsys/net/ip/ipv4_fragment.c index 3df39c28970b..bbe41ab534ea 100644 --- a/subsys/net/ip/ipv4_fragment.c +++ b/subsys/net/ip/ipv4_fragment.c @@ -211,9 +211,9 @@ static void reassemble_packet(struct net_ipv4_reassembly *reass) /* We need to use the queue when feeding the packet back into the * IP stack as we might run out of stack if we call processing_data() * directly. As the packet does not contain link layer header, we - * MUST NOT pass it to L2 so there will be a special check for that - * in process_data() when handling the packet. + * MUST NOT pass it to L2 so mark it as l2_processed. */ + net_pkt_set_l2_processed(pkt, true); if (net_recv_data(net_pkt_iface(pkt), pkt) >= 0) { return; } diff --git a/subsys/net/ip/ipv6_fragment.c b/subsys/net/ip/ipv6_fragment.c index 22408a46f9c1..dc913a7a6033 100644 --- a/subsys/net/ip/ipv6_fragment.c +++ b/subsys/net/ip/ipv6_fragment.c @@ -346,9 +346,9 @@ static void reassemble_packet(struct net_ipv6_reassembly *reass) /* We need to use the queue when feeding the packet back into the * IP stack as we might run out of stack if we call processing_data() * directly. As the packet does not contain link layer header, we - * MUST NOT pass it to L2 so there will be a special check for that - * in process_data() when handling the packet. + * MUST NOT pass it to L2 so mark it as l2_processed. */ + net_pkt_set_l2_processed(pkt, true); if (net_recv_data(net_pkt_iface(pkt), pkt) >= 0) { return; } diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 23083575d613..e5737fb3b5d0 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -67,9 +67,6 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL); 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); @@ -77,13 +74,6 @@ static inline enum net_verdict process_data(struct net_pkt *pkt) 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); @@ -92,8 +82,9 @@ static inline enum net_verdict process_data(struct net_pkt *pkt) return NET_DROP; } - if (!net_pkt_is_loopback(pkt) && !locally_routed) { + if (!net_pkt_is_loopback(pkt) && !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); @@ -105,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. */ From e17f88f7b657ad234016f493e008d80e9f51ffd9 Mon Sep 17 00:00:00 2001 From: Cla Mattia Galliard Date: Tue, 15 Jul 2025 06:47:01 +0200 Subject: [PATCH 3/3] packet_socket: Specify the socket-type, when inputing Specify the socket type, when inputing a packet into a packet-socket. Signed-off-by: Cla Mattia Galliard --- subsys/net/ip/connection.c | 9 +++++---- subsys/net/ip/connection.h | 5 ++++- subsys/net/ip/net_core.c | 12 +++++------- subsys/net/ip/packet_socket.c | 6 ++++-- subsys/net/ip/packet_socket.h | 7 +++++-- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index b95462f9331a..58c6ae782c22 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -637,7 +637,7 @@ static void conn_raw_socket_deliver(struct net_pkt *pkt, struct net_conn *conn, #endif /* defined(CONFIG_NET_SOCKETS_PACKET) || defined(CONFIG_NET_SOCKETS_INET_RAW) */ #if defined(CONFIG_NET_SOCKETS_PACKET) -enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto) +enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto, enum net_sock_type type) { bool raw_sock_found = false; bool raw_pkt_continue = false; @@ -670,7 +670,7 @@ enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto) continue; /* wrong family */ } - if (conn->type == SOCK_DGRAM && !net_pkt_is_l2_processed(pkt)) { + if (conn->type == SOCK_DGRAM && type == SOCK_RAW) { /* If DGRAM packet sockets are present, we shall continue * with this packet regardless the result. */ @@ -678,7 +678,7 @@ enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto) continue; /* L2 not processed yet */ } - if (conn->type == SOCK_RAW && net_pkt_is_l2_processed(pkt)) { + if (conn->type == SOCK_RAW && type != SOCK_RAW) { continue; /* L2 already processed */ } @@ -727,10 +727,11 @@ enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto) return NET_CONTINUE; } #else -enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto) +enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto, enum net_sock_type type) { ARG_UNUSED(pkt); ARG_UNUSED(proto); + ARG_UNUSED(type); return NET_CONTINUE; } diff --git a/subsys/net/ip/connection.h b/subsys/net/ip/connection.h index a6660cad6bbc..bc11703e16b6 100644 --- a/subsys/net/ip/connection.h +++ b/subsys/net/ip/connection.h @@ -189,11 +189,14 @@ int net_conn_update(struct net_conn_handle *handle, * * @param pkt Network packet holding received data * @param proto LL protocol for the connection + * @param type socket type * * @return NET_OK if the packet was consumed, NET_CONTINUE if the packet should * be processed further in the stack. */ -enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto); +enum net_verdict net_conn_packet_input(struct net_pkt *pkt, + uint16_t proto, + enum net_sock_type type); /** * @brief Called by net_core.c when an IP packet is received diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index e5737fb3b5d0..888ce9da9fc9 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -68,8 +68,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt) { int ret; - /* Initial call will forward packets to SOCK_RAW packet sockets. */ - ret = net_packet_socket_input(pkt, ETH_P_ALL); + ret = net_packet_socket_input(pkt, ETH_P_ALL, SOCK_RAW); if (ret != NET_CONTINUE) { return ret; } @@ -82,7 +81,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt) return NET_DROP; } - if (!net_pkt_is_loopback(pkt) && !net_pkt_is_l2_processed(pkt)) { + 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) { @@ -102,10 +101,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt) net_pkt_cursor_init(pkt); if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM)) { - /* Consecutive call will forward packets to SOCK_DGRAM packet sockets - * (after L2 removed header). - */ - ret = net_packet_socket_input(pkt, net_pkt_ll_proto_type(pkt)); + ret = net_packet_socket_input(pkt, net_pkt_ll_proto_type(pkt), SOCK_DGRAM); if (ret != NET_CONTINUE) { return ret; } @@ -410,6 +406,7 @@ int net_try_send_data(struct net_pkt *pkt, k_timeout_t timeout) */ NET_DBG("Loopback pkt %p back to us", pkt); net_pkt_set_loopback(pkt, true); + net_pkt_set_l2_processed(pkt, true); processing_data(pkt); ret = 0; goto err; @@ -482,6 +479,7 @@ static void net_rx(struct net_if *iface, struct net_pkt *pkt) #ifdef CONFIG_NET_L2_DUMMY if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) { net_pkt_set_loopback(pkt, true); + net_pkt_set_l2_processed(pkt, true); } #endif } diff --git a/subsys/net/ip/packet_socket.c b/subsys/net/ip/packet_socket.c index 829e990dafef..3ce571f5d875 100644 --- a/subsys/net/ip/packet_socket.c +++ b/subsys/net/ip/packet_socket.c @@ -22,7 +22,9 @@ LOG_MODULE_REGISTER(net_sockets_raw, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "connection.h" #include "packet_socket.h" -enum net_verdict net_packet_socket_input(struct net_pkt *pkt, uint16_t proto) +enum net_verdict net_packet_socket_input(struct net_pkt *pkt, + uint16_t proto, + enum net_sock_type type) { sa_family_t orig_family; enum net_verdict net_verdict; @@ -41,7 +43,7 @@ enum net_verdict net_packet_socket_input(struct net_pkt *pkt, uint16_t proto) net_pkt_set_family(pkt, AF_PACKET); - net_verdict = net_conn_packet_input(pkt, proto); + net_verdict = net_conn_packet_input(pkt, proto, type); net_pkt_set_family(pkt, orig_family); diff --git a/subsys/net/ip/packet_socket.h b/subsys/net/ip/packet_socket.h index b44717635b41..a2704c4e5914 100644 --- a/subsys/net/ip/packet_socket.h +++ b/subsys/net/ip/packet_socket.h @@ -26,10 +26,13 @@ * disabled, the function will always return NET_DROP. */ #if defined(CONFIG_NET_SOCKETS_PACKET) -enum net_verdict net_packet_socket_input(struct net_pkt *pkt, uint16_t proto); +enum net_verdict net_packet_socket_input(struct net_pkt *pkt, + uint16_t proto, + enum net_sock_type type); #else static inline enum net_verdict net_packet_socket_input(struct net_pkt *pkt, - uint16_t proto) + uint16_t proto, + enum net_sock_type type) { return NET_CONTINUE; }