Commit Graph

33 Commits

Author SHA1 Message Date
Zhe Weng
3a844d8dd7 net/netlink: Add NETLINK_NETFILTER's CONNTRACK support
Now we only supports conntrack info from NAT entries, to let our apps in user space know the mapping status in NAT.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-18 13:03:59 +08:00
Zhe Weng
b0cf0acc66 net/nat: Add foreach interface for entries
Prepare for netlink conntrack dump of entries.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-18 13:03:59 +08:00
Zhe Weng
932c41debb net/nat: Remove unnecessary logic in inbound logic
Finish https://github.com/apache/nuttx/pull/12116#discussion_r1560880897

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-12 14:39:01 +02:00
Zhe Weng
17584eaa4f net/nat: Rename struct ipv*_nat_entry to ipv*_nat_entry_t
I found `struct ipv*_nat_entry` is missing `_s` suffix, but the name is too long in some cases, so maybe `ipv*_nat_entry_t` could be better.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-12 14:39:01 +02:00
Zhe Weng
e543a8086e net: Optimize TCP/UDP port selection
Optimize TCP/UDP port selection, and fix possibly dead loop.

Finish discussion in https://github.com/apache/nuttx/pull/12116#discussion_r1560851977

Note:
Linux also uses EADDRINUSE for failing in finding a portno, according to https://man7.org/linux/man-pages/man2/bind.2.html

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-12 15:46:29 +08:00
Zhe Weng
4eddf84a76 net/nat: Optimize port selection
And fix possibly dead loop.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-11 22:23:29 +08:00
Zhe Weng
f3b34c84c2 net/nat: Support IPv6 Masquerading (NAT66)
Notes:
1. This version of NAT66 is a stateful one like NAT44, corresponding to Linux's MASQUERADE target of ip6tables.  We can support stateless NAT66 & NPTv6 later by slightly modify the address & port selection logic (maybe just match the rules and skip the entry find).
2. We're using same flag `IFF_NAT` for both NAT44 & NAT66 to make control easier.  Which means, if we enable NAT, both NAT44 & NAT66 will be enabled.  If we don't want one of them, we can just disable that one in Kconfig.
3. Maybe we can accelerate the checksum adjustment by pre-calculate a difference of checksum, and apply it to each packet, instead of calling `net_chksum_adjust` each time.  Just a thought, maybe do it later.
4. IP fragment segments on NAT66 connections are not supported yet.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-11 22:23:29 +08:00
Zhe Weng
f2ff5cee03 net/nat: Make some IPv4 NAT functions as common
To prepare for future IPv6 NAT functions.
- Rename common ipv4_nat_xxx to nat_xxx
- Move some common definitions into header

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-11 22:23:29 +08:00
meijian
93beeeeab0 [tcp/udp] fix port generation not in range
(port % max + min)may overflow uint16

Signed-off-by: meijian <meijian@xiaomi.com>
2024-04-09 23:35:55 +08:00
wangchen
b446a002db net:add customizable default max & min port
add customizable default max & min port

Signed-off-by: wangchen <wangchen41@xiaomi.com>
2024-04-09 23:35:55 +08:00
Zhe Weng
7f1e80f0de net/nat: Slightly optimize the IPv4 NAT
1. Reduce getting `old_ip` in `ipv4_nat_ip_adjust`.
2. Some format change.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-09 14:44:26 +08:00
Zhe Weng
a1a09f271f net/nat: Support Symmetric NAT
The symmetric NAT limits one external port to be used with only one peer ip:port.

Note:
1. To avoid using too much #ifdef, we're always passing peer_ip and peer_port as arguments, but won't use them under full cone NAT, let the compiler optimize them.
2. We need to find port binding without peer ip:port, so don't add peer ip:port into hash key.
3. Symmetric NAT needs to *select another external port if a port is used by any other NAT entry*, this behavior is exactly same as Full Cone NAT, so we don't need to change anything related to `ipv4_nat_port_inuse`.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-04-07 23:57:55 +08:00
Zhe Weng
5a10367312 net/nat: Fix ICMP Error MSG Processing
1. Don't assert on IGMP inside ICMP, just ignore it.
2. Check we have full IP header inside ICMP payload before accessing it.
3. `inner_l4hdrbak` need to be `L4_MAXHDRLEN`, not `L4_MAXHDRLEN/2`.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2024-02-05 19:36:59 +08:00
chao an
664927c86e mm/alloc: remove all unnecessary cast for alloc
Fix the minor style issue and remove unnecessary cast

