The Network Stack: Helping Linux Systems Communicate

0
26
linux-network-stack

The socket stack, the protocol stack and the network device drivers in the latest Linux versions offer great support for networking. This is how they work…

Version 0.01 of the Linux kernel was released to the public on May 14, 1991, with no support for networking. This first version relied heavily on 80386-compatible Intel processors and PC hardware. The release of Linux 1.0 on March 14, 1994, ushered a major revolution in open source technology as it introduced support for networking through UNIX’s standard TCP/IP networking protocols as well as a BSD-compatible socket interface for network programming.

Communication-between-layers-of-the-network-stack
Figure 1: Communication between layers of the network stack

Ever since, Linux has undergone major upgrades and now has three layers — the socket stack, the protocol stack, and the network device drivers.

The socket stack

This layer takes care of all the networking requests by user applications.

The protocol stack

This is a framework for networking data arriving either from an application socket or a network device driver. It is tagged with an identifier, specifying which network protocol they contain. Protocols can communicate with each other, manage routines, report errors and perform reliable transmission of lost data. The main task of this layer is to decide which socket or device it will send a packet to. It may rewrite the packets, split them, reassemble packets into fragments, or simply discard incoming data. Once the protocol layer has finished processing a set of packets, it passes them on upward to the socket interface or device driver according to the nature of the connection.

The communication between the layers of the network stack takes place by passing a single skbuff (socket buffer) structure. Each structure packs a set of pointers into a single contiguous memory representing a buffer, inside which network packets can be constructed. This allows flexibility in manipulating packet headers and checksums while avoiding unnecessary data copying.

In Linux and all modern operating systems, the TCP/IP suite is fundamental to networking. The IP protocol manages the routing of data, while protocols like TCP, UDP, and ICMP provide layers of functionality to meet different communication needs.

  • IP routes packets.
  • TCP ensures reliable delivery.
  • UDP offers fast, unreliable delivery.
  • ICMP diagnoses network issues.

When skbuff() arrives at the network stack’s protocol software, it is identified by the device driver since different network device drivers encode the protocol type in different ways. The device driver uses a hash table of known networking protocol identifiers to look up the appropriate protocol and passes the packet to that protocol.

Network device driver

Once the packets are delivered by skbuff() to the driver, the job of this layer is to perform routing. After deciding where to send the packet, the driver forwards the packet to the internal protocol driver to be delivered locally or injects it back into a selected network device driver queue to be forwarded by another host.

The routing is performed based on two tables — FIB or forwarding information base, and the cache of recent routing decisions.

When an incoming packet arrives, the system first checks the routing cache, which stores recently used routing decisions. If a matching entry is found (a cache hit), the cached route is used, allowing the system to quickly forward the packet without performing a full lookup. If there is no match (a cache miss), the system performs a lookup in the FIB. The FIB is the main routing table managed by the kernel and is responsible for determining the correct next-hop and network interface based on the destination IP address. This table is optimised for fast lookup and is continuously updated by routing utilities and daemons (such as through the ip route command). Once the FIB determines the appropriate route, the packet is forwarded accordingly, as shown in Figure 2.

Packet-forwarding-mechanism
Figure 2: Packet forwarding mechanism

In older versions of the Linux kernel, the result of this lookup could be added to the routing cache to speed up future decisions. However, in modern Linux kernels (version 3.x and above), the global routing cache has been deprecated due to performance and scalability concerns, and routing optimisations are now handled differently. Despite these changes, the FIB remains the authoritative and essential part of the Linux routing process.

The other functions performed by the IP driver are disassembly and reassembly of large packets. When an outgoing packet exceeds the size limitations of a network device, the IP driver automatically fragments it into smaller pieces that can be individually queued for transmission. On the receiving end, these fragments must be reassembled to reconstruct the original packet. To manage this, the IP layer maintains an ipfrag object for each fragment awaiting reassembly and an ipq (IP queue) structure for each datagram in the process of being reassembled. As fragments arrive, they are matched against existing ipq entries; if no match is found, a new ipq is created. Once all fragments for a particular ipq have arrived, the driver constructs a new skbuff to represent the complete packet. This functionality ensures that data transmission remains robust and reliable, even when large packets must be divided to traverse networks with varying MTU (maximum transmission unit) limits.

LEAVE A REPLY

Please enter your comment!
Please enter your name here