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

ARP/ND Build Separation #1175

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d70ec50
Separate ARP and ND
HTRamsey Feb 9, 2024
030d4b2
Merge branch 'main' into dev-ip-build-sep
HTRamsey Feb 9, 2024
4ec6783
Uncrustify: triggered by comment.
actions-user Feb 9, 2024
bb4df6e
Merge branch 'main' into dev-ip-build-sep
HTRamsey Feb 10, 2024
d151490
Fix merge conflicts wrt to PR#1105 & Merge branch 'main' of github.co…
tony-josi-aws Mar 18, 2024
aa86354
Fully separate ARP & ND
HTRamsey Mar 20, 2024
f74834e
Merge branch 'main' into dev-ip-build-sep
HTRamsey Mar 20, 2024
4558cf1
Merge branch 'dev-ip-build-sep' of https://github.com/HTRamsey/FreeRT…
HTRamsey Mar 20, 2024
4547473
Merge branch 'main' into dev-ip-build-sep
HTRamsey Apr 22, 2024
8238b6f
Fix tracing and config macros
HTRamsey Apr 22, 2024
afd4666
Fix Build Issues
HTRamsey Apr 22, 2024
9d5ec49
Changed resolution enum name
HTRamsey Aug 1, 2024
c43498d
Merge branch 'main' into dev-ip-build-sep
HTRamsey Aug 1, 2024
bf49f4f
Add ND Timer event implementation
HTRamsey Aug 1, 2024
6a8b501
Uncrustify: triggered by comment.
actions-user Aug 3, 2024
973fbc4
Fix Tests
HTRamsey Aug 25, 2024
d5474ee
Merge branch 'main' into dev-ip-build-sep
HTRamsey Sep 19, 2024
dd1f80b
Fix Unit Tests
HTRamsey Sep 19, 2024
5fc03b7
Uncrustify: triggered by comment.
actions-user Sep 25, 2024
d93e085
Merge branch 'main' into dev-ip-build-sep
ActoryOu Oct 1, 2024
50d9833
Merge branch 'main' into dev-ip-build-sep
ActoryOu Oct 1, 2024
0f744c8
Merge branch 'main' into dev-ip-build-sep
tony-josi-aws Oct 10, 2024
8af0a42
Fix CBMC testing
ActoryOu Oct 16, 2024
5e842c6
Fix ARP utest
ActoryOu Oct 17, 2024
698f2c3
Code review suggestion
ActoryOu Oct 17, 2024
3fee861
In unit-test, define ipconfigIS_ENABLED to nothing to pass compilation.
ActoryOu Oct 17, 2024
341d974
Fix UT coverage.
ActoryOu Oct 17, 2024
145eaac
Fix buffer access issue in UT.
ActoryOu Oct 17, 2024
be8b4f9
Fix spelling
ActoryOu Oct 17, 2024
1245cb7
100% UT coverage
ActoryOu Oct 18, 2024
9e9b29f
Merge branch 'main' into dev-ip-build-sep
ActoryOu Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/.cSpellWords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@ STLIDMPUSR
STLIMPUOR
STLNVICACTVOR
STLNVICPENDOR
Storex
strbt
STRBT
strexb
Expand Down
829 changes: 366 additions & 463 deletions source/FreeRTOS_ARP.c

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion source/FreeRTOS_DHCP.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,6 @@
/* DHCP failed, the default configured IP-address will be used. Now
* call vIPNetworkUpCalls() to send the network-up event and start the ARP
* timer. */

vIPNetworkUpCalls( pxEndPoint );

/* Close socket to ensure packets don't queue on it. */
Expand Down
11 changes: 3 additions & 8 deletions source/FreeRTOS_DHCPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,12 @@
#include "FreeRTOS_DHCPv6.h"
#include "FreeRTOS_DNS.h"
#include "NetworkBufferManagement.h"
#include "FreeRTOS_ARP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_IP_Timers.h"

#include "FreeRTOS_BitConfig.h"

#include "FreeRTOS_Routing.h"

#include "FreeRTOS_ND.h"

