heinbali01 wrote on Wednesday, April 19, 2017:
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
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
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 )
volatile eFrameProcessingResult_t eReturned;
configASSERT( pxNetworkBuffer );
+ if( xToMyRouter( pxNetworkBuffer ) )
+ /* The packet has bee forwarded to a router. */
+ eReturned = eFrameConsumed;
/* 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 )
/* Set the `bReleaseAfterSend` parameter to true, to pass the ownership to the driver. */
xNetworkInterfaceOutput( ( NetworkBufferDescriptor_t * ) xReceivedEvent.pvData, pdTRUE );
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.