Fundamentals 28 min read

How Linux Connection Tracking Works: Inside Netfilter and NAT

This article explains the principles, applications, and Linux kernel implementation of connection tracking (conntrack), covering its role in NAT, L4 load balancing, key data structures, hook mechanisms, and performance considerations with detailed code examples.

ITPUB
ITPUB
ITPUB
How Linux Connection Tracking Works: Inside Netfilter and NAT

Introduction

Connection tracking (conntrack, CT) is the basis of many Linux networking features such as Kubernetes Service, service‑mesh sidecars, LVS/IPVS, Docker networking, OVS and iptables firewalls. It records the state of each connection by extracting a tuple from packets, maintaining a conntrack table, recycling expired entries, and providing information for higher‑level functions like NAT.

Concept

Conntrack stores a tuple that uniquely identifies a unidirectional flow. Unlike the TCP/IP notion of a session, a tuple can represent UDP, ICMP or other L3/L4 protocols.

Network Address Translation (NAT)

NAT rewrites the IP+Port of packets. For example, a private address 192.168.x.x is replaced with the host’s public IP (e.g., 10.1.1.2) before leaving the machine, and the reverse translation is applied to returning packets. Types of NAT include SNAT (source translation), DNAT (destination translation) and Full NAT (both). NAT relies on conntrack results.

Layer‑4 Load Balancing (L4 LB)

L4 LB distributes traffic based on Layer‑4 fields (src/dst IP, src/dst port, protocol). A Virtual IP (VIP) maps to multiple real backend IPs; packets arrive at the VIP and are forwarded to a selected backend, often using NAT to rewrite addresses.

Principles

Intercept every packet passing through the machine.

Build or update a connection‑state database (conntrack table).

Continuously refresh the database as new packets arrive.

Performance is critical because each packet is examined.

Netfilter Hook Mechanism

Netfilter provides five IPv4 hook points:

#define NF_IP_PRE_ROUTING   0
#define NF_IP_LOCAL_IN      1
#define NF_IP_FORWARD       2
#define NF_IP_LOCAL_OUT     3
#define NF_IP_POST_ROUTING  4
#define NF_IP_NUMHOOKS      5

Handlers registered at a hook return one of the following verdicts:

#define NF_DROP   0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE  3
#define NF_REPEAT 4

Netfilter Framework

The primary modules are the conntrack (CT) module and the NAT module. CT identifies trackable packets; NAT performs address translation based on CT results.

Rule Organization

iptables configures Netfilter rules, which are grouped into tables such as raw, filter, nat and mangle.

Conntrack Implementation

Conntrack maintains a hash table of active flows and currently supports six protocols: TCP, UDP, ICMP, DCCP, SCTP and GRE.

Key Structures

struct nf_conntrack_tuple

: defines a tuple (source and destination information). struct nf_conntrack_tuple_hash: hash‑table entry for a tuple. struct nf_conn: represents a connection (flow) and stores status, timeout and protocol‑specific data.

Important functions: hash_conntrack_raw(): computes a 32‑bit hash from a tuple. nf_conntrack_in(): core entry point for new packets. resolve_normal_ct()init_conntrack()l4proto->new(): creates a new conntrack entry. nf_conntrack_confirm(): moves an entry from the unconfirmed list to the confirmed list after the packet passes later hooks.

Tuple Details

For IPv4 UDP the tuple fields are src.protonum, src.u3.ip, dst.u3.ip, src.u.udp.port and dst.u.udp.port.

L4 Protocol Interface

Each trackable protocol implements struct nf_conntrack_l4proto, providing callbacks such as pkt_to_tuple(), packet(), new() and error().

Conntrack Core Flow

Retrieve any existing conntrack record for the packet.

If tracking is not needed, increment the ignore counter and accept the packet.

Extract L4 information and obtain the protocol‑specific handler.

Run protocol‑specific error checks.

Call resolve_normal_ct() to create or update a conntrack entry.

Invoke the protocol’s packet() callback for further processing.

Confirmation

After nf_conntrack_in() creates an entry, nf_conntrack_confirm() is called at POST_ROUTING (outbound) or LOCAL_IN (inbound) to mark the entry as confirmed and move it to the main hash table.

NAT Implementation

NAT is a separate module that relies on conntrack results. Supported protocols must implement struct nf_nat_l3proto and struct nf_nat_l4proto callbacks.

Core NAT Function

The function nf_nat_inet_fn() is invoked at all Netfilter hooks except NF_INET_FORWARD. It looks up the conntrack entry; if none exists, NAT cannot be applied.

If a NAT rule is present, nf_nat_packet() calls nf_nat_manip_pkt(), which uses the appropriate L3/L4 protocol handlers to rewrite packet headers.

NAT Types

Typical NAT configurations replace one IP with another (e.g., IP1 → IP2). Masquerade rewrites the source IP to the outgoing interface’s address, automatically adapting to IP changes.

Design Alternatives

While Netfilter is the common implementation, any system with hook capability can implement its own conntrack. Cilium, for example, uses BPF hooks to provide an independent conntrack and NAT mechanism starting from version 1.7.4 (kernel ≥ 4.19). Its conntrack data is stored in BPF maps, not in the Netfilter tables, and is managed with commands such as:

$ cilium bpf nat list
$ cilium bpf ct list global

Configuration options include --bpf-ct-tcp-max and similar flags.

Summary

Conntrack is a fundamental kernel module that tracks connection state for a limited set of protocols. In high‑concurrency scenarios such as L4 load balancing, the conntrack table can become a bottleneck, leading to silent packet drops if the table is too small or garbage collection is insufficient.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Linux kernelNATconntracknetfilterpacket filtering
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.