/* Timer parameters */
#ifndef dhcpINITIAL_DHCP_TX_PERIOD
/** @brief DHCP timer period in ms */
Expand Down Expand Up @@ -531,7 +526,7 @@ static void vDHCPv6ProcessEndPoint_HandleReply( NetworkEndPoint_t * pxEndPoint,

/* DHCP failed, the default configured IP-address will be used
* Now call vIPNetworkUpCalls() to send the network-up event and
* start the ARP timer. */
* start the Address Resolution timer. */
vIPNetworkUpCalls( pxEndPoint );
}
/*-----------------------------------------------------------*/
Expand Down Expand Up @@ -823,8 +818,8 @@ static void vDHCPv6ProcessEndPoint( BaseType_t xReset,
prvCloseDHCPv6Socket( pxEndPoint );

/* DHCP failed, the default configured IP-address will be used. Now
* call vIPNetworkUpCalls() to send the network-up event and start the ARP
* timer. */
* call vIPNetworkUpCalls() to send the network-up event and start the
* Address Resolution timer. */
vIPNetworkUpCalls( pxEndPoint );
}
}
Expand Down
1 change: 0 additions & 1 deletion source/FreeRTOS_ICMP.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_ICMP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_ARP.h"
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_DHCP.h"
#include "NetworkInterface.h"
Expand Down
166 changes: 119 additions & 47 deletions source/FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_ARP.h"
#include "FreeRTOS_ND.h"
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_DHCP.h"
#if ( ipconfigUSE_DHCPv6 == 1 )
Expand All @@ -58,12 +59,12 @@
#include "NetworkBufferManagement.h"
#include "FreeRTOS_DNS.h"
#include "FreeRTOS_Routing.h"
#include "FreeRTOS_ND.h"

/** @brief Time delay between repeated attempts to initialise the network hardware. */
#ifndef ipINITIALISATION_RETRY_DELAY
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000U ) )
#endif

#if ( ipconfigUSE_TCP_MEM_STATS != 0 )
#include "tcp_mem_stats.h"
#endif
Expand All @@ -73,16 +74,12 @@
#define ipARP_RESOLUTION_MAX_DELAY ( pdMS_TO_TICKS( 2000U ) )
#endif

#ifndef iptraceIP_TASK_STARTING
#define iptraceIP_TASK_STARTING() do {} while( ipFALSE_BOOL ) /**< Empty definition in case iptraceIP_TASK_STARTING is not defined. */
#endif

#if ( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
/** @brief When initialising the TCP timer, give it an initial time-out of 1 second. */
#define ipTCP_TIMER_PERIOD_MS ( 1000U )
/** @brief Maximum time to wait for a ND resolution while holding a packet. */
#ifndef ipND_RESOLUTION_MAX_DELAY
#define ipND_RESOLUTION_MAX_DELAY ( pdMS_TO_TICKS( 2000U ) )
#endif

/** @brief Defines how often the ARP timer callback function is executed. The time is
/** @brief Defines how often the ARP resolution timer callback function is executed. The time is
* shorter in the Windows simulator as simulated time is not real time. */
#ifndef ipARP_TIMER_PERIOD_MS
#ifdef _WINDOWS_
Expand All @@ -92,6 +89,25 @@
#endif
#endif

/** @brief Defines how often the ND resolution timer callback function is executed. The time is
* shorter in the Windows simulator as simulated time is not real time. */
#ifndef ipND_TIMER_PERIOD_MS
#ifdef _WINDOWS_
#define ipND_TIMER_PERIOD_MS ( 500U ) /* For windows simulator builds. */
#else
#define ipND_TIMER_PERIOD_MS ( 10000U )
#endif
#endif

#if ( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
/** @brief When initialising the TCP timer, give it an initial time-out of 1 second. */
#define ipTCP_TIMER_PERIOD_MS ( 1000U )
#endif

#ifndef iptraceIP_TASK_STARTING
#define iptraceIP_TASK_STARTING() do {} while( ipFALSE_BOOL ) /**< Empty definition in case iptraceIP_TASK_STARTING is not defined. */
#endif

/** @brief The frame type field in the Ethernet header must have a value greater than 0x0600.
* If the configuration option ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is enabled, the stack
* will discard packets with a frame type value less than or equal to 0x0600.
Expand All @@ -107,7 +123,14 @@ static void prvIPTask_CheckPendingEvents( void );
/*-----------------------------------------------------------*/

/** @brief The pointer to buffer with packet waiting for ARP resolution. */
NetworkBufferDescriptor_t * pxARPWaitingNetworkBuffer = NULL;
#if ipconfigIS_ENABLED( ipconfigUSE_IPv4 )
NetworkBufferDescriptor_t * pxARPWaitingNetworkBuffer = NULL;
#endif

/** @brief The pointer to buffer with packet waiting for ND resolution. */
#if ipconfigIS_ENABLED( ipconfigUSE_IPv6 )
NetworkBufferDescriptor_t * pxNDWaitingNetworkBuffer = NULL;
#endif

/*-----------------------------------------------------------*/

Expand Down Expand Up @@ -238,7 +261,7 @@ static void prvProcessIPEventsAndTimers( void )

ipconfigWATCHDOG_TIMER();

/* Check the ARP, DHCP and TCP timers to see if there is any periodic
/* Check the Resolution, DHCP and TCP timers to see if there is any periodic
* or timeout processing to perform. */
vCheckNetworkTimers();

