Skip to content

Commit 9247b83

Browse files
committed
net_pkt: Store meta-information of processing in the net_pkt
Store a flag about which layer has already processed a packet in its meta information. This enables deferred processing of it.
1 parent c287e48 commit 9247b83

File tree

5 files changed

+136
-55
lines changed

5 files changed

+136
-55
lines changed

include/zephyr/net/net_pkt.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,18 @@ struct net_pkt {
231231
* preserved. Useful only if
232232
* defined(CONFIG_NET_ETHERNET_BRIDGE).
233233
*/
234+
uint8_t raw_processed : 1; /* Set to 1 if this packet has already been
235+
* processed by SOCK_RAW
236+
*/
237+
uint8_t dgram_processed : 1; /* Set to 1 if this packet has already been
238+
* processed by SOCK_DGRAM
239+
*/
234240
uint8_t l2_processed : 1; /* Set to 1 if this packet has already been
235241
* processed by the L2
236242
*/
243+
uint8_t l3_processed : 1; /* Set to 1 if this packet has already been
244+
* processed by the L3
245+
*/
237246
uint8_t chksum_done : 1; /* Checksum has already been computed for
238247
* the packet.
239248
*/
@@ -554,6 +563,28 @@ static inline void net_pkt_set_l2_bridged(struct net_pkt *pkt, bool is_l2_bridge
554563
}
555564
}
556565

