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 <shichunma@bestechnic.com>
This commit is contained in:
shichunma 2026-08-01 21:54:32 +08:00
parent 48dfff56ae
commit 6dfb82dc4a
2 changed files with 39 additions and 14 deletions

View file

@ -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

View file

@ -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: