Skip to content

Commit

Permalink
Merge branch 'main' of github.com:FreeRTOS/FreeRTOS-Plus-TCP into v4.…
Browse files Browse the repository at this point in the history
…1.0_bugfixes
  • Loading branch information
tony-josi-aws committed Feb 14, 2024
2 parents 695c90e + a87f489 commit 7e05630
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 20 deletions.
43 changes: 33 additions & 10 deletions source/FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,10 @@ static void prvHandleEthernetPacket( NetworkBufferDescriptor_t * pxBuffer )
/* When ipconfigUSE_LINKED_RX_MESSAGES is set to 0 then only one
* buffer will be sent at a time. This is the default way for +TCP to pass
* messages from the MAC to the TCP/IP stack. */
prvProcessEthernetPacket( pxBuffer );
if( pxBuffer != NULL )
{
prvProcessEthernetPacket( pxBuffer );
}
}
#else /* ipconfigUSE_LINKED_RX_MESSAGES */
{
Expand Down Expand Up @@ -1542,15 +1545,35 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
const EthernetHeader_t * pxEthernetHeader;
eFrameProcessingResult_t eReturned = eReleaseBuffer;

configASSERT( pxNetworkBuffer != NULL );
configASSERT( pxNetworkBuffer->pxInterface != NULL );
/* From here on, all incoming packet processing can rely on all of the above non-NULL */
/* Use do{}while(pdFALSE) to allow the use of break; */
do
{
/* prvHandleEthernetPacket() already checked for ( pxNetworkBuffer != NULL ) so
* it is safe to break out of the do{}while() and let the second half of this
* function handle the releasing of pxNetworkBuffer */

iptraceNETWORK_INTERFACE_INPUT( pxNetworkBuffer->xDataLength, pxNetworkBuffer->pucEthernetBuffer );
if( ( pxNetworkBuffer->pxInterface == NULL ) || ( pxNetworkBuffer->pxEndPoint == NULL ) )
{
break;
}

/* Beyond this point,
* ( pxNetworkBuffer != NULL ),
* ( pxNetworkBuffer->pxInterface != NULL ),
* ( pxNetworkBuffer->pxEndPoint != NULL ),
* Additionally, FreeRTOS_FillEndPoint() and FreeRTOS_FillEndPoint_IPv6() guarantee
* that endpoints always have a valid interface assigned to them, and consequently:
* ( pxNetworkBuffer->pxEndPoint->pxInterface != NULL )
* None of the above need to be checked again in code that handles incoming packets. */

iptraceNETWORK_INTERFACE_INPUT( pxNetworkBuffer->xDataLength, pxNetworkBuffer->pucEthernetBuffer );

/* Interpret the Ethernet frame. */
if( pxNetworkBuffer->xDataLength < sizeof( EthernetHeader_t ) )
{
break;
}

/* Interpret the Ethernet frame. */
if( ( pxNetworkBuffer->pxEndPoint != NULL ) && ( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) ) )
{
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );

/* Map the buffer onto the Ethernet Header struct for easy access to the fields. */
Expand Down Expand Up @@ -1613,9 +1636,9 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
eReturned = eReleaseBuffer;
#endif
break;
}
} /* switch( pxEthernetHeader->usFrameType ) */
}
}
} while( pdFALSE );

/* Perform any actions that resulted from processing the Ethernet frame. */
switch( eReturned )
Expand Down
46 changes: 36 additions & 10 deletions test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ void test_prvProcessIPEventsAndTimers_eNetworkRxEventNULL( void )
xQueueReceive_ExpectAnyArgsAndReturn( pdTRUE );
xQueueReceive_ReturnMemThruPtr_pvBuffer( &xReceivedEvent, sizeof( xReceivedEvent ) );

catch_assert( prvProcessIPEventsAndTimers() );
prvProcessIPEventsAndTimers();
}

/**
Expand Down Expand Up @@ -680,6 +680,41 @@ void test_prvProcessIPEventsAndTimers_eNetworkTxEvent_NullInterface( void )
prvProcessIPEventsAndTimers();
}

/**
* @brief test_prvProcessIPEventsAndTimers_eNetworkRxEvent_NullEndPoint
* Check if prvProcessIPEventsAndTimers() skip receiving data through network interface
* when network endpoint pointer is NULL.
*/
void test_prvProcessIPEventsAndTimers_eNetworkRxEvent_NullEndPoint( void )
{
IPStackEvent_t xReceivedEvent;
NetworkEndPoint_t xEndPoints;
NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer;
uint8_t ucEthBuffer[ ipconfigTCP_MSS ];
struct xNetworkInterface xInterface;

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer;
pxNetworkBuffer->xDataLength = sizeof( EthernetHeader_t ) - 1;
pxNetworkBuffer->pxInterface = &xInterface;
pxNetworkBuffer->pxEndPoint = NULL;

NetworkInterfaceOutputFunction_Stub_Called = 0;

xReceivedEvent.eEventType = eNetworkRxEvent;
xReceivedEvent.pvData = pxNetworkBuffer;
xNetworkDownEventPending = pdFALSE;

/* prvProcessIPEventsAndTimers */
vCheckNetworkTimers_Expect();
xCalculateSleepTime_ExpectAndReturn( 0 );
xQueueReceive_ExpectAnyArgsAndReturn( pdTRUE );
xQueueReceive_ReturnMemThruPtr_pvBuffer( &xReceivedEvent, sizeof( xReceivedEvent ) );
vReleaseNetworkBufferAndDescriptor_Expect( pxNetworkBuffer );

prvProcessIPEventsAndTimers();
}

/**
* @brief test_prvProcessIPEventsAndTimers_eARPTimerEvent
* Check if prvProcessIPEventsAndTimers() updates the cache for ARP/ND when timeout event triggered.
Expand Down Expand Up @@ -1736,15 +1771,6 @@ void test_prvProcessEthernetPacket_NoData( void )
prvProcessEthernetPacket( pxNetworkBuffer );
}

/**
* @brief test_prvProcessEthernetPacket_NullNetworkBufferDescriptor
* To validate if prvProcessEthernetPacket triggers assertion when input is NULL.
*/
void test_prvProcessEthernetPacket_NullNetworkBufferDescriptor( void )
{
catch_assert( prvProcessEthernetPacket( NULL ) );
}

/**
* @brief test_prvProcessEthernetPacket_UnknownFrameType
* To validate if prvProcessEthernetPacket calls vReleaseNetworkBufferAndDescriptor
Expand Down

0 comments on commit 7e05630

Please sign in to comment.