566+
static inline bool net_pkt_is_raw_processed(struct net_pkt *pkt)
567+
{
568+
return !!(pkt->raw_processed);
569+
}
570+
571+
static inline void net_pkt_set_raw_processed(struct net_pkt *pkt,
572+
bool is_raw_processed)
573+
{
574+
pkt->raw_processed = is_raw_processed;
575+
}
576+
577+
static inline bool net_pkt_is_dgram_processed(struct net_pkt *pkt)
578+
{
579+
return !!(pkt->dgram_processed);
580+
}
581+
582+
static inline void net_pkt_set_dgram_processed(struct net_pkt *pkt,
583+
bool is_dgram_processed)
584+
{
585+
pkt->dgram_processed = is_dgram_processed;
586+
}
587+
557588
static inline bool net_pkt_is_l2_processed(struct net_pkt *pkt)
558589
{
559590
return !!(pkt->l2_processed);
@@ -565,6 +596,17 @@ static inline void net_pkt_set_l2_processed(struct net_pkt *pkt,
565596
pkt->l2_processed = is_l2_processed;
566597
}
567598

599+
static inline bool net_pkt_is_l3_processed(struct net_pkt *pkt)
600+
{
601+
return !!(pkt->l3_processed);
602+
}
603+
604+
static inline void net_pkt_set_l3_processed(struct net_pkt *pkt,
605+
bool is_l3_processed)
606+
{
607+
pkt->l3_processed = is_l3_processed;
608+
}
609+
568610
static inline bool net_pkt_is_chksum_done(struct net_pkt *pkt)
569611
{
570612
return !!(pkt->chksum_done);

subsys/net/ip/net_core.c

Lines changed: 75 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -68,87 +68,107 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
6868
{
6969
int ret;
7070

71-
net_packet_socket_input(pkt, ETH_P_ALL, SOCK_RAW);
72-
73-
/* If there is no data, then drop the packet. */
74-
if (!pkt->frags) {
71+
if (!net_pkt_is_raw_processed(pkt)) {
72+
net_pkt_set_raw_processed(pkt, true);
73+
net_packet_socket_input(pkt, ETH_P_ALL, SOCK_RAW);
74+
return NET_CONTINUE;
75+
} else if (!pkt->frags) {
76+
/* If there is no data, then drop the packet. */
7577
NET_DBG("Corrupted packet (frags %p)", pkt->frags);
7678
net_stats_update_processing_error(net_pkt_iface(pkt));
77-
7879
return NET_DROP;
79-
}
80-
81-
if (!net_pkt_is_l2_processed(pkt)) {
82-
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
80+
} else if (!net_pkt_is_l2_processed(pkt)) {
8381
net_pkt_set_l2_processed(pkt, true);
82+
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
8483
if (ret != NET_CONTINUE) {
8584
if (ret == NET_DROP) {
8685
NET_DBG("Packet %p discarded by L2", pkt);
8786
net_stats_update_processing_error(
8887
net_pkt_iface(pkt));
8988
}
90-
9189
return ret;
9290
}
93-
}
94-
95-
/* L2 has modified the buffer starting point, it is easier
96-
* to re-initialize the cursor rather than updating it.
97-
*/
98-
net_pkt_cursor_init(pkt);
99-
100-
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM)) {
91+
/* L2 has modified the buffer starting point, it is easier
92+
* to re-initialize the cursor rather than updating it.
93+
*/
94+
net_pkt_cursor_init(pkt);
95+
return NET_CONTINUE;
96+
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM) &&
97+
!net_pkt_is_dgram_processed(pkt)) {
98+
net_pkt_set_dgram_processed(pkt, true);
10199
net_packet_socket_input(pkt, net_pkt_ll_proto_type(pkt), SOCK_DGRAM);
100+
return NET_CONTINUE;
101+
} else if (net_pkt_is_l3_processed(pkt)) {
102+
net_pkt_set_l3_processed(pkt, true);
103+
uint8_t family = net_pkt_family(pkt);
104+
105+
if (IS_ENABLED(CONFIG_NET_IP) && (family == AF_INET || family == AF_INET6 ||
106+
family == AF_UNSPEC || family == AF_PACKET)) {
107+
/* IP version and header length. */
108+
uint8_t vtc_vhl = NET_IPV6_HDR(pkt)->vtc & 0xf0;
109+
110+
if (IS_ENABLED(CONFIG_NET_IPV6) && vtc_vhl == 0x60) {
111+
return net_ipv6_input(pkt);
112+
} else if (IS_ENABLED(CONFIG_NET_IPV4) && vtc_vhl == 0x40) {
113+
return net_ipv4_input(pkt);
114+
}
115+
116+
NET_DBG("Unknown IP family packet (0x%x)", NET_IPV6_HDR(pkt)->vtc & 0xf0);
117+
net_stats_update_ip_errors_protoerr(net_pkt_iface(pkt));
118+
net_stats_update_ip_errors_vhlerr(net_pkt_iface(pkt));
119+
return NET_DROP;
120+
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
121+
return net_canbus_socket_input(pkt);
122+
}
123+
NET_DBG("Unknown protocol family packet (0x%x)", family);
124+
return NET_DROP;
102125
}
103126

104-
uint8_t family = net_pkt_family(pkt);
127+
return NET_DROP;
105128

106-
if (IS_ENABLED(CONFIG_NET_IP) && (family == AF_INET || family == AF_INET6 ||
107-
family == AF_UNSPEC || family == AF_PACKET)) {
108-
/* IP version and header length. */
109-
uint8_t vtc_vhl = NET_IPV6_HDR(pkt)->vtc & 0xf0;
129+
}
110130

111-
if (IS_ENABLED(CONFIG_NET_IPV6) && vtc_vhl == 0x60) {
112-
return net_ipv6_input(pkt);
113-
} else if (IS_ENABLED(CONFIG_NET_IPV4) && vtc_vhl == 0x40) {
114-
return net_ipv4_input(pkt);
131+
static void update_priority(struct net_pkt *pkt)
132+
{
133+
/* This is just an example.
134+
* Similar infrastructure with custom application rules like
135+
* net_pkt_filter could be established
136+
* */
137+
if (net_pkt_is_l2_processed(pkt)) {
138+
if (net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_PTP) {
139+
net_pkt_set_priority(pkt, NET_PRIORITY_IC);
115140
}
116-
117-
NET_DBG("Unknown IP family packet (0x%x)", NET_IPV6_HDR(pkt)->vtc & 0xf0);
118-
net_stats_update_ip_errors_protoerr(net_pkt_iface(pkt));
119-
net_stats_update_ip_errors_vhlerr(net_pkt_iface(pkt));
120-
return NET_DROP;
121-
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
122-
return net_canbus_socket_input(pkt);
123141
}
142+
}
124143

125-
NET_DBG("Unknown protocol family packet (0x%x)", family);
126-
return NET_DROP;
144+
static bool being_processed_by_correct_thread(struct net_pkt *pkt)
145+
{
146+
uint8_t prio = net_pkt_priority(pkt);
147+
uint8_t tc = net_rx_priority2tc(prio);
148+
149+
return net_tc_is_current_thread(tc);
127150
}
128151

129152
static void processing_data(struct net_pkt *pkt)
130153
{
131-
again:
132-
switch (process_data(pkt)) {
133-
case NET_CONTINUE:
134-
if (IS_ENABLED(CONFIG_NET_L2_VIRTUAL)) {
135-
/* If we have a tunneling packet, feed it back
136-
* to the stack in this case.
137-
*/
138-
goto again;
139-
} else {
140-
NET_DBG("Dropping pkt %p", pkt);
141-
net_pkt_unref(pkt);
154+
enum net_verdict verdict = NET_CONTINUE;
155+
156+
do {
157+
verdict = process_data(pkt);
158+
if (verdict != NET_CONTINUE) {
159+
break;
142160
}
143-
break;
144-
case NET_OK:
145-
NET_DBG("Consumed pkt %p", pkt);
146-
break;
147-
case NET_DROP:
148-
default:
149-
NET_DBG("Dropping pkt %p", pkt);
161+
162+
update_priority(pkt);
163+
164+
if (!being_processed_by_correct_thread(pkt)) {
165+
net_queue_rx(net_pkt_iface(pkt), pkt);
166+
}
167+
168+
} while (true);
169+
170+
if (verdict != NET_OK) {
150171
net_pkt_unref(pkt);
151-
break;
152172
}
153173
}
154174

subsys/net/ip/net_pkt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,7 +2052,10 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt)
20522052
net_pkt_set_cooked_mode(clone_pkt, net_pkt_is_cooked_mode(pkt));
20532053
net_pkt_set_ipv4_pmtu(clone_pkt, net_pkt_ipv4_pmtu(pkt));
20542054
net_pkt_set_l2_bridged(clone_pkt, net_pkt_is_l2_bridged(pkt));
2055+
net_pkt_set_raw_processed(clone_pkt, net_pkt_is_raw_processed(pkt));
2056+
net_pkt_set_dgram_processed(clone_pkt, net_pkt_is_dgram_processed(pkt));
20552057
net_pkt_set_l2_processed(clone_pkt, net_pkt_is_l2_processed(pkt));
2058+
net_pkt_set_l3_processed(clone_pkt, net_pkt_is_l3_processed(pkt));
20562059
net_pkt_set_ll_proto_type(clone_pkt, net_pkt_ll_proto_type(pkt));
20572060

20582061
#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_L2_IPIP)

subsys/net/ip/net_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ static inline void net_tc_rx_init(void) { }
201201
#endif
202202
enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
203203
k_timeout_t timeout);
204+
bool net_tc_is_current_thread(uint8_t tc);
204205
extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
205206
extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
206207

subsys/net/ip/net_tc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ static struct net_traffic_class tx_classes[NET_TC_TX_COUNT];
6565
static struct net_traffic_class rx_classes[NET_TC_RX_COUNT];
6666
#endif
6767

68+
bool net_tc_is_current_thread(uint8_t tc)
69+
{
70+
uint8_t thread_priority;
71+
int priority;
72+
int desired_priority;
73+
74+
thread_priority = tx_tc2thread(tc);
75+
desired_priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ?
76+
K_PRIO_COOP(thread_priority) :
77+
K_PRIO_PREEMPT(thread_priority);
78+
priority = k_thread_priority_get(k_current_get());
79+
80+
return priority == desired_priority;
81+
}
82+
6883
enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
6984
k_timeout_t timeout)
7085
{

0 commit comments

Comments
 (0)