Fundamentals 18 min read

Understanding Linux Network Namespaces: Implementation, Usage, and Internals

This article explains how Linux network namespaces provide isolated network stacks by using virtual Ethernet devices, kernel data structures, and per‑namespace routing and iptables, offering step‑by‑step commands, code excerpts, and deep insight into the kernel mechanisms that enable container networking isolation.

Refining Core Development Skills
Refining Core Development Skills
Refining Core Development Skills
Understanding Linux Network Namespaces: Implementation, Usage, and Internals

1. How to Use netns

We create a new network namespace net1 , add a pair of veth devices, move one end into net1 , assign IP addresses, bring the interfaces up, and verify communication with ping . The commands used are ip netns add net1 , ip link add veth1 type veth peer name veth1_p , ip link set veth1 netns net1 , and the subsequent ip addr and ifconfig steps.

2. Kernel Definition of Namespace

Each process is represented by struct task_struct which contains a pointer to struct nsproxy . The nsproxy holds pointers to various namespaces, including the network namespace struct net *net_ns . Network devices ( struct net_device ) and sockets ( struct sock_common ) also store a reference to their owning net object.

2.1 Network Namespace Core Structure

The core struct net includes a loopback device, routing tables, and iptables structures, e.g., struct netns_ipv4 ipv4 which contains fib_table pointers for routing and xt_table pointers for iptables.

2.2 Registration of Subsystems

Kernel subsystems register their initialization functions via register_pernet_subsys , which adds them to the global pernet_list . When a new namespace is created, setup_net iterates over this list and calls each subsystem’s init function, creating isolated routing tables, iptables, etc.

3. Creation of a Network Namespace

The default namespace init_net is set up for the init process (PID 1). Creating a new namespace involves copy_net_ns , which checks the CLONE_NEWNET flag; if set, it allocates a fresh struct net and calls setup_net to initialize all subsystems.

3.1 Adding Devices

New devices are initially attached to init_net via alloc_netdev_mqs . They can later be moved to another namespace with dev_change_net_namespace , which updates the device’s nd_net pointer.

4. Network I/O Within a Namespace

Sockets inherit the namespace of the creating process; the kernel stores this in skc_net. When sending packets, functions like ip_queue_xmit retrieve the socket’s namespace via sock_net(sk) and use it to look up the appropriate routing tables ( fib_lookup ) and iptables chains, ensuring isolation between namespaces.

5. Conclusion

Linux network namespaces achieve logical isolation by providing each namespace with its own struct net containing independent routing tables, iptables, and devices. Although there is a single underlying network stack, the per‑namespace pointers make it appear as multiple isolated stacks, which is the foundation for container networking such as Docker.

DockerKernellinuxisolationNetwork NamespaceVirtual Ethernet
Refining Core Development Skills
Written by

Refining Core Development Skills

Fei has over 10 years of development experience at Tencent and Sogou. Through this account, he shares his deep insights on performance.

0 followers
Reader feedback

How this landed with the community

login 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.