Loopback is actually a hole.
But if it's not a hole, it can do something, like Cisco's NVi. Since the prophase is "if it is not a hole," then you need to make some changes to the code. Before you change, you have to understand why the Linux loopback interface is a hole.
The standard stipulates that all packets attempting to go through the loopback interface to another place (not native) are discarded. Linux uses the loop hole to do this. Linux limits loopback traffic in the local scope of the way is that all the loopback traffic must be sent through the machine, then in Ip_output will be set to LOOPBACK_DST, and then into the IP receive routines, It already has the associated routing items, and then will not go to query the routing table, so all the data into the ip_input logic is not the machine issued, so in its internal can do a more ruthless judgment, the source address is the local address, all discarded! So the package sent by the machine will not go through the loopback mouth and then to the outside, we look at the external entry into the package can go through the loopback port to the outside. The answer is no doubt, look at the following process: packets from the physical network card into the-> is routed to the LO Port-> will loopback_dst this routing item to the packet->loopback interface XMit Packet-> The analog loopback interface receives packets-> into the ip_input routing judgment-> is forwarded according to the routing item because of the routing item already in use. There are two ways to forward routing items, and Ip_forward will be invoked continuously for externally entered packets until the TTL changes to 0. So as long as entered the loopback, either directly discarded, or crazy loop, is absolutely out of the way.
Let me just say how to break these constraints. First of all, let's say how the data packets sent by the computer first go through the loopback, and then explain how the incoming packets go through the loopback before going out, and finally explain, What problems will be encountered as NAT and how to solve the NAT problem in combination with the above two kinds of scenarios for the local contract and the external package.
1. This machine contract sends through loopback
Modifying the code is unnecessary, because I am destroying the principle. Luckily, the code just changes a little bit. The part of the modification is to identify the package "sent by loopback" and then delete its associated route entry. This is simple to do with NetFilter on prerouting. The other is to delete the local route that represents the native address from the list, and then join the main table as the unicast route, so that when you do a reverse routing query, you will not be able to match the route to the list (Linux requires that the type of the reverse route must be unicast), To this is ok!
2. External contract is forwarded via loopback
In this case, the loopback Routing item association, as long as it is deleted, can be forwarded smoothly. Because the source IP address of the packet can not be native IP, so it can not be local, if the data flow to the original way back, it must have a reverse unicast route.
3.NAT problem
In the case where the SNAT is configured, to see what Snat became the address, if it is Sant into the local address, then face the 1th section of the problem, the solution is to remove the address from the local table, but after the deletion will cause other machines ARP this address, the machine no longer reply, Therefore, after the deletion and explicitly arping the address of the ARP update, if the Snat is another address, it involves the problem of reverse accessibility, because the next jump does not necessarily know the accessibility of the address.
Resolution of 4.NAT problem
The problem with NAT is that it only exists when Snat becomes a different address. There are two different situations here, the first scenario is that Snat becomes an unrelated network segment address, which requires that the next hop configuration to the address route ensure that the reverse packet of the stream can be returned to this box, which can be manually configured in a simple environment, In the complex environment, the Snat address can be declared by dynamic routing method. The second situation is that the Snat address is the same network segment as the next hop, which will cause the data stream reverse packet to return to the next hop, the Snat address at this time the target address, because in the same network segment, so will be directly ARP , you need to add an ARP conversion rule:
Arptables-t mangle-a output-d Next hop gateway address-j mangle--mangle-ip-s
Knowing the problem and the solution, you can do it now. The goal of this article is to achieve a similar Cisco NVI, that is, a virtual network card in the virtual network card delivery process to achieve NAT. In view of the loopback so good ready-made things, I will no longer write virtual network card, directly with the loopback analog one or. The overall process is as follows:
Packets from the physical network card into the-> execution dnat-> route to loopback-> execution snat->loopback Port emit-> policy route-> physical network card issued
As you can see, the route was executed two times, for the first time for Nat, and the second for real routing.
In addition to using loopback, writing a virtual NIC similar to Veth is a better choice:
Veth stands for Virtual ETHernet. It is a simple tunnel driver which works at the link layer and looks like a pair of Ethernet devices interconnected
With each other.
Better than loopback, this basically does not modify the code to implement the NVi, and it is easy to access the packet raw entry interface. The logic of the drive is very simple, that is, a pair contains a main interface and an auxiliary interface, data packets from the main interface into the secondary interface that is routed to the main interface, note, do not change the SKB receive interface, this so-called routing is only to make a "from the physical network card received to send to another network card action", At this point, the prerouting/postrouting is complete, and the real route can be sent from another main interface.
This is not urgent to write their own virtual network card, first toss after loopback, then do it now!
1. Modifications to the code:
Re-encapsulate the nf_inet_pre_routing hook function of the raw table, calling the following logic before the Ipt_hook call:
Judgment is a bit reckless, and normal should be designed to be a matching algorithm.
if (Skb->dev->flags & Iff_loopback && skb->nfct) {
SKB->NFCT = &nf_conntrack_untracked.ct_general;
Skb->nfctinfo = ip_ct_new;
Nf_conntrack_get (SKB->NFCT);
Skb_dst_drop (SKB);
return nf_accept;
}
This code means that if the packet is entered from the physical network card, it is obviously necessary to match and apply the rules (such as NAT), if the matter is done, the data is to be routed through the loopback interface, then do not use the Conntrack, At this point, however, the nfct of the SKB may have been set, then notrack it and discard the SKB routing cache. Linux IP routing is so treated loopback, if the result of routing query is Loopback interface, is directly set Dst,loopback xmit send packets, call a NETIF_RX to receive, reach Ip_rcv_ When you finish, you don't have to query for routing because you already have DST. But if so, our second routing query--which is actually a policy-routed query-will not be implemented, so you must drop the original DST.