Expand Down Expand Up @@ -294,15 +317,17 @@ static void prvProcessIPEventsAndTimers( void )
break;

case eARPTimerEvent:
/* The ARP timer has expired, process the ARP cache. */
#if ( ipconfigUSE_IPv4 != 0 )
/* The ARP Resolution timer has expired, process the cache. */
#if ipconfigIS_ENABLED( ipconfigUSE_IPv4 )
vARPAgeCache();
#endif /* ( ipconfigUSE_IPv4 != 0 ) */
break;

#if ( ipconfigUSE_IPv6 != 0 )
case eNDTimerEvent:
/* The ND Resolution timer has expired, process the cache. */
#if ipconfigIS_ENABLED( ipconfigUSE_IPv6 )
vNDAgeCache();
#endif /* ( ipconfigUSE_IPv6 != 0 ) */

break;

case eSocketBindEvent:
Expand Down Expand Up @@ -493,8 +518,15 @@ static void prvIPTask_Initialise( void )
}
#endif

/* Mark the timer as inactive since we are not waiting on any ARP resolution as of now. */
vIPSetARPResolutionTimerEnableState( pdFALSE );
#if ipconfigIS_ENABLED( ipconfigUSE_IPv4 )
/* Mark the ARP timer as inactive since we are not waiting on any resolution as of now. */
vIPSetARPResolutionTimerEnableState( pdFALSE );
#endif

#if ipconfigIS_ENABLED( ipconfigUSE_IPv6 )
/* Mark the ND timer as inactive since we are not waiting on any resolution as of now. */
vIPSetNDResolutionTimerEnableState( pdFALSE );
#endif

#if ( ( ipconfigDNS_USE_CALLBACKS != 0 ) && ( ipconfigUSE_DNS != 0 ) )
{
Expand Down Expand Up @@ -648,7 +680,18 @@ void vIPNetworkUpCalls( struct xNetworkEndPoint * pxEndPoint )
#endif /* ipconfigDNS_USE_CALLBACKS != 0 */

/* Set remaining time to 0 so it will become active immediately. */
vARPTimerReload( pdMS_TO_TICKS( ipARP_TIMER_PERIOD_MS ) );
if( pxEndPoint->bits.bIPv6 == pdTRUE_UNSIGNED )
{
#if ipconfigIS_ENABLED( ipconfigUSE_IPv6 )
vNDTimerReload( pdMS_TO_TICKS( ipND_TIMER_PERIOD_MS ) );
#endif
}
else
{
#if ipconfigIS_ENABLED( ipconfigUSE_IPv4 )
vARPTimerReload( pdMS_TO_TICKS( ipARP_TIMER_PERIOD_MS ) );
#endif
}
}
/*-----------------------------------------------------------*/

Expand Down Expand Up @@ -1718,7 +1761,7 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
case eReturnEthernetFrame:

/* The Ethernet frame will have been updated (maybe it was
* an ARP request or a PING request?) and should be sent back to
* a resolution request or a PING request?) and should be sent back to
* its source. */
vReturnEthernetFrame( pxNetworkBuffer, pdTRUE );

Expand All @@ -1732,22 +1775,51 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
* yet. */
break;

case eWaitingARPResolution:
case eWaitingResolution:
ActoryOu marked this conversation as resolved.
Show resolved Hide resolved

