IP forwarding: Flesh out TCP, UDP, and ICMPv6 packet forwarding logic.

This commit is contained in:
Gregory Nutt
2017-07-05 11:01:16 -06:00
parent 65c3fa6375
commit 31f832d8c5
20 changed files with 1102 additions and 162 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ endif
ifeq ($(CONFIG_NET_IPFORWARD),y)
ifeq ($(CONFIG_NETDEV_MULTINIC),y)
NET_CSRCS += ip_forward.c
NET_CSRCS += ip_forward.c devif_forward.c
endif
endif
+102
View File
@@ -0,0 +1,102 @@
/****************************************************************************
* net/devif/devif_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/net/netdev.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: devif_forward
*
* Description:
* Called from protocol-specific IP forwarding logic to re-send a packet.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
void devif_forward(FAR struct forward_s *fwd)
{
unsigned int offset;
int ret;
DEBUGASSERT(fwd != NULL && fwd->f_dev != NULL);
offset = NET_LL_HDRLEN(fwd->f_dev);
/* Copy the saved L2 + L3 header */
DEBUGASSERT(offset + fwd->f_hdrsize <= NET_DEV_MTU(fwd->f_dev));
memcpy(&fwd->f_dev->d_buf[offset], &fwd->f_hdr, fwd->f_hdrsize);
offset += fwd->f_hdrsize;
/* Copy the IOB chain that contains the payload */
if (fwd->f_iob != NULL && fwd->f_iob->io_pktlen > 0)
{
DEBUGASSERT(offset + fwd->f_iob->io_pktlen <= NET_DEV_MTU(fwd->f_dev));
ret = iob_copyout(&fwd->f_dev->d_buf[offset], fwd->f_iob,
fwd->f_iob->io_pktlen, 0);
DEBUGASSERT(ret == fwd->f_iob->io_pktlen);
offset += fwd->f_iob->io_pktlen;
}
fwd->f_dev->d_sndlen = offset;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NETDEV_MULTINIC */
-28
View File
@@ -48,34 +48,6 @@
#ifdef CONFIG_MM_IOB
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Constant Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
+2 -29
View File
@@ -47,33 +47,7 @@
#include <nuttx/net/netdev.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Constant Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#include "devif/devif.h"
/****************************************************************************
* Public Functions
@@ -87,8 +61,7 @@
* the network interface driver.
*
* Assumptions:
* Called from the interrupt level or, at a minimum, with interrupts
* disabled.
* The network is locked.
*
****************************************************************************/
+54 -12
View File
@@ -49,6 +49,10 @@
#include <nuttx/net/tcp.h>
#include <nuttx/net/icmpv6.h>
#include "udp/udp.h"
#include "tcp/tcp.h"
#include "icmpv6/icmpv6.h"
#undef HAVE_FWDALLOC
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NETDEV_MULTINIC)
@@ -69,7 +73,7 @@
/* IPv4 + L2 header */
#ifdef CONFIG_NET_IPv4
struct ipv6_fwdhdr_s
struct fwd_ipv4hdr_u
{
struct ipv4_hdr_s l2;
union
@@ -91,7 +95,7 @@ struct ipv6_fwdhdr_s
/* IPv6 + L2 header */
#ifdef CONFIG_NET_IPv6
struct ipv6_fwdhdr_s
struct fwd_ipv6hdr_u
{
struct ipv6_hdr_s l2;
union
@@ -112,28 +116,46 @@ struct ipv6_fwdhdr_s
/* IPv4 or IPv6 + L2 header */
union ip_fwdhdr_u
union fwd_iphdr_u
{
#ifdef CONFIG_NET_IPv4
struct ipv4_fwdhdr_s ipv4;
struct fwd_ipv4hdr_u ipv4;
#endif
#ifdef CONFIG_NET_IPv6
struct ipv6_fwdhdr_s ipv6;
struct fwd_ipv6hdr_u ipv6;
#endif
};
/* Connection structures */
union fwd_conn_u
{
#ifdef CONFIG_NET_TCP
struct tcp_conn_s tcp;
#endif
#ifdef CONFIG_NET_UDP
struct udp_conn_s udp;
#endif
#ifdef CONFIG_NET_ICMPv6
struct icmpv6_conn_s icmpv6;
#endif
};
/* This is the send state structure */
struct net_driver_s; /* Forward reference */
struct iob_s; /* Forward reference */
struct devif_callback_s; /* Forward refernce */
struct net_driver_s; /* Forward reference */
struct iob_s; /* Forward reference */
struct forward_s
{
FAR struct forward_s *f_flink; /* Supports a singly linked list */
FAR struct net_driver_s *f_dev; /* Forwarding device */
FAR struct iob_s *f_iob; /* IOBs containing the data payload */
union ip_fwdhdr_u f_hdr; /* Copy of original L2+L3 headers */
uint8_t f_hdrsize; /* The size of the L2+L3 headers */
FAR struct forward_s *f_flink; /* Supports a singly linked list */
FAR struct net_driver_s *f_dev; /* Forwarding device */
FAR struct iob_s *f_iob; /* IOBs containing the data payload */
FAR struct devif_callback_s *f_cb; /* Reference to callback instance */
union fwd_iphdr_u f_hdr; /* Copy of original L2+L3 headers */
union fwd_conn_u f_conn; /* Protocol-specific connectin struct */
uint8_t f_hdrsize; /* The size of the L2+L3 headers */
};
/****************************************************************************
@@ -182,5 +204,25 @@ FAR struct forward_s *ip_forward_alloc(void);
void ip_forward_free(FAR struct forward_s *fwd);
/****************************************************************************
* Name: devif_forward
*
* Description:
* Called from protocol-specific IP forwarding logic to re-send a packet.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
void devif_forward(FAR struct forward_s *fwd);
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NETDEV_MULTINIC */
#endif /* __NET_DEVIF_IP_FORWARD_H */
+33 -8
View File
@@ -225,6 +225,17 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
FAR uint8_t *payload;
unsigned int paysize;
/* Verify that the full packet will fit within the forwarding devices
* MTU. We provide no support for fragmenting forwarded packets.
*/
if (NET_LL_HDRLEN(fwddev) + dev->d_len > NET_DEV_MTU(fwddev))
{
nwarn("WARNING: Packet > MTU... Dropping\n");
ret = -EFBIG;
goto errout;
}
/* Get a pre-allocated forwarding structure, This structure will be
* completely zeroed when we receive it.
*/
@@ -246,6 +257,10 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
*
* Remember that the size of the L1 header has already been subtracted
* from dev->d_len.
*
* REVISIT: Consider an alternative design that does not require data
* copying. This would require a pool of d_buf's that are managed by
* the network rather than the network device.
*/
hdrsize = ipv6_hdrsize(ipv6);
@@ -258,7 +273,7 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
/* Save the entire L2 and L3 headers in the state structure */
if (hdrsize > sizeof(union ip_fwdhdr_u))
if (hdrsize > sizeof(union fwd_iphdr_u))
{
nwarn("WARNING: Header is too big for pre-allocated structure\n");
ret = -E2BIG;
@@ -278,7 +293,12 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
payload = (FAR uint8_t *)ipv6 + hdrsize;
paysize = dev->d_len - hdrsize;
/* If there is a payload, then copy it into an IOB chain */
/* If there is a payload, then copy it into an IOB chain.
*
* REVISIT: Consider an alternative design that does not require data
* copying. This would require a pool of d_buf's that are managed by
* the network rather than the network device.
*/
if (paysize > 0)
{
@@ -308,16 +328,21 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
}
}
/* Then set up to forward the packet according to the protocol */
/* Then set up to forward the packet according to the protocol.
*
* REVISIT: Are these protocol specific forwarders necessary? I think
* that this could be done with a single forwarding function for all
* protocols.
*/
switch (ipv6->proto)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
{
/* Forward a TCP packet, handling ACKs, windowing, etc. */
/* Forward a TCP packet. */
ret = tcp_ipv6_dev_forward(fwd);
ret = tcp_forward(fwd);
}
break;
#endif
@@ -327,7 +352,7 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
{
/* Forward a UDP packet */
ret = udp_ipv6_dev_forward(fwd);
ret = udp_forward(fwd);
}
break;
#endif
@@ -337,7 +362,7 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
{
/* Forward an ICMPv6 packet */
ret = icmpv6_dev_forward(fwd);
ret = icmpv6_forward(fwd);
}
break;
#endif
@@ -428,7 +453,7 @@ static int ipv6_decr_ttl(FAR struct ipv6_hdr_s *ipv6)
* Name: ipv6_dropstats
*
* Description:
* Update statistics for a droped packet.
* Update statistics for a dropped packet.
*
* Input Parameters:
* ipv6 - A convenience pointer to the IPv6 header in within the IPv6