Signed-off-by: chao an <anchao@xiaomi.com>
2023-08-30 14:34:20 +08:00
Zhe Weng
4ffd2cc84c net/nat: Fix compiler warning
We found warning of "%x" mismatch with "in_addr_t" on some platforms.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2023-07-12 19:29:14 +08:00
chao an
6ee9ec7656 build: add initial cmake build system
1. Update all CMakeLists.txt to adapt to new layout
2. Fix cmake build break
3. Update all new file license
4. Fully compatible with current compilation environment(use configure.sh or cmake as you choose)

------------------

How to test

From within nuttx/. Configure:

cmake -B build -DBOARD_CONFIG=sim/nsh -GNinja
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake -B build -DBOARD_CONFIG=sabre-6quad/smp -GNinja
cmake -B build -DBOARD_CONFIG=lm3s6965-ek/qemu-flat -GNinja

(or full path in custom board) :
cmake -B build -DBOARD_CONFIG=$PWD/boards/sim/sim/sim/configs/nsh -GNinja

This uses ninja generator (install with sudo apt install ninja-build). To build:

$ cmake --build build

menuconfig:

$ cmake --build build -t menuconfig

--------------------------

2. cmake/build: reformat the cmake style by cmake-format

https://github.com/cheshirekow/cmake_format

$ pip install cmakelang

$ for i in `find -name CMakeLists.txt`;do cmake-format $i -o $i;done
$ for i in `find -name *\.cmake`;do cmake-format $i -o $i;done

Co-authored-by: Matias N <matias@protobits.dev>
Signed-off-by: chao an <anchao@xiaomi.com>
2023-07-08 13:50:48 +08:00
chao an
e3a6c16944 net/ip: fix compile break if disable NET_TCP
1.
ipfrag/ipv4_frag.c: In function ‘ipv4_fragin’:
ipfrag/ipv4_frag.c:184:22: warning: ‘head’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  184 |   ipv4->len[1] = head->io_pktlen & 0xff;
      |                  ~~~~^~~~~~~~~~~
ipfrag/ipv4_frag.c:123:21: note: ‘head’ was declared here
  123 |   FAR struct iob_s *head;
      |                     ^~~~

2.
devif/ipv6_input.c: In function ‘ipv6_in’:
devif/ipv6_input.c:60:33: error: ‘TCPIPv6BUF’ undeclared (first use in this function); did you mean ‘UDPIPv6BUF’?
   60 | #define PAYLOAD ((FAR uint8_t *)TCPIPv6BUF)
      |                                 ^~~~~~~~~~

