wengzhe commented on code in PR #7562: URL: https://github.com/apache/incubator-nuttx/pull/7562#discussion_r1018628858
########## net/nat/ipv4_nat.c: ########## @@ -0,0 +1,321 @@ +/**************************************************************************** + * net/nat/ipv4_nat.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/config.h> + +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> + +#include <nuttx/net/tcp.h> + +#include "nat/nat.h" +#include "utils/utils.h" + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Adjust checksums in headers. */ + +#define chksum_adjust(chksum,old_data,new_data) \ + net_chksum_adjust((FAR uint16_t *)&chksum, \ + (FAR uint16_t *)&old_data, sizeof(old_data), \ + (FAR uint16_t *)&new_data, sizeof(new_data)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_inbound_tcp + * + * Description: + * Check if a received TCP packet belongs to a NAT entry. If so, translate + * it. + * + * Input Parameters: + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet is received on NAT device and is targeting at the address + * assigned to the device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_inbound_tcp(FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = + ipv4_nat_inbound_entry_find(IP_PROTO_TCP, tcp->destport); + if (!entry) + { + /* Inbound without entry is OK (e.g. towards NuttX itself), skip NAT. */ + + return OK; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->destport, entry->local_port); + tcp->destport = entry->local_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->destipaddr, entry->local_ip); + chksum_adjust(ipv4->ipchksum, ipv4->destipaddr, entry->local_ip); + net_ipv4addr_hdrcopy(ipv4->destipaddr, &entry->local_ip); + + return OK; +} +#endif + +/**************************************************************************** + * Name: ipv4_nat_outbound_tcp + * + * Description: + * Check if we want to perform NAT with this outbound TCP packet before + * sending it. If so, translate it. + * + * Input Parameters: + * dev - The device to sent the packet. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet will be sent on NAT device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_outbound_tcp(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = ipv4_nat_outbound_entry_find( + IP_PROTO_TCP, net_ip4addr_conv32(ipv4->srcipaddr), tcp->srcport); + if (!entry) + { + /* Outbound entry creation failed, should have corresponding entry. */ + Review Comment: When `ipv4_nat_outbound()` returns an error, nwarn will be called in `ipv4_dev_forward()`, and we will only fail in this case (malloc failed), so maybe it's enough? ########## net/nat/Kconfig: ########## @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config NET_NAT + bool "Network address translation (NAT)" Review Comment: Done. ########## net/nat/ipv4_nat.c: ########## @@ -0,0 +1,321 @@ +/**************************************************************************** + * net/nat/ipv4_nat.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/config.h> + +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> + +#include <nuttx/net/tcp.h> + +#include "nat/nat.h" +#include "utils/utils.h" + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Adjust checksums in headers. */ + +#define chksum_adjust(chksum,old_data,new_data) \ + net_chksum_adjust((FAR uint16_t *)&chksum, \ + (FAR uint16_t *)&old_data, sizeof(old_data), \ + (FAR uint16_t *)&new_data, sizeof(new_data)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_inbound_tcp + * + * Description: + * Check if a received TCP packet belongs to a NAT entry. If so, translate + * it. + * + * Input Parameters: + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet is received on NAT device and is targeting at the address + * assigned to the device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_inbound_tcp(FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = + ipv4_nat_inbound_entry_find(IP_PROTO_TCP, tcp->destport); + if (!entry) + { + /* Inbound without entry is OK (e.g. towards NuttX itself), skip NAT. */ + + return OK; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->destport, entry->local_port); + tcp->destport = entry->local_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->destipaddr, entry->local_ip); + chksum_adjust(ipv4->ipchksum, ipv4->destipaddr, entry->local_ip); + net_ipv4addr_hdrcopy(ipv4->destipaddr, &entry->local_ip); + + return OK; +} +#endif + +/**************************************************************************** + * Name: ipv4_nat_outbound_tcp + * + * Description: + * Check if we want to perform NAT with this outbound TCP packet before + * sending it. If so, translate it. + * + * Input Parameters: + * dev - The device to sent the packet. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet will be sent on NAT device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_outbound_tcp(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = ipv4_nat_outbound_entry_find( + IP_PROTO_TCP, net_ip4addr_conv32(ipv4->srcipaddr), tcp->srcport); + if (!entry) + { + /* Outbound entry creation failed, should have corresponding entry. */ + + return -ENOMEM; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->srcport, entry->external_port); + tcp->srcport = entry->external_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->srcipaddr, dev->d_ipaddr); + chksum_adjust(ipv4->ipchksum, ipv4->srcipaddr, dev->d_ipaddr); + net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_enable + * + * Description: + * Enable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the outbound packets will be masqueraded. + * + * Returned Value: + * Zero is returned if NAT function is successfully enabled on the device; + * A negated errno value is returned if failed. + * + * Assumptions: + * NAT will only be enabled on at most one device. + * + * Limitations: + * External ports are not isolated between devices yet, so if NAT is + * enabled on more than one device, an external port used on one device + * will also be used by same local ip:port on another device. + * + * TODO: + * Support multiple NAT devices with isolated external port mapping. + ****************************************************************************/ + +int ipv4_nat_enable(FAR struct net_driver_s *dev) +{ + if (IFF_IS_NAT(dev->d_flags)) + { + return -EEXIST; + } + + IFF_SET_NAT(dev->d_flags); + return OK; +} + +/**************************************************************************** + * Name: ipv4_nat_disable + * + * Description: + * Disable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the NAT function will be disabled. + * + * Returned Value: + * Zero is returned if NAT function is successfully disabled on the device; + * A negated errno value is returned if failed. + * + ****************************************************************************/ + +int ipv4_nat_disable(FAR struct net_driver_s *dev) +{ + if (!IFF_IS_NAT(dev->d_flags)) + { + return -ENODEV; Review Comment: Done. ########## net/nat/ipv4_nat.c: ########## @@ -0,0 +1,321 @@ +/**************************************************************************** + * net/nat/ipv4_nat.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/config.h> + +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> + +#include <nuttx/net/tcp.h> + +#include "nat/nat.h" +#include "utils/utils.h" + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Adjust checksums in headers. */ + +#define chksum_adjust(chksum,old_data,new_data) \ + net_chksum_adjust((FAR uint16_t *)&chksum, \ + (FAR uint16_t *)&old_data, sizeof(old_data), \ + (FAR uint16_t *)&new_data, sizeof(new_data)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_inbound_tcp + * + * Description: + * Check if a received TCP packet belongs to a NAT entry. If so, translate + * it. + * + * Input Parameters: + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet is received on NAT device and is targeting at the address + * assigned to the device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_inbound_tcp(FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = + ipv4_nat_inbound_entry_find(IP_PROTO_TCP, tcp->destport); + if (!entry) + { + /* Inbound without entry is OK (e.g. towards NuttX itself), skip NAT. */ + + return OK; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->destport, entry->local_port); + tcp->destport = entry->local_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->destipaddr, entry->local_ip); + chksum_adjust(ipv4->ipchksum, ipv4->destipaddr, entry->local_ip); + net_ipv4addr_hdrcopy(ipv4->destipaddr, &entry->local_ip); + + return OK; +} +#endif + +/**************************************************************************** + * Name: ipv4_nat_outbound_tcp + * + * Description: + * Check if we want to perform NAT with this outbound TCP packet before + * sending it. If so, translate it. + * + * Input Parameters: + * dev - The device to sent the packet. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet will be sent on NAT device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_outbound_tcp(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = ipv4_nat_outbound_entry_find( + IP_PROTO_TCP, net_ip4addr_conv32(ipv4->srcipaddr), tcp->srcport); + if (!entry) + { + /* Outbound entry creation failed, should have corresponding entry. */ + + return -ENOMEM; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->srcport, entry->external_port); + tcp->srcport = entry->external_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->srcipaddr, dev->d_ipaddr); + chksum_adjust(ipv4->ipchksum, ipv4->srcipaddr, dev->d_ipaddr); + net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_enable + * + * Description: + * Enable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the outbound packets will be masqueraded. + * + * Returned Value: + * Zero is returned if NAT function is successfully enabled on the device; + * A negated errno value is returned if failed. + * + * Assumptions: + * NAT will only be enabled on at most one device. + * + * Limitations: + * External ports are not isolated between devices yet, so if NAT is + * enabled on more than one device, an external port used on one device + * will also be used by same local ip:port on another device. + * + * TODO: + * Support multiple NAT devices with isolated external port mapping. + ****************************************************************************/ + +int ipv4_nat_enable(FAR struct net_driver_s *dev) +{ + if (IFF_IS_NAT(dev->d_flags)) + { + return -EEXIST; Review Comment: Done. ########## net/nat/Kconfig: ########## @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config NET_NAT + bool "Network address translation (NAT)" + default n + depends on NET_IPFORWARD + ---help--- + Enable or disable Network address translation (NAT) function. Review Comment: Done. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
