This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch releases/13.0 in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 32f679eaf070a557b1b8230a903c67aea90c0bde Author: shichunma <[email protected]> AuthorDate: Sat Aug 1 21:54:32 2026 +0800 net/nat: Reassemble IPv6 fragments before NAT66 NAT66 needs transport headers to create or match address and port mappings. Consume IPv6 fragments through local reassembly before NAT66 processing so forwarded fragmented traffic is not translated fragment-by-fragment without L4 context. Also dispatch inbound NAT66 using the parsed IPv6 next-header value, matching the outbound path and allowing packets with extension headers before the transport header to be translated. Signed-off-by: shichunma <[email protected]> --- net/devif/ipv6_input.c | 51 +++++++++++++++++++++++++++++++++++++------------- net/nat/ipv6_nat.c | 2 +- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/net/devif/ipv6_input.c b/net/devif/ipv6_input.c index dc1c04360de..7236d320a10 100644 --- a/net/devif/ipv6_input.c +++ b/net/devif/ipv6_input.c @@ -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) +/**************************************************************************** + * 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) 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) isfrag = true; #endif } @@ -302,6 +332,11 @@ static int ipv6_in(FAR struct net_driver_s *dev) } #ifdef CONFIG_NET_NAT66 + if (isfrag) + { + return ipv6_fragin_or_drop(dev); + } + /* Try NAT inbound, rule matching will be performed in NAT module. */ ipv6_nat_inbound(dev, ipv6); @@ -410,17 +445,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 diff --git a/net/nat/ipv6_nat.c b/net/nat/ipv6_nat.c index 1c0f16ec955..4a40d2cc4be 100644 --- a/net/nat/ipv6_nat.c +++ b/net/nat/ipv6_nat.c @@ -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:
