Skip to content

Commit 222a36d

Browse files
The new loopback network interface (#1022)
Co-authored-by: Tony Josi <[email protected]>
1 parent ce7b689 commit 222a36d

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* FreeRTOS+TCP V2.3.1
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
* this software and associated documentation files (the "Software"), to deal in
7+
* the Software without restriction, including without limitation the rights to
8+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
* the Software, and to permit persons to whom the Software is furnished to do so,
10+
* subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in all
13+
* copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*
22+
* http://aws.amazon.com/freertos
23+
* http://www.FreeRTOS.org
24+
*/
25+
26+
/* Standard includes. */
27+
#include <stdint.h>
28+
#include <stdio.h>
29+
#include <stdlib.h>
30+
31+
/* FreeRTOS includes. */
32+
#include "FreeRTOS.h"
33+
#include "task.h"
34+
#include "queue.h"
35+
#include "semphr.h"
36+
37+
/* FreeRTOS+TCP includes. */
38+
#include "FreeRTOS_IP.h"
39+
#include "FreeRTOS_Sockets.h"
40+
#include "FreeRTOS_IP_Private.h"
41+
#include "FreeRTOS_DNS.h"
42+
#include "FreeRTOS_Routing.h"
43+
#include "FreeRTOS_ND.h"
44+
#include "NetworkBufferManagement.h"
45+
#include "NetworkInterface.h"
46+
47+
#if ( ipconfigUSE_LOOPBACK == 0 )
48+
#error Please define ipconfigUSE_LOOPBACK as 1 if you want to use the loop-back interface
49+
#endif
50+
51+
#define ipICMP_ECHO_REQUEST ( ( uint8_t ) 8 )
52+
#define ipICMP_ECHO_REPLY ( ( uint8_t ) 0 )
53+
54+
/*-----------------------------------------------------------*/
55+
56+
NetworkInterface_t * xLoopbackInterface;
57+
58+
static BaseType_t prvLoopback_Initialise( NetworkInterface_t * pxInterface );
59+
static BaseType_t prvLoopback_Output( NetworkInterface_t * pxInterface,
60+
NetworkBufferDescriptor_t * const pxGivenDescriptor,
61+
BaseType_t bReleaseAfterSend );
62+
static BaseType_t prvLoopback_GetPhyLinkStatus( NetworkInterface_t * pxInterface );
63+
64+
NetworkInterface_t * pxLoopback_FillInterfaceDescriptor( BaseType_t xEMACIndex,
65+
NetworkInterface_t * pxInterface );
66+
67+
/*-----------------------------------------------------------*/
68+
69+
static BaseType_t prvLoopback_Initialise( NetworkInterface_t * pxInterface )
70+
{
71+
/* When returning non-zero, the stack will become active and
72+
* start DHCP (in configured) */
73+
( void ) pxInterface;
74+
return pdTRUE;
75+
}
76+
/*-----------------------------------------------------------*/
77+
78+
#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 )
79+
80+
/* Do not call the following function directly. It is there for downward compatibility.
81+
* The function FreeRTOS_IPInit() will call it to initialice the interface and end-point
82+
* objects. See the description in FreeRTOS_Routing.h. */
83+
NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex,
84+
NetworkInterface_t * pxInterface )
85+
{
86+
pxLoopback_FillInterfaceDescriptor( xEMACIndex, pxInterface );
87+
}
88+
89+
#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */
90+
/*-----------------------------------------------------------*/
91+
92+
NetworkInterface_t * pxLoopback_FillInterfaceDescriptor( BaseType_t xEMACIndex,
93+
NetworkInterface_t * pxInterface )
94+
{
95+
/* This function pxLoopback_FillInterfaceDescriptor() adds a network-interface.
96+
* Make sure that the object pointed to by 'pxInterface'
97+
* is declared static or global, and that it will remain to exist. */
98+
99+
memset( pxInterface, '\0', sizeof( *pxInterface ) );
100+
pxInterface->pcName = "Loopback"; /* Just for logging, debugging. */
101+
pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */
102+
pxInterface->pfInitialise = prvLoopback_Initialise;
103+
pxInterface->pfOutput = prvLoopback_Output;
104+
pxInterface->pfGetPhyLinkStatus = prvLoopback_GetPhyLinkStatus;
105+
106+
FreeRTOS_AddNetworkInterface( pxInterface );
107+
xLoopbackInterface = pxInterface;
108+
109+
return pxInterface;
110+
}
111+
/*-----------------------------------------------------------*/
112+
113+
static BaseType_t prvLoopback_GetPhyLinkStatus( NetworkInterface_t * pxInterface )
114+
{
115+
/* This function returns true if the Link Status in the PHY is high. */
116+
( void ) pxInterface;
117+
return pdTRUE;
118+
}
119+
/*-----------------------------------------------------------*/
120+
121+
static BaseType_t prvLoopback_Output( NetworkInterface_t * pxInterface,
122+
NetworkBufferDescriptor_t * const pxGivenDescriptor,
123+
BaseType_t bReleaseAfterSend )
124+
{
125+
NetworkBufferDescriptor_t * pxDescriptor = pxGivenDescriptor;
126+
127+
( void ) pxInterface;
128+
129+
IPPacket_t * a = ( IPPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
130+
131+
if( a->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
132+
{
133+
usGenerateProtocolChecksum( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, pdTRUE );
134+
}
135+
136+
{
137+
MACAddress_t xMACAddress;
138+
139+
if( pxDescriptor->pxEndPoint->bits.bIPv6 != 0 )
140+
{
141+
#if ( ipconfigUSE_IPv6 != 0 )
142+
if( xIsIPv6Loopback( &( pxDescriptor->xIPAddress ) ) != pdFALSE )
143+
{
144+
vNDRefreshCacheEntry( &xMACAddress, &( pxDescriptor->xIPAddress.xIP_IPv6 ), pxDescriptor->pxEndPoint );
145+
}
146+
#endif
147+
}
148+
else
149+
{
150+
#if ( ipconfigUSE_IPv4 != 0 )
151+
if( xIsIPv4Loopback( pxDescriptor->xIPAddress.ulIP_IPv4 ) )
152+
{
153+
vARPRefreshCacheEntry( &xMACAddress, pxDescriptor->xIPAddress.ulIP_IPv4, pxDescriptor->pxEndPoint );
154+
}
155+
#endif
156+
}
157+
}
158+
159+
if( bReleaseAfterSend == pdFALSE )
160+
{
161+
NetworkBufferDescriptor_t * pxNewDescriptor =
162+
pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, pxDescriptor->xDataLength );
163+
pxDescriptor = pxNewDescriptor;
164+
}
165+
166+
if( pxDescriptor != NULL )
167+
{
168+
IPStackEvent_t xRxEvent;
169+
170+
xRxEvent.eEventType = eNetworkRxEvent;
171+
xRxEvent.pvData = ( void * ) pxDescriptor;
172+
173+
if( xSendEventStructToIPTask( &xRxEvent, 0u ) != pdTRUE )
174+
{
175+
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
176+
iptraceETHERNET_RX_EVENT_LOST();
177+
FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
178+
}
179+
}
180+
181+
/* The return value is actually ignored by the IP-stack. */
182+
return pdTRUE;
183+
}
184+
/*-----------------------------------------------------------*/

0 commit comments

Comments
 (0)