if( pxARPWaitingNetworkBuffer == NULL )
{
pxARPWaitingNetworkBuffer = pxNetworkBuffer;
vIPTimerStartARPResolution( ipARP_RESOLUTION_MAX_DELAY );
#if ipconfigIS_ENABLED( ipconfigUSE_IPv4 )
if( ( pxEthernetHeader->usFrameType == ipIPv4_FRAME_TYPE ) || ( pxEthernetHeader->usFrameType == ipARP_FRAME_TYPE ) )
{
if( pxARPWaitingNetworkBuffer == NULL )
{
pxARPWaitingNetworkBuffer = pxNetworkBuffer;
vIPTimerStartARPResolution( ipARP_RESOLUTION_MAX_DELAY );

iptraceDELAYED_ARP_REQUEST_STARTED();
}
else
{
/* We are already waiting on one ARP resolution. This frame will be dropped. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
iptraceDELAYED_ARP_REQUEST_STARTED();
}
else
{
/* We are already waiting on one resolution. This frame will be dropped. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );

iptraceDELAYED_ARP_BUFFER_FULL();
}
iptraceDELAYED_ARP_BUFFER_FULL();
}

break;
}
#endif /* if ipconfigIS_ENABLED( ipconfigUSE_IPv4 ) */

#if ipconfigIS_ENABLED( ipconfigUSE_IPv6 )
if( pxEthernetHeader->usFrameType == ipIPv6_FRAME_TYPE )
{
if( pxNDWaitingNetworkBuffer == NULL )
{
pxNDWaitingNetworkBuffer = pxNetworkBuffer;
vIPTimerStartNDResolution( ipND_RESOLUTION_MAX_DELAY );

iptraceDELAYED_ND_REQUEST_STARTED();
}
else
{
/* We are already waiting on one resolution. This frame will be dropped. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );

iptraceDELAYED_ND_BUFFER_FULL();
}

break;
}
#endif /* if ipconfigIS_ENABLED( ipconfigUSE_IPv6 ) */

break;

Expand Down Expand Up @@ -1775,7 +1847,7 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
static eFrameProcessingResult_t prvProcessUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
eFrameProcessingResult_t eReturn = eReleaseBuffer;
BaseType_t xIsWaitingARPResolution = pdFALSE;
BaseType_t xIsWaitingResolution = pdFALSE;
/* The IP packet contained a UDP frame. */
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
Expand Down Expand Up @@ -1847,16 +1919,16 @@ static eFrameProcessingResult_t prvProcessUDPPacket( NetworkBufferDescriptor_t *
* implementation. */
if( xProcessReceivedUDPPacket( pxNetworkBuffer,
pxUDPHeader->usDestinationPort,
&( xIsWaitingARPResolution ) ) == pdPASS )
&( xIsWaitingResolution ) ) == pdPASS )
{
eReturn = eFrameConsumed;
}
else
{
/* Is this packet to be set aside for ARP resolution. */
if( xIsWaitingARPResolution == pdTRUE )
/* Is this packet to be set aside for resolution. */
if( xIsWaitingResolution == pdTRUE )
{
eReturn = eWaitingARPResolution;
eReturn = eWaitingResolution;
}
}
}
Expand Down Expand Up @@ -2014,21 +2086,21 @@ static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * pxIPPacke
/* coverity[const] */
if( eReturn != eReleaseBuffer )
{
/* Add the IP and MAC addresses to the ARP table if they are not
/* Add the IP and MAC addresses to the cache if they are not
* already there - otherwise refresh the age of the existing
* entry. */
if( ucProtocol != ( uint8_t ) ipPROTOCOL_UDP )
{
if( xCheckRequiresARPResolution( pxNetworkBuffer ) == pdTRUE )
if( xCheckRequiresResolution( pxNetworkBuffer ) == pdTRUE )
{
eReturn = eWaitingARPResolution;
eReturn = eWaitingResolution;
}
else
{
/* Refresh the ARP cache with the IP/MAC-address of the received
/* Refresh the cache with the IP/MAC-address of the received
* packet. For UDP packets, this will be done later in
* xProcessReceivedUDPPacket(), as soon as it's know that the message
* will be handled. This will prevent the ARP cache getting
* will be handled. This will prevent the cache getting
* overwritten with the IP address of useless broadcast packets. */
/* Case default is never toggled because eReturn is not eProcessBuffer in previous step. */
switch( pxIPPacket->xEthernetHeader.usFrameType ) /* LCOV_EXCL_BR_LINE */
Expand All @@ -2054,7 +2126,7 @@ static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * pxIPPacke
}
}

if( eReturn != eWaitingARPResolution )
if( eReturn != eWaitingResolution )
{
switch( ucProtocol )
{
Expand Down Expand Up @@ -2171,7 +2243,7 @@ void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer,

#if ( ipconfigUSE_IPv4 != 0 )
MACAddress_t xMACAddress;
eARPLookupResult_t eResult;
eResolutionLookupResult_t eResult;
uint32_t ulDestinationIPAddress = 0U;
#endif /* ( ipconfigUSE_IPv4 != 0 ) */

Expand Down Expand Up @@ -2219,7 +2291,7 @@ void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer,
* address. */
eResult = eARPGetCacheEntry( &ulDestinationIPAddress, &xMACAddress, &( pxNetworkBuffer->pxEndPoint ) );

if( eResult == eARPCacheHit )
if( eResult == eResolutionCacheHit )
{
/* Best case scenario - an address is found, use it. */
pvCopySource = &xMACAddress;
Expand All @@ -2235,7 +2307,7 @@ void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer,
case ipIPv6_FRAME_TYPE:
case ipARP_FRAME_TYPE:
default:
/* In case of ARP frame, just swap the source and destination MAC addresses. */
/* Just swap the source and destination MAC addresses. */
pvCopySource = &( pxIPPacket->xEthernetHeader.xSourceAddress );
break;
}
Expand All @@ -2262,7 +2334,7 @@ void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer,
{
IPStackEvent_t xSendEvent;

/* Send a message to the IP-task to send this ARP packet. */
/* Send a message to the IP-task to send this packet. */
xSendEvent.eEventType = eNetworkTxEvent;
xSendEvent.pvData = pxNetworkBuffer;

Expand Down
Loading
Loading