1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Internet Protocol (IP) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "tx_thread.h"
30 #include "nx_ip.h"
31 #include "nx_packet.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_ip_raw_packet_processing PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function processes a received raw IP packet from the */
47 /* _nx_ip_packet_receive function and either queues it or gives it to */
48 /* the first suspended thread waiting for a raw IP packet. */
49 /* */
50 /* INPUT */
51 /* */
52 /* ip_ptr Pointer to IP control block */
53 /* packet_ptr Pointer to packet to send */
54 /* protocol The upper layer protocol */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* None */
59 /* */
60 /* CALLS */
61 /* */
62 /* _tx_thread_system_resume Resume suspended thread */
63 /* _nx_packet_release Release the raw packet */
64 /* [nx_ip_raw_packet_filter] User-defined packet filter */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* _nx_ip_packet_receive Packet receive processing */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
75 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_nx_ip_raw_packet_processing(NX_IP * ip_ptr,ULONG protocol,NX_PACKET * packet_ptr)79 UINT _nx_ip_raw_packet_processing(NX_IP *ip_ptr, ULONG protocol, NX_PACKET *packet_ptr)
80 {
81
82 TX_INTERRUPT_SAVE_AREA
83 TX_THREAD *thread_ptr;
84
85 /* Add debug information. */
86 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
87
88 #ifdef NX_ENABLE_IP_RAW_PACKET_FILTER
89 /* If raw packet filter is installed */
90 if (ip_ptr -> nx_ip_raw_packet_filter)
91 {
92 if ((ip_ptr -> nx_ip_raw_packet_filter)(ip_ptr, (protocol >> 16) & 0xFF, packet_ptr) != NX_SUCCESS)
93 {
94 return(1); /* Raw filter did not consume this packet. Allow the caller to process this packet. */
95 }
96 else
97 {
98 return(NX_SUCCESS); /* The caller should not process this packet. */
99 }
100 }
101 #else
102 NX_PARAMETER_NOT_USED(protocol);
103 #endif /* NX_ENABLE_IP_RAW_PACKET_FILTER */
104
105 /* Disable interrupts. */
106 TX_DISABLE
107
108 /* Determine if there is a thread waiting for the IP packet. If so, just
109 give the packet to the waiting thread. */
110 thread_ptr = ip_ptr -> nx_ip_raw_packet_suspension_list;
111 if (thread_ptr)
112 {
113
114 /* Yes, a thread is suspended on the raw IP packet queue. */
115
116 /* See if this is the only suspended thread on the list. */
117 if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
118 {
119
120 /* Yes, the only suspended thread. */
121
122 /* Update the head pointer. */
123 ip_ptr -> nx_ip_raw_packet_suspension_list = NX_NULL;
124 }
125 else
126 {
127
128 /* At least one more thread is on the same expiration list. */
129
130 /* Update the list head pointer. */
131 ip_ptr -> nx_ip_raw_packet_suspension_list = thread_ptr -> tx_thread_suspended_next;
132
133 /* Update the links of the adjacent threads. */
134 (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
135 thread_ptr -> tx_thread_suspended_previous;
136 (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
137 thread_ptr -> tx_thread_suspended_next;
138 }
139
140 /* Decrement the suspension count. */
141 ip_ptr -> nx_ip_raw_packet_suspended_count--;
142
143 /* Prepare for resumption of the first thread. */
144
145 /* Clear cleanup routine to avoid timeout. */
146 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
147
148 /* Temporarily disable preemption. */
149 _tx_thread_preempt_disable++;
150
151 /* Add debug information. */
152 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
153
154 /* Restore interrupts. */
155 TX_RESTORE
156
157 /* Return this packet pointer to the suspended thread waiting for
158 a block. */
159 *((NX_PACKET **)thread_ptr -> tx_thread_additional_suspend_info) = packet_ptr;
160
161 /* Put return status into the thread control block. */
162 thread_ptr -> tx_thread_suspend_status = NX_SUCCESS;
163
164 /* Resume thread. */
165 _tx_thread_system_resume(thread_ptr);
166 }
167 else
168 {
169
170 /* The packet is queued only if the number of packets in the queue does not exceed
171 user-speicified limit. */
172 if (ip_ptr -> nx_ip_raw_received_packet_count >= ip_ptr -> nx_ip_raw_received_packet_max)
173 {
174 _nx_packet_release(packet_ptr);
175 return(NX_SUCCESS); /* This packet has been released so the caller should not
176 further process it. */
177 }
178
179
180
181 /* Otherwise, queue the raw IP packet in a FIFO manner on the raw packet list. */
182
183 /* Clear the next packet pointer. */
184 packet_ptr -> nx_packet_queue_next = NX_NULL;
185
186 /* Determine if the queue is empty. */
187 if (ip_ptr -> nx_ip_raw_received_packet_tail)
188 {
189
190 /* List is not empty, place the raw packet at the end of the raw packet list. */
191 (ip_ptr -> nx_ip_raw_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
192 ip_ptr -> nx_ip_raw_received_packet_tail = packet_ptr;
193 }
194 else
195 {
196
197 /* This is the first entry on the queue so set the head and tail pointers. */
198 ip_ptr -> nx_ip_raw_received_packet_head = packet_ptr;
199 ip_ptr -> nx_ip_raw_received_packet_tail = packet_ptr;
200 }
201
202 /* Increment the raw packet received count. */
203 ip_ptr -> nx_ip_raw_received_packet_count++;
204
205 /* Restore interrupts. */
206 TX_RESTORE
207 }
208
209 /* The packet is enqueued, therefore return NX_SUCCESS so the stack does not
210 further process this packet. */
211 return(NX_SUCCESS);
212 }
213
214