mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
Merge 21b8e01a0f into e73f7f7d0e
This commit is contained in:
commit
68a7423da2
5 changed files with 112 additions and 33 deletions
|
|
@ -84,6 +84,7 @@
|
|||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <nuttx/debug.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -166,6 +167,34 @@ static int ipv4_check_opt(FAR struct ipv4_hdr_s *ipv4)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv4_fragin_or_drop
|
||||
*
|
||||
* Description:
|
||||
* Reassemble an incoming IPv4 fragment for local processing or drop it if
|
||||
* fragment reassembly is not available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ipv4_fragin_or_drop(FAR struct net_driver_s *dev)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPFRAG
|
||||
if (ipv4_fragin(dev) == OK)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv4.drop++;
|
||||
g_netstats.ipv4.fragerr++;
|
||||
#endif
|
||||
nwarn("WARNING: IP fragment dropped\n");
|
||||
|
||||
dev->d_len = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv4_in
|
||||
*
|
||||
|
|
@ -199,6 +228,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
|||
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
||||
in_addr_t destipaddr;
|
||||
uint16_t totlen;
|
||||
bool isfrag;
|
||||
int ret = OK;
|
||||
|
||||
/* Handle ARP on input then give the IPv4 packet to the network layer */
|
||||
|
|
@ -273,22 +303,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
|||
|
||||
/* Check the fragment flag. */
|
||||
|
||||
if ((ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPFRAG
|
||||
if (ipv4_fragin(dev) == OK)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv4.drop++;
|
||||
g_netstats.ipv4.fragerr++;
|
||||
#endif
|
||||
nwarn("WARNING: IP fragment dropped\n");
|
||||
goto drop;
|
||||
}
|
||||
isfrag = (ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (ipv4_check_opt(ipv4) != OK)
|
||||
|
|
@ -301,6 +316,13 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_NAT44) || defined(CONFIG_NET_IPFILTER)
|
||||
if (isfrag)
|
||||
{
|
||||
return ipv4_fragin_or_drop(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NAT44
|
||||
/* Try NAT inbound, rule matching will be performed in NAT module. */
|
||||
|
||||
|
|
@ -334,6 +356,11 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
|||
ipv4_forward_broadcast(dev, ipv4);
|
||||
#endif
|
||||
|
||||
if (isfrag)
|
||||
{
|
||||
return ipv4_fragin_or_drop(dev);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_BROADCAST) && defined(NET_UDP_HAVE_STACK)
|
||||
if (ipv4->proto == IP_PROTO_UDP)
|
||||
{
|
||||
|
|
@ -406,6 +433,16 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* Forwarding has already had a chance to consume non-local unicast
|
||||
* fragments. Any remaining fragments are for local input and must be
|
||||
* reassembled before the transport layer sees them.
|
||||
*/
|
||||
|
||||
if (isfrag)
|
||||
{
|
||||
return ipv4_fragin_or_drop(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_IPV4_CHECKSUMS
|
||||
if (((dev->d_features & NETDEV_RX_CSUM) == 0)
|
||||
&& (ipv4_chksum(IPv4BUF) != 0xffff))
|
||||
|
|
|
|||
|
|
@ -151,6 +151,36 @@ static bool check_destipaddr(FAR struct net_driver_s *dev,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_IPFRAG) || defined(CONFIG_NET_NAT66) || defined(CONFIG_NET_IPFILTER)
|
||||
/****************************************************************************
|
||||
* Name: ipv6_fragin_or_drop
|
||||
*
|
||||
* Description:
|
||||
* Reassemble an incoming IPv6 fragment for NAT or local processing or drop
|
||||
* it if fragment reassembly is not available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ipv6_fragin_or_drop(FAR struct net_driver_s *dev)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPFRAG
|
||||
if (ipv6_fragin(dev) == OK)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv6.drop++;
|
||||
g_netstats.ipv6.fragerr++;
|
||||
#endif
|
||||
nwarn("WARNING: IPv6 fragment dropped\n");
|
||||
|
||||
dev->d_len = 0;
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv6_in
|
||||
*
|
||||
|
|
@ -195,7 +225,7 @@ static int ipv6_in(FAR struct net_driver_s *dev)
|
|||
#ifdef CONFIG_NET_IPFORWARD
|
||||
int ret;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPFRAG
|
||||
#if defined(CONFIG_NET_IPFRAG) || defined(CONFIG_NET_NAT66) || defined(CONFIG_NET_IPFILTER)
|
||||
bool isfrag = false;
|
||||
#endif
|
||||
|
||||
|
|
@ -287,7 +317,7 @@ static int ipv6_in(FAR struct net_driver_s *dev)
|
|||
if (nxthdr == NEXT_FRAGMENT_EH)
|
||||
{
|
||||
extlen = EXTHDR_FRAG_LEN;
|
||||
#ifdef CONFIG_NET_IPFRAG
|
||||
#if defined(CONFIG_NET_IPFRAG) || defined(CONFIG_NET_NAT66) || defined(CONFIG_NET_IPFILTER)
|
||||
isfrag = true;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -301,6 +331,13 @@ static int ipv6_in(FAR struct net_driver_s *dev)
|
|||
nxthdr = exthdr->nxthdr;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_NAT66) || defined(CONFIG_NET_IPFILTER)
|
||||
if (isfrag)
|
||||
{
|
||||
return ipv6_fragin_or_drop(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NAT66
|
||||
/* Try NAT inbound, rule matching will be performed in NAT module. */
|
||||
|
||||
|
|
@ -410,17 +447,7 @@ static int ipv6_in(FAR struct net_driver_s *dev)
|
|||
#ifdef CONFIG_NET_IPFRAG
|
||||
if (isfrag)
|
||||
{
|
||||
if (ipv6_fragin(dev) == OK)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv6.fragerr++;
|
||||
#endif
|
||||
goto drop;
|
||||
}
|
||||
return ipv6_fragin_or_drop(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ static int ipv4_hdrsize(FAR struct ipv4_hdr_s *ipv4)
|
|||
|
||||
iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2;
|
||||
|
||||
if ((ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0)
|
||||
{
|
||||
return iphdrlen;
|
||||
}
|
||||
|
||||
/* Size is also determined by the following protocol header, */
|
||||
|
||||
switch (ipv4->proto)
|
||||
|
|
|
|||
|
|
@ -360,6 +360,8 @@ int32_t ipv4_fragout(FAR struct net_driver_s *dev, uint16_t mtu)
|
|||
uint32_t iter;
|
||||
uint32_t nfrags;
|
||||
uint16_t offset = 0;
|
||||
uint16_t fragoff;
|
||||
uint16_t morefrags;
|
||||
uint16_t hdrlen;
|
||||
FAR struct iob_s *frag = NULL;
|
||||
FAR struct ipv4_hdr_s *ref = NULL;
|
||||
|
|
@ -374,6 +376,14 @@ int32_t ipv4_fragout(FAR struct net_driver_s *dev, uint16_t mtu)
|
|||
|
||||
hdrlen = (IPv4BUF->vhl & IPv4_HLMASK) << 2;
|
||||
|
||||
/* Preserve the original fragment offset when splitting an
|
||||
* already-fragmented packet for a smaller egress MTU.
|
||||
*/
|
||||
|
||||
fragoff = (IPv4BUF->ipoffset[0] << 8) + IPv4BUF->ipoffset[1];
|
||||
morefrags = fragoff & IP_FLAG_MOREFRAGS;
|
||||
fragoff &= 0x1fff;
|
||||
|
||||
/* Reconstruct I/O Buffer according to MTU, which will reserve
|
||||
* the space for the L3 header
|
||||
*/
|
||||
|
|
@ -401,13 +411,13 @@ int32_t ipv4_fragout(FAR struct net_driver_s *dev, uint16_t mtu)
|
|||
/* Update the IPv4 header of the first fragment */
|
||||
|
||||
ipv4_fragout_buildipv4header(ref, ref, frag->io_pktlen,
|
||||
IP_FLAG_MOREFRAGS);
|
||||
fragoff | IP_FLAG_MOREFRAGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t ipoff = (offset - iter * hdrlen) >> 3;
|
||||
uint16_t ipoff = fragoff + ((offset - iter * hdrlen) >> 3);
|
||||
|
||||
if (iter < nfrags - 1)
|
||||
if (iter < nfrags - 1 || morefrags)
|
||||
{
|
||||
ipoff |= IP_FLAG_MOREFRAGS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ ipv6_nat_inbound_internal(FAR struct ipv6_hdr_s *ipv6,
|
|||
uint8_t proto;
|
||||
FAR void *l4hdr = net_ipv6_payload(ipv6, &proto);
|
||||
|
||||
switch (ipv6->proto)
|
||||
switch (proto)
|
||||
{
|
||||
#ifdef CONFIG_NET_TCP
|
||||
case IP_PROTO_TCP:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue