@@ -68,87 +68,107 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
68
68
{
69
69
int ret ;
70
70
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. */
75
77
NET_DBG ("Corrupted packet (frags %p)" , pkt -> frags );
76
78
net_stats_update_processing_error (net_pkt_iface (pkt ));
77
-
78
79
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 )) {
83
81
net_pkt_set_l2_processed (pkt , true);
82
+ ret = net_if_recv_data (net_pkt_iface (pkt ), pkt );
84
83
if (ret != NET_CONTINUE ) {
85
84
if (ret == NET_DROP ) {
86
85
NET_DBG ("Packet %p discarded by L2" , pkt );
87
86
net_stats_update_processing_error (
88
87
net_pkt_iface (pkt ));
89
88
}
90
-
91
89
return ret ;
92
90
}
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);
101
99
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 ;
102
125
}
103
126
104
- uint8_t family = net_pkt_family ( pkt ) ;
127
+ return NET_DROP ;
105
128
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
+ }
110
130
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 );
115
140
}
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 );
123
141
}
142
+ }
124
143
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 );
127
150
}
128
151
129
152
static void processing_data (struct net_pkt * pkt )
130
153
{
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 ;
142
160
}
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 ) {
150
171
net_pkt_unref (pkt );
151
- break ;
152
172
}
153
173
}
154
174
0 commit comments