net/: Rename CONFIG_TCP_REASSEMBLY to CONFIG_IPv4_REASSEMBLY. Add some fixes to get a clen compile with CONFIG_IPv4_REASSEMBLY enabled. There are several problems with the current implementation: It is untested (and depends on CONFIG_EXPERMIMENTAL). It uses some Ethernet specific definitions (and depends on CONFIG_NET_ETHERNET). There is only a single reassembly buffer. The last two issues prevent use of this feature in any context where IPv4 packets may be reassembled for multiple network devices concurrently).
This commit is contained in:
parent
fe592d502c
commit
433f29eea2
33
net/Kconfig
33
net/Kconfig
@ -260,6 +260,39 @@ config NET_IPv4
|
||||
---help---
|
||||
Build in support for IPv4.
|
||||
|
||||
config NET_IPv4_REASSEMBLY
|
||||
bool "IPv4 reassembly"
|
||||
default n
|
||||
depends on NET_IPv4 && EXPERIMENTAL && NET_ETHERNET
|
||||
---help---
|
||||
Enable support for IP packet reassembly of fragmented IP packets.
|
||||
|
||||
This features requires an additional amount of RAM to hold a single
|
||||
reassembly buffer. The reassembly buffer is of the same size as the
|
||||
MTU of the selected device.
|
||||
|
||||
REVISIT: There are multiple issues with the current implementation:
|
||||
1. IPv4 reassembly in its current form is untested (and, hence,
|
||||
depends on CONFIG_EXPERIMENTAL).
|
||||
2. Currently this feature can only work with Ethernet due to internal
|
||||
definitions that depend on Ethernet configuration settings (and,
|
||||
hence, depends on CONFIG_NET_ETHERNET).
|
||||
3. Since there is only a single reassembly buffer, IPv4 reassembly
|
||||
cannot be used in a context where multiple network devices may be
|
||||
concurrently re-assemblying packets.
|
||||
|
||||
if NET_IPv4_REASSEMBLY
|
||||
|
||||
config NET_IPv4_REASS_MAXAGE
|
||||
int "IP fragment timeout"
|
||||
default 200
|
||||
---help---
|
||||
The maximum time an IP fragment should wait in the reassembly buffer
|
||||
before it is dropped. Units are deci-seconds, the range of the timer
|
||||
is 8-bits. Default: 20 seconds.
|
||||
|
||||
endif # NET_IPv4_REASSEMBLY
|
||||
|
||||
config NET_IPv6
|
||||
bool "IPv6"
|
||||
default n
|
||||
|
@ -289,7 +289,7 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_TCP_REASSEMBLY)
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
/* Reassembly timer (units: deci-seconds) */
|
||||
|
||||
EXTERN uint8_t g_reassembly_timer;
|
||||
|
@ -66,7 +66,7 @@ struct net_stats_s g_netstats;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_TCP_REASSEMBLY)
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
/* Reassembly timer (units: deci-seconds) */
|
||||
|
||||
uint8_t g_reassembly_timer;
|
||||
|
@ -737,11 +737,11 @@ int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
|
||||
|
||||
/* Perform periodic activitives that depend on hsec > 0 */
|
||||
|
||||
#if defined(CONFIG_NET_TCP_REASSEMBLY) && defined(CONFIG_NET_IPv4)
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
/* Increment the timer used by the IP reassembly logic */
|
||||
|
||||
if (g_reassembly_timer != 0 &&
|
||||
g_reassembly_timer < CONFIG_NET_TCP_REASS_MAXAGE)
|
||||
g_reassembly_timer < CONFIG_NET_IPv4_REASS_MAXAGE)
|
||||
{
|
||||
g_reassembly_timer += hsec;
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
* net/devif/ipv4_input.c
|
||||
* Device driver IPv4 packet receipt interface
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2013-2015, 2018 Gregory Nutt. All rights
|
||||
* reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||
@ -112,20 +113,29 @@
|
||||
#define BUF ((FAR struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||
#define FBUF ((FAR struct ipv4_hdr_s *)&g_reassembly_buffer[0])
|
||||
|
||||
/* IP fragment re-assembly */
|
||||
/* IP fragment re-assembly.
|
||||
*
|
||||
* REVISIT: There are multiple issues with the current implementation:
|
||||
* 1. IPv4 reassembly is untested.
|
||||
* 2. Currently can only work with Ethernet due to the definition of
|
||||
* IPv4_REASS_BUFSIZE.
|
||||
* 3. Since there is only a single reassembly buffer, IPv4 reassembly cannot
|
||||
* be used in a context where multiple network devices may be concurrently
|
||||
* re-assemblying packets.
|
||||
*/
|
||||
|
||||
#define IP_MF 0x20 /* See IP_FLAG_MOREFRAGS */
|
||||
#define TCP_REASS_BUFSIZE (NET_DEV_MTU(dev) - NET_LL_HDRLEN(dev))
|
||||
#define TCP_REASS_LASTFRAG 0x01
|
||||
#define IPv4_REASS_BUFSIZE (CONFIG_NET_ETH_MTU - ETH_HDRLEN)
|
||||
#define IPv4_REASS_LASTFRAG 0x01
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_TCP_REASSEMBLY) && !defined(CONFIG_NET_IPv6)
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
|
||||
static uint8_t g_reassembly_buffer[TCP_REASS_BUFSIZE];
|
||||
static uint8_t g_reassembly_bitmap[TCP_REASS_BUFSIZE / (8 * 8)];
|
||||
static uint8_t g_reassembly_buffer[IPv4_REASS_BUFSIZE];
|
||||
static uint8_t g_reassembly_bitmap[IPv4_REASS_BUFSIZE / (8 * 8)];
|
||||
|
||||
static const uint8_t g_bitmap_bits[8] =
|
||||
{
|
||||
@ -135,7 +145,7 @@ static const uint8_t g_bitmap_bits[8] =
|
||||
static uint16_t g_reassembly_len;
|
||||
static uint8_t g_reassembly_flags;
|
||||
|
||||
#endif /* CONFIG_NET_TCP_REASSEMBLY */
|
||||
#endif /* CONFIG_NET_IPv4_REASSEMBLY */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -151,8 +161,8 @@ static uint8_t g_reassembly_flags;
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_TCP_REASSEMBLY) && !defined(CONFIG_NET_IPv6)
|
||||
static uint8_t devif_reassembly(void)
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
static uint8_t devif_reassembly(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct ipv4_hdr_s *ipv4 = BUF;
|
||||
FAR struct ipv4_hdr_s *fipv4 = FBUF;
|
||||
@ -168,7 +178,7 @@ static uint8_t devif_reassembly(void)
|
||||
if (!g_reassembly_timer)
|
||||
{
|
||||
memcpy(g_reassembly_buffer, &ipv4->vhl, IPv4_HDRLEN);
|
||||
g_reassembly_timer = CONFIG_NET_TCP_REASS_MAXAGE;
|
||||
g_reassembly_timer = CONFIG_NET_IPv4_REASS_MAXAGE;
|
||||
g_reassembly_flags = 0;
|
||||
|
||||
/* Clear the bitmap. */
|
||||
@ -183,16 +193,17 @@ static uint8_t devif_reassembly(void)
|
||||
|
||||
if (net_ipv4addr_hdrcmp(ipv4->srcipaddr, fipv4->srcipaddr) &&
|
||||
net_ipv4addr_hdrcmp(ipv4->destipaddr, fipv4->destipaddr) &&
|
||||
ipv4->g_ipid[0] == fipv4->g_ipid[0] && ipv4->g_ipid[1] == fipv4->g_ipid[1])
|
||||
ipv4->ipid[0] == fipv4->ipid[0] && ipv4->ipid[1] == fipv4->ipid[1])
|
||||
{
|
||||
len = (ipv4->len[0] << 8) + ipv4->len[1] - (ipv4->vhl & 0x0f) * 4;
|
||||
len = ((uint16_t)ipv4->len[0] << 8) + (uint16_t)ipv4->len[1] -
|
||||
(uint16_t)(ipv4->vhl & 0x0f) * 4;
|
||||
offset = (((ipv4->ipoffset[0] & 0x3f) << 8) + ipv4->ipoffset[1]) * 8;
|
||||
|
||||
/* If the offset or the offset + fragment length overflows the
|
||||
* reassembly buffer, we discard the entire packet.
|
||||
*/
|
||||
|
||||
if (offset > TCP_REASS_BUFSIZE || offset + len > TCP_REASS_BUFSIZE)
|
||||
if (offset > IPv4_REASS_BUFSIZE || offset + len > IPv4_REASS_BUFSIZE)
|
||||
{
|
||||
g_reassembly_timer = 0;
|
||||
goto nullreturn;
|
||||
@ -240,7 +251,7 @@ static uint8_t devif_reassembly(void)
|
||||
|
||||
if ((ipv4->ipoffset[0] & IP_MF) == 0)
|
||||
{
|
||||
g_reassembly_flags |= TCP_REASS_LASTFRAG;
|
||||
g_reassembly_flags |= IPv4_REASS_LASTFRAG;
|
||||
g_reassembly_len = offset + len;
|
||||
}
|
||||
|
||||
@ -249,7 +260,7 @@ static uint8_t devif_reassembly(void)
|
||||
* are set.
|
||||
*/
|
||||
|
||||
if (g_reassembly_flags & TCP_REASS_LASTFRAG)
|
||||
if (g_reassembly_flags & IPv4_REASS_LASTFRAG)
|
||||
{
|
||||
/* Check all bytes up to and including all but the last byte in
|
||||
* the bitmap.
|
||||
@ -298,7 +309,7 @@ static uint8_t devif_reassembly(void)
|
||||
nullreturn:
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NET_TCP_REASSEMBLY */
|
||||
#endif /* CONFIG_NET_IPv4_REASSEMBLY */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -380,20 +391,18 @@ int ipv4_input(FAR struct net_driver_s *dev)
|
||||
|
||||
if ((ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0)
|
||||
{
|
||||
#if defined(CONFIG_NET_TCP_REASSEMBLY)
|
||||
dev->d_len = devif_reassembly();
|
||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
||||
dev->d_len = devif_reassembly(dev);
|
||||
if (dev->d_len == 0)
|
||||
#endif
|
||||
{
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv4.drop++;
|
||||
g_netstats.ipv4.fragerr++;
|
||||
#endif
|
||||
nwarn("WARNING: IP fragment dropped\n");
|
||||
goto drop;
|
||||
}
|
||||
#else /* CONFIG_NET_TCP_REASSEMBLY */
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv4.drop++;
|
||||
g_netstats.ipv4.fragerr++;
|
||||
#endif
|
||||
nwarn("WARNING: IP fragment dropped\n");
|
||||
goto drop;
|
||||
#endif /* CONFIG_NET_TCP_REASSEMBLY */
|
||||
}
|
||||
|
||||
/* Get the destination IP address in a friendlier form */
|
||||
|
@ -35,33 +35,6 @@ config NET_TCPURGDATA
|
||||
compiled in. Urgent data (out-of-band data) is a rarely used TCP feature
|
||||
that is very seldom would be required.
|
||||
|
||||
config NET_TCP_REASSEMBLY
|
||||
bool "TCP reassembly"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
Enable support for IP packet reassembly of fragmented IP packets.
|
||||
|
||||
This features requires an additional amount of RAM to hold the
|
||||
reassembly buffer and the reassembly code size is approximately 700
|
||||
bytes. The reassembly buffer is of the same size as the d_buf buffer
|
||||
(configured by CONFIG_NET_xxx_MTU).
|
||||
|
||||
Note: IP packet reassembly is not heavily tested (and, hence,
|
||||
EXPERIMENTAL).
|
||||
|
||||
if NET_TCP_REASSEMBLY
|
||||
|
||||
config NET_TCP_REASS_MAXAGE
|
||||
int "IP fragment timeout"
|
||||
default 200
|
||||
---help---
|
||||
The maximum time an IP fragment should wait in the reassembly buffer
|
||||
before it is dropped. Units are deci-seconds, the range of the timer
|
||||
is 8-bits. Default: 20 seconds.
|
||||
|
||||
endif # NET_TCP_REASSEMBLY
|
||||
|
||||
config NET_TCP_CONNS
|
||||
int "Number of TCP/IP connections"
|
||||
default 8
|
||||
|
@ -111,7 +111,13 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
|
||||
|
||||
tcp = (FAR struct tcp_hdr_s *)&dev->d_buf[iplen + NET_LL_HDRLEN(dev)];
|
||||
|
||||
/* Get the size of the IP header and the TCP header */
|
||||
/* Get the size of the IP header and the TCP header.
|
||||
*
|
||||
* REVISIT: TCP header is *not* a constant! It can be larger if the
|
||||
* TCP header includes options. The constand TCP_HDRLEN should be
|
||||
* replaced with the macro TCP_OPT_HDRLEN(n) which will calculate the
|
||||
* correct header length in all cases.
|
||||
*/
|
||||
|
||||
tcpiplen = iplen + TCP_HDRLEN;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user