Skip to content

net_pkt: Store meta-information of processing in the net_pkt #93298

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 5 commits 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
54 changes: 54 additions & 0 deletions include/zephyr/net/net_pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,22 @@ struct net_pkt {
* preserved. Useful only if
* defined(CONFIG_NET_ETHERNET_BRIDGE).
*/
uint8_t raw_processed : 1; /* Set to 1 if this packet has already been
* processed by SOCK_RAW
*/
uint8_t dgram_processed : 1; /* Set to 1 if this packet has already been
* processed by SOCK_DGRAM
*/
uint8_t l2_processed : 1; /* Set to 1 if this packet has already been
* processed by the L2
*/
uint8_t l3_processed : 1; /* Set to 1 if this packet has already been
* processed by the L3
*/
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 @@ -553,6 +563,28 @@ static inline void net_pkt_set_l2_bridged(struct net_pkt *pkt, bool is_l2_bridge
}
}

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

static inline void net_pkt_set_raw_processed(struct net_pkt *pkt,
bool is_raw_processed)
{
pkt->raw_processed = is_raw_processed;
}

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

static inline void net_pkt_set_dgram_processed(struct net_pkt *pkt,
bool is_dgram_processed)
{
pkt->dgram_processed = is_dgram_processed;
}

static inline bool net_pkt_is_l2_processed(struct net_pkt *pkt)
{
return !!(pkt->l2_processed);
Expand All @@ -564,6 +596,17 @@ static inline void net_pkt_set_l2_processed(struct net_pkt *pkt,
pkt->l2_processed = is_l2_processed;
}

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

static inline void net_pkt_set_l3_processed(struct net_pkt *pkt,
bool is_l3_processed)
{
pkt->l3_processed = is_l3_processed;
}

static inline bool net_pkt_is_chksum_done(struct net_pkt *pkt)
{
return !!(pkt->chksum_done);
Expand Down Expand Up @@ -1020,6 +1063,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
49 changes: 11 additions & 38 deletions subsys/net/ip/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,16 +637,14 @@ 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)
void 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;
struct sockaddr_ll *local;
struct net_conn *conn;

/* Only accept input with AF_PACKET family. */
if (net_pkt_family(pkt) != AF_PACKET) {
return NET_CONTINUE;
return;
}

NET_DBG("Check proto 0x%04x listener for pkt %p family %d",
Expand All @@ -666,33 +664,22 @@ enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto)
* in this packet.
*/
if (conn->family != AF_PACKET) {
raw_pkt_continue = true;
continue; /* wrong family */
}

if (conn->type == SOCK_DGRAM && !net_pkt_is_l2_processed(pkt)) {
/* If DGRAM packet sockets are present, we shall continue
* with this packet regardless the result.
*/
raw_pkt_continue = true;
continue; /* L2 not processed yet */
}

if (conn->type == SOCK_RAW && net_pkt_is_l2_processed(pkt)) {
continue; /* L2 already processed */
if (conn->type != type) {
continue;
}

if (conn->proto == 0) {
continue; /* Local proto 0 doesn't forward any packets */
}

if (conn->proto != proto) {
/* Allow proto mismatch if socket was created with ETH_P_ALL, or it's raw
* packet socket input (proto ETH_P_ALL).
*/
if (conn->proto != ETH_P_ALL && proto != ETH_P_ALL) {
continue; /* wrong protocol */
}
/* Allow proto mismatch if socket was created with ETH_P_ALL, or it's raw
* packet socket input.
*/
if (conn->proto != proto && conn->proto != ETH_P_ALL && type != SOCK_RAW) {
continue; /* wrong protocol */
}

/* Apply protocol-specific matching criteria... */
Expand All @@ -708,31 +695,17 @@ enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto)

conn_raw_socket_deliver(pkt, conn, false);

raw_sock_found = true;
}

k_mutex_unlock(&conn_lock);

if (!raw_pkt_continue && raw_sock_found) {
/* As one or more raw socket packets have already been delivered
* in the loop above, report NET_OK.
*/
net_pkt_unref(pkt);
return NET_OK;
}

/* When there is open connection different than AF_PACKET this
* packet shall be also handled in the upper net stack layers.
*/
return NET_CONTINUE;
}
#else
enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto)
void net_conn_packet_input(struct net_pkt *pkt, uint16_t proto, enum net_sock_type type)
{
ARG_UNUSED(pkt);
ARG_UNUSED(proto);

return NET_CONTINUE;
ARG_UNUSED(type);
}
#endif /* defined(CONFIG_NET_SOCKETS_PACKET) */

Expand Down
7 changes: 4 additions & 3 deletions subsys/net/ip/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,12 @@ 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);
void 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
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: 3 additions & 2 deletions subsys/net/ip/ipv4_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,10 @@ 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);
net_pkt_set_l3_processed(pkt, false);
if (net_recv_data(net_pkt_iface(pkt), pkt) >= 0) {
return;
}
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: 3 additions & 2 deletions subsys/net/ip/ipv6_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,10 @@ 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);
net_pkt_set_l3_processed(pkt, false);
if (net_recv_data(net_pkt_iface(pkt), pkt) >= 0) {
return;
}
Expand Down
Loading