If you look at the help of iproute2, you will find that there is a nat action in the route section, where the via Parameter provides the conversion address. I will not mention the specific configuration. I only propose two points. First, the stateless nat of iproute2 requires the participation of policy routing. Second, it is removed from the 2.6 kernel. For more information, see the documentation. In the 2.6 kernel, the kernel protocol stack leaves all extensions to Netfilter for implementation, and only implements the Standard Minimal set.
Why should we mention the 2.4 kernel nat route? Since NAT has been removed, it is of Philosophical Significance to implement nat in Netfilter. Since I have implemented a two-way stateless NAT Based on Netfilter myself (SEE ), so what does it mean to repeat old things? I told my wife that there is a set of self-explanatory theories behind everything I say and do. No matter how ridiculous it is, it can be self-circular! So now I want to implement a stateless nat, which also requires theoretical support: it is reasonable to insert NAT into the routing table, because NAT is affected by the route (whether it is a local route or a remote route), it is better to directly remove it in the route. Because the intermediate point of PRE/POST-ROUTING is ROUTING, why not merge NAT in the ROUTING? Although this is not in line with the Netfilter philosophy, it is too good for pragmatism! 2.4 The reason why the nat route implemented by the kernel is not good is that there are code reasons in addition to philosophical reasons. The implementation code is too messy!
If nat route is implemented based on the above ideas, there is no need to use policy routing, no need to configure ip rule, and no need to configure two rules. Its flowchart is as follows, and the code is better modified:
We can see that this implementation uses recursive route query, which is not implemented in Linux at all. Therefore, you need to modify some code of Route insertion. I use several flags to identify that this route is used for NAT. Because it is a two-way NAT of stateless, therefore, when you insert a NAT route, it must be automatically generated in another direction. For example, if you insert the following route:
Ip route add dnat x via y
Indicates that all the target x is converted to y. The following routes must be automatically generated:
Ip route add snat y via x
Indicates that all sources whose IP addresses are y must be converted to x. Of course, the following items should not be manually configured. The auto label should be used to name them automatically generated.
The above needs to be explained as snat. In principle, snat is implemented after the route, otherwise it may be useless. Why is the flowchart snat before the route? This is to minimize the number of queries. Otherwise, a lot of useless queries will be performed to check whether all data packets require snat, one technique used here is that route query is based on the longest prefix match. If snat is required, a detailed 32-bit prefix snat route is provided. If no, that means no snat is required. Of course, the above flowchart can be optimized, because we realize that because it is a two-way nat, as long as there is a dnat, there will be an snat, and in turn the same, it will appear in pairs, can we optimize it based on this?