This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0ed3a386382f8367508b036b161485a912a442e6
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:

Reply via email to