Chapter 12: Networks
12.8.4 Packet Forwarding
IP packets may be delivered locally as described above, or they may leave the IP layer for forwarding to
another computer without having come into local contact with the higher protocol instances. There are
two categories of packet destinations:
- Target computers in one of the local networks to which the sending computer is attached.
- Geographically remote computers not attached to the local network and accessible only via
gateways.
The second scenario is rather more complicated. The first station to which the packet is forwarded along
the remaining route must be found in order to move onestep closer to the final destination. Information
is therefore required not only on the structure of the network in which the computer resides but also on
the structure of the ‘‘adjacent‘‘ networks and associated outgoing paths.
This information is provided byrouting tablesmanaged by the kernel in a variety of data structures
discussed in Section 12.8.5. Theip_route_inputfunction invoked when a packet is received acts as the
interface to the routing implementation, not only because it is able to recognize whether a packet is to be
delivered locally or forwarded, but also because it also finds the route to the destination. The destination
is stored in thedstfield of the socket buffer.
This makes the work ofip_forwardvery easy, as the code flow diagram in Figure 12-17 shows.
TTL ≤ 1? Discard packet
ip_forward
ip_decrease_ttl
ip_forward_finish
ip_forward_options
dst_output skb->dst->output
Netfilter hook NF_IP_FORWARD
Figure 12-17: Code flow diagram forip_forward.
First, the function refers to the TTL field to check whether the packet is allowed to pass through another
hop. If the TTL value is less than or equal to 1, the packet is discarded; otherwise, the counter is decre-
mented by 1.ip_decrease_ttldoes this because changing the TTL field also means that the packet
checksum must be altered.
Once the netfilter hookNF_IP_FORWARDhas been called, the kernel resumes processing in
ip_forward_finish. This function delegates its work to two other functions: