fir3net
PPS-Firenetbanner-780.5x190-30-03-17

The Journey of a Frame through a Linux Based System

 

Contents[Hide]

Abstract

The scope of this article is to describe, at a high level, the journey a frame takes through a Linux based system.

NOTE This article does not cover Linux kernel performance issues and caveats, for more information around this please see pushing the limits of kernel networking.

Ingress

Lets first look at the path an ingress frame would take.takes (Figure 1).

  1. Frame is received by the network adapter.
  2. Frame is moved (via DMA) to a RX ring buffer in kernel memory*.
  3. The NIC notifies the system of that there is a new frame ready for processing by raising a hardware interrupt (IRQ)**.
  4. The IRQ is cleared on the NIC and the kernel executes the device driver which drains the RX ring via SoftIRQs.
  5. The SoftIRQs place the frames into a kernel data structure called an sk_buff or "skb" (i.e socket buffer).
  6. The frame is passed up through the networking stack for further processing.
  7. The packet finally arrives at the receive socket buffer (also known as the receive window).
  8. Application calls the read system call. The area is changed to the kernel area and the data in the socket buffer is copied to the userspace of the application.

*RX ring buffer - the ring buffer is a circular buffer (FIFO). This means an overflow will simply overwrite existing data.
**Interrupts - Hardware (also known as top-half) interrupts can be expensive in terms of CPU usage, it alerts the CPU to a high-priority condition requiring the processor to suspend what is currently doing, saving its state and then initialize an interrupt handler to deal with the event. The hard interrupt handler then leaves the majority of packet reception to a software (also known as bottom-half) interrupt process which can be scheduled more fairly[1].  

Figure 1 - High Level overview of components involved in Frame Reception/Delivery.

Egress

Now lets look at the path an egress frame would take (Figure 1).

  1. Application performs a write() on the socket.
  2. Frame is copied from the applications user space to the send socket buffer.
  3. Frame is passed down the stack to the output queue (qdisc).
  4. Frame is passed to the device driver, who moves it to a TX ring buffer.
  5. The device driver invokes the NIC DMA engine to transmit the frame onto the wire.
  6. Once transmission is complete, the device raises an interrupt to signal transmit completion.
  7. The device drivers IRQ handler runs and triggers SoftIRQs.
  8. SoftIRQs unmap the DMA regions and frees the packet data.

NAPI

Introduced within the Linux Kernel 2.4.20, NAPI (New API) reduces the amount of hard IRQs raised by network adapters for ingress frames. It works by disabling hard IRQs from the NIC, packets are then pulled from the RX ring buffer by the NAPI subsystem. Once the RX ring buffer is empty, IRQs from the NIC are re-enabled.

Sources

[1] https://access.redhat.com/sites/default/files/attachments/20150325_network_performance_tuning.pdf

Further Reading

http://rhelblog.redhat.com/2015/09/29/pushing-the-limits-of-kernel-networking/ 
http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf 
https://blog.selectel.com/introduction-dpdk-architecture-principles/ 
https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data
http://www.cubrid.org/blog/understanding-tcp-ip-network-stack

Tags: Linux, Kernel, SoftIRQ, HardIRQ, SocketBuffer, SKB

About the Author

RDonato

R Donato

Ricky Donato is the Founder and Chief Editor of Fir3net.com. He currently works as a Principal Network Security Engineer and has a keen interest in automation and the cloud.

You can find Ricky on Twitter @f3lix001