nuttx/net:Support to PMTUD
RFC 1191 When a router is unable to forward a datagram because it exceeds the MTU of the next-hop network and its Don't Fragment bit is set, the router is required to return an ICMP Destination Unreachable message to the source of the datagram, with the Code indicating "fragmentation needed and DF set". To support the Path MTU Discovery technique specified in this memo, the router MUST include the MTU of that next-hop network in the low-order 16 bits of the ICMP header field that is labelled "unused" in the ICMP specification [7]. The high-order 16 bits remain unused, and MUST be set to zero. Thus, the message has the following format: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 3 | Code = 4 | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unused = 0 | Next-Hop MTU | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + 64 bits of Original Datagram Data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ RFC 1185 Packet Too Big Message 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | MTU | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | As much of invoking packet | + as will fit without the ICMPv6 packet + | exceeding 576 octets | IPv6 Fields: Destination Address Copied from the Source Address field of the invoking packet. ICMPv6 Fields: Type 2 Code 0 MTU The Maximum Transmission Unit of the next-hop link. Description A Packet Too Big MUST be sent by a router in response to a packet that it cannot forward because the packet is larger than the MTU of the outgoing link. The information in this message is used as part of the Path MTU Discovery process [RFC-1191]. Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
parent
26536f9f55
commit
2e6d0815b2
@ -596,6 +596,22 @@ int devif_loopback(FAR struct net_driver_s *dev);
|
||||
int netdev_input(FAR struct net_driver_s *dev,
|
||||
devif_poll_callback_t callback, bool reply);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devif_get_mtu
|
||||
*
|
||||
* Description:
|
||||
* Get mtu
|
||||
*
|
||||
* Parameters:
|
||||
* dev Ethernet driver device structure
|
||||
*
|
||||
* Return:
|
||||
* return (Maximum packet size - Link layer header size),
|
||||
* if PMTUD enable return pmtu
|
||||
****************************************************************************/
|
||||
|
||||
uint16_t devif_get_mtu(FAR struct net_driver_s *dev);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "ipforward/ipforward.h"
|
||||
#include "sixlowpan/sixlowpan.h"
|
||||
#include "ipfrag/ipfrag.h"
|
||||
#include "inet/inet.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -1152,4 +1153,70 @@ int devif_poll_out(FAR struct net_driver_s *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devif_get_mtu
|
||||
*
|
||||
* Description:
|
||||
* Get mtu
|
||||
*
|
||||
* Parameters:
|
||||
* dev Ethernet driver device structure
|
||||
*
|
||||
* Return:
|
||||
* return (Maximum packet size - Link layer header size),
|
||||
* if PMTUD enable return pmtu
|
||||
****************************************************************************/
|
||||
|
||||
uint16_t devif_get_mtu(FAR struct net_driver_s *dev)
|
||||
{
|
||||
if (dev->d_iob == NULL || dev->d_len == 0)
|
||||
{
|
||||
return dev->d_pktsize - dev->d_llhdrlen;
|
||||
}
|
||||
|
||||
#if (defined(CONFIG_NET_IPv6) && \
|
||||
defined(CONFIG_NET_ICMPv6) && \
|
||||
!defined(CONFIG_NET_ICMPv6_NO_STACK) && \
|
||||
CONFIG_NET_ICMPv6_PMTU_ENTRIES > 0)
|
||||
if (IFF_IS_IPv6(dev->d_flags))
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||
|
||||
if (!net_ipv6addr_cmp(ipv6->destipaddr, g_ipv6_unspecaddr))
|
||||
{
|
||||
FAR struct icmpv6_pmtu_entry *entry =
|
||||
icmpv6_find_pmtu_entry(ipv6->destipaddr);
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
return entry->pmtu;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#if (defined(CONFIG_NET_IPv4) && \
|
||||
defined(CONFIG_NET_ICMP) && \
|
||||
!defined(CONFIG_NET_ICMP_NO_STACK) && \
|
||||
CONFIG_NET_ICMP_PMTU_ENTRIES > 0)
|
||||
if (IFF_IS_IPv4(dev->d_flags))
|
||||
{
|
||||
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
||||
|
||||
if (!net_ipv4addr_cmp(ipv4->destipaddr, INADDR_ANY))
|
||||
{
|
||||
FAR struct icmp_pmtu_entry *entry =
|
||||
icmpv4_find_pmtu_entry(net_ip4addr_conv32(ipv4->destipaddr));
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
return entry->pmtu;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
return dev->d_pktsize - dev->d_llhdrlen;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET */
|
||||
|
@ -21,6 +21,19 @@ config NET_ICMP_NO_STACK
|
||||
|
||||
if NET_ICMP && !NET_ICMP_NO_STACK
|
||||
|
||||
config NET_ICMP_PMTU_ENTRIES
|
||||
int "Path MTU Discovery (PMTUD) ICMP pmtu entry number"
|
||||
default 0
|
||||
---help---
|
||||
The number of the ICMP pmtu entry
|
||||
|
||||
config NET_ICMP_PMTU_TIMEOUT
|
||||
int "Path MTU Discovery (PMTUD) ICMP pmtu entry timeout (Time Unit:minute)"
|
||||
default 10
|
||||
depends on NET_ICMP_PMTU_ENTRIES != 0
|
||||
---help---
|
||||
The timout of the ICMP pmtu entry
|
||||
|
||||
config NET_ICMP_SOCKET
|
||||
bool "IPPROTO_ICMP socket support"
|
||||
default n
|
||||
|
@ -25,6 +25,10 @@ ifneq ($(CONFIG_NET_ICMP_NO_STACK),y)
|
||||
|
||||
NET_CSRCS += icmp_input.c icmp_reply.c
|
||||
|
||||
ifneq ($(CONFIG_NET_ICMP_PMTU_ENTRIES), 0)
|
||||
NET_CSRCS += icmp_pmtu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_ICMP_SOCKET),y)
|
||||
SOCK_CSRCS += icmp_sockif.c icmp_poll.c icmp_conn.c icmp_sendmsg.c
|
||||
SOCK_CSRCS += icmp_recvmsg.c icmp_netpoll.c icmp_ioctl.c
|
||||
|
@ -104,6 +104,16 @@ struct icmp_conn_s
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
struct icmp_pmtu_entry
|
||||
{
|
||||
in_addr_t daddr;
|
||||
uint16_t pmtu;
|
||||
clock_t time;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -396,6 +406,38 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code);
|
||||
int icmp_ioctl(FAR struct socket *psock, int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv4_find_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Search for a ipv4 destination cache entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv4 address of the destination
|
||||
*
|
||||
* Return:
|
||||
* not null is success; null is failure
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct icmp_pmtu_entry *icmpv4_find_pmtu_entry(in_addr_t destipaddr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv4_add_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Create a new ipv4 destination cache entry. If no unused entry is found,
|
||||
* will recycle oldest entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv4 address of the destination
|
||||
* mtu MTU
|
||||
*
|
||||
* Return:
|
||||
* void
|
||||
****************************************************************************/
|
||||
|
||||
void icmpv4_add_pmtu_entry(in_addr_t destipaddr, int mtu);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
@ -298,6 +299,39 @@ void icmp_input(FAR struct net_driver_s *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_NET_ICMP_PMTU_ENTRIES > 0
|
||||
else if (icmp->type == ICMP_DEST_UNREACHABLE)
|
||||
{
|
||||
if (icmp->icode == ICMP_FRAG_NEEDED)
|
||||
{
|
||||
FAR struct icmp_pmtu_entry *entry;
|
||||
FAR struct ipv4_hdr_s *inner;
|
||||
int mtu;
|
||||
|
||||
mtu = ntohs(icmp->data[0]) << 16 | ntohs(icmp->data[1]);
|
||||
if (mtu <= 0)
|
||||
{
|
||||
goto typeerr;
|
||||
}
|
||||
|
||||
inner = (FAR struct ipv4_hdr_s *)(icmp + 1);
|
||||
entry = icmpv4_find_pmtu_entry(
|
||||
net_ip4addr_conv32(inner->destipaddr));
|
||||
if (entry == NULL)
|
||||
{
|
||||
icmpv4_add_pmtu_entry(
|
||||
net_ip4addr_conv32(inner->destipaddr), mtu);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->pmtu = mtu;
|
||||
}
|
||||
|
||||
goto icmp_send_nothing;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Otherwise the ICMP input was not processed */
|
||||
|
||||
else
|
||||
@ -319,6 +353,11 @@ drop:
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmp.drop++;
|
||||
#endif
|
||||
|
||||
#if CONFIG_NET_ICMP_PMTU_ENTRIES > 0
|
||||
icmp_send_nothing:
|
||||
#endif
|
||||
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
|
118
net/icmp/icmp_pmtu.c
Normal file
118
net/icmp/icmp_pmtu.c
Normal file
@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
* net/icmp/icmp_pmtu.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "icmp/icmp.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct icmp_pmtu_entry
|
||||
g_icmp_pmtu_entry[CONFIG_NET_ICMP_PMTU_ENTRIES];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv4_find_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Search for a ipv4 destination cache entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv4 address of the destination
|
||||
*
|
||||
* Return:
|
||||
* not null is success; null is failure
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct icmp_pmtu_entry *icmpv4_find_pmtu_entry(in_addr_t destipaddr)
|
||||
{
|
||||
clock_t now = clock_systime_ticks();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMP_PMTU_ENTRIES; i++)
|
||||
{
|
||||
if (g_icmp_pmtu_entry[i].pmtu == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_ipv4addr_cmp(destipaddr, g_icmp_pmtu_entry[i].daddr))
|
||||
{
|
||||
g_icmp_pmtu_entry[i].time = now;
|
||||
return &g_icmp_pmtu_entry[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv4_add_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Create a new ipv4 destination cache entry. If no unused entry is found,
|
||||
* will recycle oldest entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv4 address of the destination
|
||||
* mtu MTU
|
||||
*
|
||||
* Return:
|
||||
* void
|
||||
****************************************************************************/
|
||||
|
||||
void icmpv4_add_pmtu_entry(in_addr_t destipaddr, int mtu)
|
||||
{
|
||||
clock_t now = clock_systime_ticks();
|
||||
int j = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMP_PMTU_ENTRIES; i++)
|
||||
{
|
||||
if ((g_icmp_pmtu_entry[i].pmtu == 0) ||
|
||||
(sclock_t)(now - g_icmp_pmtu_entry[i].time) >=
|
||||
SEC2TICK(CONFIG_NET_ICMP_PMTU_TIMEOUT * 60))
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sclock_t)(g_icmp_pmtu_entry[i].time -
|
||||
g_icmp_pmtu_entry[j].time) < 0)
|
||||
{
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
net_ipv4addr_copy(g_icmp_pmtu_entry[j].daddr, destipaddr);
|
||||
g_icmp_pmtu_entry[j].pmtu = mtu;
|
||||
g_icmp_pmtu_entry[j].time = now;
|
||||
}
|
@ -22,6 +22,19 @@ config NET_ICMPv6_NO_STACK
|
||||
|
||||
if NET_ICMPv6 && !NET_ICMPv6_NO_STACK
|
||||
|
||||
config NET_ICMPv6_PMTU_ENTRIES
|
||||
int "PMTUD ICMPv6 pmtu entry"
|
||||
default 0
|
||||
---help---
|
||||
The number of the ICMPv6 pmtu entry
|
||||
|
||||
config NET_ICMPv6_PMTU_TIMEOUT
|
||||
int "PMTUD ICMPv6 pmtu entry timeout (Time Unit:minute)"
|
||||
default 10
|
||||
depends on NET_ICMPv6_PMTU_ENTRIES != 0
|
||||
---help---
|
||||
The timout of the ICMPv6 pmtu entry
|
||||
|
||||
config NET_ICMPv6_SOCKET
|
||||
bool "IPPROTO_ICMP6 socket support"
|
||||
default n
|
||||
|
@ -49,6 +49,10 @@ ifeq ($(CONFIG_NET_ICMPv6_ROUTER),y)
|
||||
NET_CSRCS += icmpv6_radvertise.c
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_NET_ICMPv6_PMTU_ENTRIES), 0)
|
||||
NET_CSRCS += icmpv6_pmtu.c
|
||||
endif
|
||||
|
||||
# Include ICMPv6 build support
|
||||
|
||||
DEPPATH += --dep-path icmpv6
|
||||
|
@ -136,6 +136,13 @@ struct icmpv6_rnotify_s
|
||||
};
|
||||
#endif
|
||||
|
||||
struct icmpv6_pmtu_entry
|
||||
{
|
||||
net_ipv6addr_t daddr;
|
||||
uint16_t pmtu;
|
||||
clock_t time;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -783,6 +790,39 @@ void icmpv6_reply(FAR struct net_driver_s *dev,
|
||||
int icmpv6_ioctl(FAR struct socket *psock, int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_find_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Search for a ipv6 pmtu entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv6 address of the destination
|
||||
*
|
||||
* Return:
|
||||
* void
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct icmpv6_pmtu_entry *
|
||||
icmpv6_find_pmtu_entry(net_ipv6addr_t destipaddr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_add_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Create a new ipv6 destination cache entry. If no unused entry is found,
|
||||
* will recycle oldest entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv6 address of the destination
|
||||
* mtu MTU
|
||||
*
|
||||
* Return:
|
||||
* void
|
||||
****************************************************************************/
|
||||
|
||||
void icmpv6_add_pmtu_entry(net_ipv6addr_t destipaddr, int mtu);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -551,6 +551,34 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
||||
}
|
||||
break;
|
||||
|
||||
#if (CONFIG_NET_ICMPv6_PMTU_ENTRIES > 0)
|
||||
case ICMPv6_PACKET_TOO_BIG:
|
||||
{
|
||||
FAR struct icmpv6_pmtu_entry *entry;
|
||||
FAR struct ipv6_hdr_s *inner;
|
||||
int mtu;
|
||||
|
||||
mtu = (ntohs(icmpv6->data[0]) << 16) | (ntohs(icmpv6->data[1]));
|
||||
if (mtu <= 0)
|
||||
{
|
||||
goto icmpv6_type_error;
|
||||
}
|
||||
|
||||
inner = (FAR struct ipv6_hdr_s *)(icmpv6 + 1);
|
||||
entry = icmpv6_find_pmtu_entry(inner->destipaddr);
|
||||
if (entry == NULL)
|
||||
{
|
||||
icmpv6_add_pmtu_entry(inner->destipaddr, mtu);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->pmtu = mtu;
|
||||
}
|
||||
|
||||
goto icmpv6_send_nothing;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_MLD
|
||||
/* Dispatch received Multicast Listener Discovery (MLD) packets. */
|
||||
|
||||
|
117
net/icmpv6/icmpv6_pmtu.c
Normal file
117
net/icmpv6/icmpv6_pmtu.c
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
* net/icmpv6/icmpv6_pmtu.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct icmpv6_pmtu_entry
|
||||
g_icmpv6_pmtu_entry[CONFIG_NET_ICMPv6_PMTU_ENTRIES];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_find_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Search for a ipv6 pmtu entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv6 address of the destination
|
||||
*
|
||||
* Return:
|
||||
* not null is success; null is failure
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct icmpv6_pmtu_entry *
|
||||
icmpv6_find_pmtu_entry(net_ipv6addr_t destipaddr)
|
||||
{
|
||||
clock_t now = clock_systime_ticks();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMPv6_PMTU_ENTRIES; i++)
|
||||
{
|
||||
if (g_icmpv6_pmtu_entry[i].pmtu == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_ipv6addr_cmp(destipaddr, g_icmpv6_pmtu_entry[i].daddr))
|
||||
{
|
||||
g_icmpv6_pmtu_entry[i].time = now;
|
||||
return &g_icmpv6_pmtu_entry[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_add_pmtu_entry
|
||||
*
|
||||
* Description:
|
||||
* Create a new ipv6 destination cache entry. If no unused entry is found,
|
||||
* will recycle oldest entry
|
||||
*
|
||||
* Parameters:
|
||||
* destipaddr the IPv6 address of the destination
|
||||
* mtu MTU
|
||||
*
|
||||
* Return:
|
||||
* void
|
||||
****************************************************************************/
|
||||
|
||||
void icmpv6_add_pmtu_entry(net_ipv6addr_t destipaddr, int mtu)
|
||||
{
|
||||
clock_t now = clock_systime_ticks();
|
||||
int j = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMPv6_PMTU_ENTRIES; i++)
|
||||
{
|
||||
if (g_icmpv6_pmtu_entry[i].pmtu == 0 ||
|
||||
(sclock_t)(now - g_icmpv6_pmtu_entry[i].time) >=
|
||||
SEC2TICK(CONFIG_NET_ICMPv6_PMTU_TIMEOUT * 60))
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sclock_t)(g_icmpv6_pmtu_entry[i].time -
|
||||
g_icmpv6_pmtu_entry[j].time) < 0)
|
||||
{
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
net_ipv6addr_copy(g_icmpv6_pmtu_entry[j].daddr, destipaddr);
|
||||
g_icmpv6_pmtu_entry[j].pmtu = mtu;
|
||||
g_icmpv6_pmtu_entry[j].time = now;
|
||||
}
|
@ -1236,7 +1236,7 @@ void ip_frag_remallfrags(void)
|
||||
|
||||
int32_t ip_fragout(FAR struct net_driver_s *dev)
|
||||
{
|
||||
uint16_t mtu = dev->d_pktsize - dev->d_llhdrlen;
|
||||
uint16_t mtu = devif_get_mtu(dev);
|
||||
|
||||
if (dev->d_iob == NULL || dev->d_len == 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user