heinbali01 wrote on Wednesday, April 19, 2017:
Hi Glen,
First some general information:
The IP-task sends all packets to Ethernet by calling this driver function:
BaseType_t xNetworkInterfaceOutput( pxDescriptor, t bReleaseAfterSend );
The IP-task receives Ethernet packets by receiving eNetworkRxEvent
messages in its queue ( xNetworkEventQueue
). A driver can send network buffers to that queue by calling xSendEventStructToIPTask()
.
Those are the two paths between +TCP and the Ethernet.
About ‘internal’ routing: the current implementation is simple:
- Every target that is within the netmask is contacted directly (using ARP look-up)
- Packets to other IP-addresses will be sent to the gateway, if any.
But every packet will finally be sent by the same xNetworkInterfaceOutput()
.
Now you want to route packets that come from your LAN, and forward them to a radio-connection and v.v., true?
prvProcessEthernetPacket()
and check if the dst addr is our addr or ‘the other end’
I think it’s a good place to forward packets!
prvProcessEthernetPacket()
will handle every packet that has been received by NetworkInterface.c
(i.e. from the LAN).
Something like the following ?
void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
EthernetHeader_t *pxEthernetHeader;
volatile eFrameProcessingResult_t eReturned;
configASSERT( pxNetworkBuffer );
+ if( xToMyRouter( pxNetworkBuffer ) )
+ {
+ /* The packet has bee forwarded to a router. */
+ eReturned = eFrameConsumed;
+ }
+ else
{
/* Interpret the Ethernet frame. */
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
}
if( eReturned == eProcessBuffer )
...
}
So if the function xToMyRouter()
handles / forwards the packet, it gets ownership of the network buffer ( call vReleaseNetworkBufferAndDescriptor()
after use ), and it must return a non-zero value. Do not block, just queue the network buffer, in order not to hold-up the IP-task.
If this approach turns out to be useful, we could make some permanent application hook here.
I suppose that you will also create a task that monitors / receives packets from the radio-connection.
We miss something here. You would like to call xNetworkInterfaceOutput()
directly to forward the packet to the LAN, true? But the code in NetworkInterface.c
assumes that the xNetworkInterfaceOutput()
function is non re-entrant.
The IP-task does not have a message type to forward a packet to the LAN. We could add that type of messages:
eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */
eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */
eARPTimerEvent, /* 2: The ARP timer expired. */
eStackTxEvent, /* 3: The software stack has queued a packet to transmit. */
+ eForwardTxPacketEvent, /* 4: Blindly forward a packet by passing it to xNetworkInterfaceOutput(). */
eDHCPEvent, /* 5: Process the DHCP state machine. */
/* And in prvIPTask() in FreeRTOS_IP.c */
switch( xReceivedEvent.eEventType )
{
...
case eForwardTxPacketEvent:
/* Set the `bReleaseAfterSend` parameter to true, to pass the ownership to the driver. */
xNetworkInterfaceOutput( ( NetworkBufferDescriptor_t * ) xReceivedEvent.pvData, pdTRUE );
break;
...
}
eStackTxEvent
is a bit misleading, it will only handle UDP-packets. It was added at the time when the library was still called +UDP 
Or you could change the implementation of xNetworkInterfaceOutput()
to become re-entrant.
I hope that I answered your question. Regards.