Skip to content
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

Don't Fragment Flags patch. #179

Merged
merged 9 commits into from
Feb 3, 2021
9 changes: 9 additions & 0 deletions FreeRTOS_DNS.c
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,15 @@
pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
pxIPHeader->ucTimeToLive = ipconfigUDP_TIME_TO_LIVE;
pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );

/* The stack doesn't support fragments, so the fragment offset field must always be zero.
* The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
*/
#if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
#else
pxIPHeader->usFragmentOffset = 0U;
#endif
usPacketIdentifier++;
pxUDPHeader->usLength = FreeRTOS_htons( ( uint32_t ) lNetLength + ipSIZE_OF_UDP_HEADER );
vFlip_16( pxUDPHeader->usSourcePort, pxUDPHeader->usDestinationPort );
Expand Down
28 changes: 14 additions & 14 deletions FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,6 @@
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#endif

#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
#if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
/** @brief The bits in the two byte IP header field that make up the fragment offset value. */
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0xff0f )
#else
/** @brief The bits in the two byte IP header field that make up the fragment offset value. */
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff )
#endif /* ipconfigBYTE_ORDER */
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */

Comment on lines -118 to -127
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was expanded with more definitions and moved to FreeRTOS_IP_Private.h so that those defines are accessible to al IP-based protocols.

/** @brief The maximum time the IP task is allowed to remain in the Blocked state if no
* events are posted to the network event queue. */
#ifndef ipconfigMAX_IP_TASK_SLEEP_TIME
Expand Down Expand Up @@ -1850,10 +1840,11 @@ static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPP
* This method may decrease the usage of sparse network buffers. */
uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;

/* Ensure that the incoming packet is not fragmented (only outgoing
* packets can be fragmented) as these are the only handled IP frames
* currently. */
if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
/* Ensure that the incoming packet is not fragmented because the stack
* doesn't not support IP fragmentation. All but the last fragment coming in will have their
* "more fragments" flag set and the last fragment will have a non-zero offset.
* We need to drop the packet in either of those cases. */
if( ( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U ) || ( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_FLAGS_MORE_FRAGMENTS ) != 0U ) )
{
/* Can not handle, fragmented packet. */
eReturn = eReleaseBuffer;
Expand Down Expand Up @@ -2246,6 +2237,15 @@ static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * pxIPPacket,
pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;

/* The stack doesn't support fragments, so the fragment offset field must always be zero.
* The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
*/
#if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
#else
pxIPHeader->usFragmentOffset = 0U;
#endif

/* Update the checksum because the ucTypeOfMessage member in the header
* has been changed to ipICMP_ECHO_REPLY. This is faster than calling
* usGenerateChecksum(). */
Expand Down
10 changes: 9 additions & 1 deletion FreeRTOS_TCP_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,15 @@
/* Just an increasing number. */
pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
usPacketIdentifier++;
pxIPHeader->usFragmentOffset = 0U;

/* The stack doesn't support fragments, so the fragment offset field must always be zero.
* The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
*/
#if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
#else
pxIPHeader->usFragmentOffset = 0U;
#endif

/* Important: tell NIC driver how many bytes must be sent. */
pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
Expand Down
9 changes: 9 additions & 0 deletions FreeRTOS_UDP_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@ void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuff
pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;

/* The stack doesn't support fragments, so the fragment offset field must always be zero.
* The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
*/
#if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
#else
pxIPHeader->usFragmentOffset = 0U;
#endif

#if ( ipconfigUSE_LLMNR == 1 )
{
/* LLMNR messages are typically used on a LAN and they're
Expand Down
12 changes: 12 additions & 0 deletions include/FreeRTOSIPConfigDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,18 @@
#define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1
#endif

/* Configuration to control whether all outgoing IP datagrams get their
* "don't fragment" flag set.
* If set to 1, the stack will set the "don't fragment" flag on all outgoing IP
* packets. If a packet needs to be fragmented somewhere along it's path, it will get
* discarded instead of fragmented.
* If set to 0, the stack will clear the "don't fragment" flag an all outgoing IP
* packets therefore allowing fragmentation if it is needed.
*/
#ifndef ipconfigFORCE_IP_DONT_FRAGMENT
#define ipconfigFORCE_IP_DONT_FRAGMENT 0
#endif

/* Configuration to control whether UDP packets with
* checksum value of zero should be passed up the software
* stack OR should be dropped.
Expand Down
24 changes: 21 additions & 3 deletions include/FreeRTOS_IP_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,6 @@
#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 )
#define ipSOCKET_OPTIONS_OFFSET ( 6 )

/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h
* setting. */
#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET )

/* The offset into a UDP packet at which the UDP data (payload) starts. */
#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) )
Expand Down Expand Up @@ -418,6 +415,27 @@

#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */

#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
#if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
/* The bits in the two byte IP header field that make up the fragment offset value. */
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0xff1fU )
/* The bits in the two byte IP header field that make up the flags value. */
#define ipFRAGMENT_FLAGS_BIT_MASK ( ( uint16_t ) 0x00e0U )
/* Don't Fragment Flag */
#define ipFRAGMENT_FLAGS_DONT_FRAGMENT ( ( uint16_t ) 0x0040U )
/* More Fragments Flag */
#define ipFRAGMENT_FLAGS_MORE_FRAGMENTS ( ( uint16_t ) 0x0020U )
#else
/* The bits in the two byte IP header field that make up the fragment offset value. */
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x1fffU )
/* The bits in the two byte IP header field that make up the flags value. */
#define ipFRAGMENT_FLAGS_BIT_MASK ( ( uint16_t ) 0xe000U )
/* Don't Fragment Flag */
#define ipFRAGMENT_FLAGS_DONT_FRAGMENT ( ( uint16_t ) 0x4000U )
/* More Fragments Flag */
#define ipFRAGMENT_FLAGS_MORE_FRAGMENTS ( ( uint16_t ) 0x2000U )
#endif /* ipconfigBYTE_ORDER */
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */

/* For convenience, a MAC address of all zeros and another of all 0xffs are
* defined const for quick reference. */
Expand Down