3.
nat/ipv4_nat.c: In function ‘ipv4_nat_inbound_icmp’:
nat/ipv4_nat.c:67:30: error: ‘TCP_HDRLEN’ undeclared (first use in this function); did you mean ‘UDP_HDRLEN’?
   67 |   ((proto) == IP_PROTO_TCP ? TCP_HDRLEN : \
      |                              ^~~~~~~~~~
nat/ipv4_nat.c:323:47: note: in expansion of macro ‘L4_HDRLEN’
  323 |             inner_l4hdrlen = MIN(inner_l4len, L4_HDRLEN(inner->proto));
      |                                               ^~~~~~~~~

Signed-off-by: chao an <anchao@xiaomi.com>
2023-02-07 12:46:40 +02:00
Zhe Weng
cb958e5d69 net/nat: Clear entries when NAT will be disabled
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-24 12:05:20 +08:00
Zhe Weng
902a6dcad2 net/nat: Support isolation between multiple WAN devices by saving external ip
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-24 12:05:20 +08:00
Zhe Weng
0ceee72239 net/nat: modify chksum_adjust and MANIP_IPADDR macro for better readability
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-24 12:05:20 +08:00
Zhe Weng
7bd2195fde net/nat: Fix misused d_draddr in select_port
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-23 19:40:19 +08:00
Zhe Weng
a9da1fff28 net/nat: Add auto reclaim logic for NAT entries.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-22 20:20:12 +08:00
Zhe Weng
879c337e30 net/nat: Use hashtable to optimize performance
Performance tested on simulator:

Before optimization:      -25% bandwidth @2k entries, -64% @10k entries
hashtable size=  2(1bit): -24% bandwidth @2k entries, -65% @10k entries
hashtable size=  4(2bits):-15% bandwidth @2k entries, -51% @10k entries
hashtable size= 32(5bits): -3% bandwidth @2k entries, -14% @10k entries
hashtable size=256(8bits): -1% bandwidth @2k entries,  -3% @10k entries

Note: Tested on worst performance, the earliest entry will be the worst.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-22 20:20:12 +08:00
Zhe Weng
f416fd86bb net/ipfwd: Support ICMP error reply when forwarding IPv4
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-02 15:26:45 +08:00
Zhe Weng
9aefd6717c net/nat: Add support for ICMP Error Message
Support DEST_UNREACHABLE, TIME_EXCEEDED and PARAMETER_PROBLEM ICMP types in NAT.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-01 22:45:22 +08:00
Zhe Weng
23dfdeacab net/nat: Split out ipv4_nat_in/outbound_internal
Split out ipv4_nat_in/outbound_internal which returns entry instead of error code, for later ICMP error types, does not change any current logic.

Reason: Outer packet doesn't have information of port, so we need to find entry by inner packet, and apply the entry to outer packet.

| Outer Packet: SRC = Peer IP<No Port>, DST = External IP<No Port> |
| Inner Packet: SRC = External IP:Port, DST = Peer IP:Port         |

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-01 22:45:22 +08:00
Zhe Weng
8b211128f1 net/nat: Support param to manipulate src or dest
This commit is for later ICMP error types processing, and does not change any current logic.

Reason for supporting both side of modification is that an inbound ICMP Error MSG may carry original packet like this:

|          IP HDR: SRC = Peer IP,       DST = External IP |
|        ICMP HDR: ERROR MSG                              |
| <Origin> IP HDR: SRC = External IP,   DST = Peer IP     |
| <Origin> L4 HDR: SRC = External Port, DST = Peer Port   |

So we need to support inbound translation (External -> Local) on SRC or DST of each header.

And so do the outbound direction.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-12-01 22:45:22 +08:00
Zhe Weng
a3a669a5f6 net/nat: Add UDP support
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00
Zhe Weng
8d401db5b9 net/nat: Add ICMP ECHO (REQUEST & REPLY) support
Support ICMP ECHO REQUEST & REPLY. Id of ICMP is processed like port of TCP in NAT. However, our ICMP stack doesn't have a method to manage id allocation like tcp_selectport(), the id is set by apps (like icmp_ping.c) without conflict avoidance, so not adding such conflict avoidance logic to ICMP stack when implementing NAT.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00
Zhe Weng
f498102512 net: select NAT external port by tcp_selectport for TCP
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00
Zhe Weng
8239ddeef4 net/nat: Add TCP entry expiration logic
Add TCP entry expiration logic for NAT, with entries changed from sq to dq for fast removal.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00
Zhe Weng
0a4e01d712 net: verify NAT port usage in tcp_selectport
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00
Zhe Weng
b595430578 net: add basic NAT workflow
Add basic functions for NAT (NAPT), remaining some logic unimplemented (UDP, ICMP, port assignment, etc). NAT for TCP can work now (unless port conflicts).
Outbound: LAN ->  Forward  ->  NAT(only if targeting at WAN)  -> WAN
Inbound:  WAN ->  NAT(only from WAN, change dest) -> Forward  -> LAN

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
2022-11-11 14:36:55 +08:00