Linux Networking, From First Principles

Understand the objects. Compare the architectures. Build the network. Explain the packets.

This is a lesson and a practical reference for someone who can use a Linux terminal but has not yet formed a clear picture of networking. You do not need to have read another document or completed an earlier lab.

We will eventually build three hosts named host1, host2, and host3, connected to the Linux bridge br1 inside the namespace bridge1. But first we will learn what each of those words means. Afterwards, we will add a router and a fourth host to discover what changes when traffic crosses into another IP subnet.

The main examples use IPv4 over Ethernet. Advanced features such as VLAN filtering, policy routing, proxy ARP, overlays, and NAT are not enabled in the lab. When a statement depends on that simple setup, the surrounding explanation says so.

How to use this lesson

For the first read, follow Part I → Part II → Part III. In the lab, stop at each Predict → Observe → Explain checkpoint instead of pasting the entire section at once. On a later visit, use the command reference and the troubleshooting questions at the end.

Part The question it answers
I. Separate the concepts What is each object, and what does it actually do?
II. Compare the architectures What changes when we connect the objects differently?
III. Build the lab How do we construct and inspect each architecture?
IV. Remember and troubleshoot How do we recall the model and locate a fault?
Sources and validation Where can we check the details, and what was tested?

Part I - Separate the concepts

Commands in this part illustrate a concept. The complete, sequential setup starts in Part III. Do not create or delete anything yet.

1. A network is more than an IP address

Imagine two laptops. Giving one the address 10.0.0.11/24 and the other 10.0.0.12/24 does not connect them. They still need a usable communication path: a cable, a wireless link, or a virtual link. The operating system also needs to know which interface to use and, when necessary, which router should receive the traffic next.

Separate these four questions:

Question Relevant concept
Where can traffic enter or leave this network stack? Interface
What actually connects the endpoints? Link, such as Ethernet or a veth pair
How does traffic reach another local endpoint? Ethernet addressing and, when present, switching
How does traffic reach an IP destination through the appropriate next hop? Routing

A host is an endpoint that originates or receives traffic. A LAN, or local area network, connects nearby or logically adjacent endpoints. In our simple switched lab, the LAN is one Ethernet broadcast domain: a broadcast can reach the other attached hosts. The Internet is not required for a LAN to function.

Remember: configuring an address describes a destination or interface; it does not create a connection.

2. Frames, packets, protocols, and ports

Networking uses layers because different problems require different information. For this lesson, concentrate on these layers rather than memorising all seven OSI layer names.

Level What it handles Example information
Application What the programs want to do An HTTP request
Transport Communication between application endpoints TCP or UDP port numbers
Network, usually called Layer 3 Delivery towards an IP destination Source and destination IP addresses
Link, usually called Layer 2 Delivery over the current local link Source and destination Ethernet MAC addresses

A protocol is a set of rules and message formats that communicating systems understand. An IP packet is a unit of IP traffic. An Ethernet frame is the Layer-2 unit that carries data across an Ethernet link; its payload may be an IP packet. IP specification · TCP specification · UDP specification

An Ethernet frame contains an IP packet, which carries transport and application data or an ICMP message.

Read the image from the outside in: the Ethernet header answers “which local Ethernet destination?”, while the IP header answers “which IP destination?”. These are not necessarily the same device. A router can be the local Ethernet destination while another host is the final IP destination.

The word port has two different meanings you must keep separate. A switch port is a connection point on a switch; in a Linux bridge, it is an attached interface. A TCP or UDP port, such as TCP 8000, is a number used to distinguish application endpoints. Attaching an interface to a bridge does not open TCP port 8000.

ping sends ICMP echo requests and receives echo replies; it is not an HTTP test and does not use a TCP or UDP destination port. A successful ping is useful evidence of IP reachability, but it does not prove that a website, database, or application is healthy. ping manual · ICMP specification

Remember: a frame is the local-link envelope; a packet carries the IP addressing inside it.

3. What is a network interface?

A network interface is an object through which a network stack sends or receives traffic. Linux exposes interfaces through commands such as ip link. An interface can be backed by physical hardware, by a virtual device presented to a VM, or entirely by software inside Linux. Device interface · Device management

An interface has properties such as a name, a device type, an administrative state, and an MTU. An Ethernet interface also has a MAC address. It can have no IP addresses, one IP address, or several. An interface and an IP address are not the same object. Address management

For example, in our lab:

Name:       eth1
Type:       veth endpoint
Namespace:  host1
IPv4:       10.0.0.11/24, once we assign it
Role:       host1's connection to the lab LAN

Names do not reliably tell you the type

eth0, eth1, ens3, enp2s0, veth123, and br0 are names. Some follow system naming conventions, while others were chosen by a person or program. We can name a veth endpoint eth1; that does not turn it into physical hardware.

Use these commands to examine the object rather than guessing from its name:

ip -br link
ip -d link show
ip -br addr

link shows devices and link properties. addr shows address assignments. -br asks for a brief view; -d asks for additional details, useful for identifying virtual device types. ip command

Interface types: learn the first four, recognise the rest

Device or type What it is What it is not
Ethernet NIC An interface for an Ethernet connection. It may be physical or presented virtually to a guest OS. Not necessarily a router or switch.
Loopback, normally lo A software interface for local delivery within the same network namespace. Not a cable to another namespace.
Veth endpoint One of two connected virtual Ethernet interfaces. Not a multi-port switch.
Linux bridge, such as br1 A software Layer-2 switch exposed as a network device. Other interfaces can become its ports. Not automatically an IP router.
Wi-Fi interface An interface to a wireless link. Not interchangeable with a veth cable in every bridging configuration.
TAP A virtual interface exchanging Ethernet frames with a userspace program, such as a virtual-machine monitor. Not automatically paired with another TAP interface.
TUN A virtual interface exchanging IP packets with a userspace program; often used in tunnelling designs. Not an Ethernet interface carrying ordinary Ethernet headers.
VLAN interface A logical interface associated with an 802.1Q VLAN on another device. Not a separate physical cable or an automatic router.
Bond A logical device grouping multiple member interfaces for modes such as redundancy or traffic distribution. Not a mechanism for giving hosts separate network stacks.
VXLAN device A device that encapsulates Ethernet traffic over an IP/UDP network. Not the simple, local two-ended connection of a veth pair.

The first four are the focus of this course. The other rows are a recognition guide, not additional configuration you need for this lab. veth · Linux bridge · TUN/TAP · VLAN and bond types · VXLAN

“UP” has more than one meaning

An interface can be administratively enabled while its link is not usable. In detailed output, UP inside the flags means administratively enabled; LOWER_UP means the driver reports lower-layer carrier. The operational state is another field. state UNKNOWN is not automatically a fault: loopback commonly works in that state. Kernel operational states

Similarly, bringing an interface up does not assign an address, create a route to every network, or attach it to a bridge. Those are separate operations.

The MTU is the maximum transmission unit of the interface; for an Ethernet IP interface, an MTU of 1500 normally permits an IP packet of up to 1500 bytes, not a complete Ethernet frame of only 1500 bytes. MTU matters when links or tunnels impose different size limits, but the lab leaves it unchanged. Interface controls · IP specification

Remember: existence, type, namespace, state, address, and bridge membership are separate properties.

4. What is a network namespace?

A network namespace gives processes a separate view of networking resources: interfaces, IP protocol stacks, routes, neighbour information, firewall rules, and socket/port spaces. An interface is visible within the namespace that owns it. Network namespaces

We will use namespaces as lightweight simulated hosts:

One Linux kernel
├── Normal shell's network namespace
├── host1: its own interfaces, routes, neighbours and sockets
├── host2: its own interfaces, routes, neighbours and sockets
├── host3: its own interfaces, routes, neighbours and sockets
└── bridge1: its own interfaces, including the bridge br1

A network namespace is not a virtual machine and not a running process. Multiple processes can use it; it can also exist without a process actively running inside it. Creating only a network namespace does not give it a separate kernel, filesystem, or hostname. Other namespace types address other forms of isolation. Namespace overview · Named namespace lifecycle

The namespace name does not create a network role

Naming a namespace bridge1 does not create a bridge inside it. Naming one router1 does not enable routing between interfaces. These are ordinary names; the devices and configuration determine the role.

Also distinguish the initial or default network namespace from the root user. A root process can run inside another network namespace. sudo changes privileges; it does not, by itself, mean “enter the initial namespace”.

Which namespace does a command inspect?

ip addr

This examines the calling process's current network namespace.

sudo ip -n host1 addr

This tells the ip program to inspect host1.

sudo ip netns exec host1 ping -n -c 3 10.0.0.12

This runs another program, ping, in host1. The distinction matters because a route in the normal shell's namespace is not automatically a route in host1. ip-netns manual

Remember: before interpreting networking output, ask “which network namespace am I looking at?”

5. What exactly is lo?

lo is Linux's usual name for the loopback interface. It provides a local networking path: traffic can go from a process into its network stack and back to a local recipient without using an external Ethernet connection.

The familiar IPv4 loopback address is 127.0.0.1; Linux treats the 127.0.0.0/8 range as loopback. The IPv6 loopback address is ::1. The hostname localhost normally resolves to a loopback address. lo is the interface name; 127.0.0.1 is an address, and localhost is a name. Linux IPv4 addresses · IPv6 loopback · Localhost name

Each network namespace has its own loopback path, so host1 and host2 can both use 127.0.0.1:8000 independently.

“Local” means this network namespace

Suppose a server in host1 listens on 127.0.0.1:8000. A client in host1 can connect to it. A client in host2 connecting to 127.0.0.1:8000 is trying to reach a server in host2, not the server in host1. The same address is not a shared meeting point between the namespaces.

That is why two separate network namespaces can independently have a listener on the same local address and TCP port. Within a shared namespace, the normal binding/conflict rules still apply. Network namespace socket isolation · IP socket binding

When do we use it?

A program may expose a development HTTP server, a local database, or an administrative endpoint only on loopback. Another local program can use that endpoint without exposing it through a non-loopback listening address.

In an ordinary configuration, binding to 127.0.0.1 limits a service to loopback. Binding to 0.0.0.0 means accepting IPv4 connections for all local IPv4 addresses in that namespace; it does not bypass firewall rules or create routes. 0.0.0.0 is a wildcard for the listener, not the address clients should use to reach it. Linux IPv4 socket addresses

What a loopback ping does not prove

ping -n -c 3 127.0.0.1

This does not test a veth pair, a bridge, a gateway, another host, or Internet connectivity. It is a local test.

There is an additional trap: pinging your own non-loopback IP address is not a reliable link test either. Linux normally has a local route for addresses assigned to the namespace, so traffic to its own address can be delivered locally. Later, ip route get will reveal that path. Local routes

Why bring lo up in the lab?

A newly created network namespace has a loopback device that normally starts administratively down. We enable it so local network communication works. That does not connect the namespace to another host. Conversely, loopback is not what a bridge uses to forward frames between bridge ports. Namespace configuration · Bridge forwarding

Remember: lo means “back into this network stack”, not “out to the other hosts”.

6. Ethernet and MAC addresses

Ethernet frames carry source and destination MAC addresses. A typical Ethernet MAC is written as six hexadecimal bytes, for example 02:00:00:00:00:11. Virtual Ethernet interfaces also have MAC addresses; a MAC address is not proof of a physical network card. Ethernet address format and resolution · Virtual Ethernet devices

For the normal unicast traffic in our lab, the source MAC identifies the Ethernet sender on the current link, and the destination MAC identifies the intended Ethernet recipient on that link.

Unicast targets one recipient. Broadcast uses the Ethernet destination ff:ff:ff:ff:ff:ff, reaching eligible endpoints in the same broadcast domain. Multicast targets a group; it exists, but our exercises focus on unicast and ARP broadcasts.

On a same-LAN ping, the Ethernet destination is the other host. On a ping through a router, the first Ethernet destination is the router's local interface. The final IP destination remains the remote host. ARP next-hop resolution · IPv4 forwarding

For clarity, diagrams sometimes use labels such as MAC-H1 and MAC-R-left. They are explanatory aliases, not literal values you can paste into a command. The lab lets Linux generate actual MAC addresses; you inspect them with ip link.

Remember: an IP destination may be many hops away; the Ethernet destination is for the current local hop.

7. What is a veth pair?

A veth pair consists of two interconnected virtual Ethernet devices. A frame transmitted through one endpoint is received at the other. The endpoints can be in the same network namespace or in different ones. veth manual

host1 eth1 and host2 eth2 are the two endpoints of a single veth pair.

The useful analogy is a virtual Ethernet cable with an interface at each end. The cable analogy is not a third kernel interface: the pair contains two interface objects.

For the direct architecture above, eth1 belongs to host1 and eth2 belongs to host2. They have different names and MAC addresses. The pair itself does not assign their IP addresses, add a gateway, or provide a third endpoint.

A bridge changes the arrangement: one veth pair connects host1 to a bridge-side port, a different pair connects host2 to another bridge-side port, and the bridge switches frames between those ports. We do not use one three-ended veth pair.

Deleting a veth endpoint also removes its peer. Taking an endpoint down is a different operation: it disables the link without deleting the pair. This distinction will be important when we replace the direct link with a switched network. veth lifecycle · Link operations

Remember: two hosts directly connected need one pair; three hosts separately attached to a bridge need three pairs.

8. Bridge, switch, bridge port: what is the difference?

A Layer-2 Ethernet switch forwards frames between ports using Ethernet addressing. A Linux bridge implements that switching role in software. For this lesson, “bridge” and “software Layer-2 switch” describe the same forwarding role; a bridge is not limited to only two ports. A device sold as a Layer-3 switch can additionally route, but that is a separate capability. Linux Ethernet bridging

A Linux bridge is itself a network device. Other interfaces become its ports by being attached to it. In the original three-host layout:

bridge1       = the network namespace
br1           = the Linux bridge device in that namespace
veth1-br      = one veth endpoint, attached as a port of br1
bridge        = a command-line tool for inspecting/configuring bridges

These four things are different.

What does attaching an interface do?

Conceptually, attaching veth1-br to br1 makes frames arriving on veth1-br available to the bridge's forwarding logic. A command such as ip link set veth1-br master br1 sets that relationship. The word master here is an iproute2 device relationship, not another computer. Link attachment · Bridge management

Does a bridge need an IP address?

Not merely to switch Ethernet frames. In our lab, br1 and its bridge-side ports have no IPv4 addresses. The endpoint hosts have IPv4 addresses because their IP stacks originate and receive our pings.

A bridge can have an IP address when the Linux system itself needs to participate at Layer 3 on that bridged network, for example for management or as part of a gateway design. That is different from the transit frames being switched. In a conventional bridged host setup, the Layer-3 configuration belongs on the bridge device, not separately on each member port. Linux bridge model · Bridge setup example

Does the bridge rewrite the hosts' MAC addresses?

Not during ordinary transparent forwarding in this lab. An Ethernet frame from host1 to host2 keeps the hosts' source and destination MAC addresses as it crosses br1. The bridge has MAC addresses of its own for its own traffic; their existence does not mean every transit frame is rewritten to originate from the bridge.

The bridge's lookup table and learning behaviour are explained in Concept 11.

Remember: the veth pair gets a frame to a switch port; the bridge decides which other port should receive it.

9. IP addresses, subnets, and CIDR

An IPv4 address is 32 bits. The suffix in an address such as 10.0.0.11/24 is the prefix length: 24 bits define the network prefix, leaving 8 bits for addresses within that prefix. CIDR notation expresses networks using these prefixes. CIDR

The first three octets in 10.0.0.11/24 form the 24-bit prefix, while the final octet is the remaining address part.

For this particular /24:

Value Meaning
10.0.0.11 Host1's assigned address
/24 Prefix length
255.255.255.0 Equivalent subnet mask
10.0.0.0/24 Network prefix
10.0.0.255 Broadcast address for this /24
10.0.0.1 through 10.0.0.254 Conventional host address range used in this lesson

These are consequences of the chosen prefix. An address ending in .255 is not universally a broadcast address regardless of prefix. We use conventional host addresses to keep the exercises portable and easy to recognise. Linux IPv4 special addresses

With our normal connected routes, host1 regards 10.0.0.12 as on-link through its 10.0.0.11/24 interface. 10.0.1.14 is outside that prefix. Reaching it requires a suitable route, which can point through a router.

Two independent requirements

The right prefix does not provide a physical or virtual link. Two isolated namespaces can have addresses in 10.0.0.0/24 and still have no path between them.

Conversely, attaching two interfaces to the same unsegmented bridge does not automatically make their IPv4 addresses part of the same subnet. Two hosts with different /24 networks can share Ethernet connectivity while lacking the routes needed for IP communication. This distinction is about Layer-2 topology versus Layer-3 addressing.

Remember: the prefix describes the IP network; it does not build the Ethernet network.

10. Routing, next hops, and the default gateway

The routing table helps Linux decide how to handle an IP destination. For ordinary traffic in our lab, a route identifies an outgoing interface and may specify a next hop: the neighbouring router to which the packet should be sent. Linux also maintains local routes for its own addresses. Route types and lookup

After we assign 10.0.0.11/24 to eth1 and bring it up, the normal connected route looks like:

10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.11

Read it as: “For this connected prefix, use eth1; 10.0.0.11 is the preferred source address shown for this route.” No gateway is listed because this is an on-link route.

Later we will add:

10.0.1.0/24 via 10.0.0.1 dev eth1

Read it as: “For 10.0.1.0/24, send through the neighbour 10.0.0.1, using eth1.” The gateway address must itself be reachable on that link in our ordinary configuration.

A default route is the fallback, not the path for everything

default via 10.0.0.1 dev eth1

default means the prefix 0.0.0.0/0. Within the selected routing table, the most specific matching prefix takes precedence. Thus a /24 route for local traffic wins over a /0 default route. Policy routing can influence which table is used, but we do not configure it here. Routing table and rules · IPv4 route selection

A default gateway is the router used by a default route. A gateway is not special because its address ends in .1; that is merely our address-plan choice. A route also does not need to be a default route: our routed lab uses explicit routes to the other /24 so the intention stays visible.

A host does routing lookups; a router also forwards other hosts' traffic

Both hosts and routers consult routes. The additional action performed by a router is forwarding a received packet onwards when it is not addressed to the router itself. In our Linux router namespace, IPv4 forwarding must be enabled, suitable routes must exist, and filtering must permit the traffic. Kernel IPv4 forwarding setting

The fact that a computer has two interfaces or can ping both LANs does not by itself prove that it forwards traffic between those LANs.

Routing is not NAT

Routing chooses where a packet goes. NAT, network address translation, changes address information; some forms also translate transport ports. We do not need NAT for two lab subnets when both sides have the correct routes, including a return path. A firewall is a further, separate mechanism that can permit or deny traffic. Traditional NAT terminology

Remember: routing chooses a path; forwarding carries another host's packet along it; NAT changes addressing.

11. ARP and the bridge forwarding database answer different questions

The routing table maps IP prefixes to paths, the neighbour table maps next-hop IP addresses to local MAC addresses, and the bridge FDB maps MAC addresses to ports.

ARP: “Which MAC address belongs to this next-hop IPv4 address?”

For IPv4 over Ethernet, ARP, the Address Resolution Protocol, resolves a local next-hop IPv4 address to an Ethernet MAC address. If host1 needs to send directly to 10.0.0.12 and has no usable mapping, it normally broadcasts an ARP request asking who has that address. Host2 can reply with its MAC address. ARP protocol

Linux records the mapping in a neighbour table, which you can inspect with ip -4 neigh. You may see an address, a device, a lladdr value, and a state. lladdr is the link-layer address; on Ethernet it is the MAC. REACHABLE means recently confirmed, while STALE means the mapping is no longer recently confirmed-not automatically wrong or unusable. INCOMPLETE means resolution is in progress; FAILED means it did not succeed. ARP implementation · Neighbour states

For a remote subnet, resolve the gateway, not the remote host. Host1 sending to 10.0.1.14 through 10.0.0.1 needs the local MAC for 10.0.0.1. It does not broadcast an ARP request across the router to find host4's MAC in this ordinary setup.

ARP and DNS are not interchangeable. DNS resolves names such as a server hostname into records, including IP addresses. ARP resolves a local IPv4 next hop into a link-layer address. A numeric ping does not need a DNS lookup for its target. IPv6 uses Neighbor Discovery rather than ARP. DNS concepts · IPv6 Neighbor Discovery

Bridge FDB: “Which port leads to this destination MAC?”

A bridge maintains a forwarding database, or FDB. In our non-VLAN lab, think of its dynamic entries as MAC address → bridge port. The bridge learns from the source MAC of incoming frames: if a frame from MAC-H1 arrives on veth1-br, that is evidence that MAC-H1 is reachable through that port. It then uses the destination MAC to decide where to forward a frame. Bridge forwarding database · Kernel bridging

With the lab's normal learning and forwarding settings, known unicast goes to the relevant port. Broadcast and unknown unicast are flooded to eligible other ports rather than arbitrarily guessed. Flooding does not mean a bridge is permanently a hub; once addresses are learned, it can forward known unicast selectively. VLANs, port states, filtering, and mirroring can alter behaviour, so do not apply the simplified lab model blindly to every production switch.

The three tables, side by side

Table Example lookup Example result Where we inspect it
Routing table Destination belongs to 10.0.1.0/24 Via 10.0.0.1, out eth1 Sending host or router
IPv4 neighbour table Next hop is 10.0.0.1 Router's local MAC address Sending host or router
Bridge FDB Destination is router's MAC Out veth-r-br Bridge namespace

They are separate information stores. Clearing host1's neighbour entry does not clear the bridge's FDB. ARP cache entries and learned bridge entries also have independent lifecycles. ARP cache · FDB management

Remember: route = IP destination to path; ARP = next-hop IP to MAC; FDB = MAC to switch port.

12. What does not happen automatically?

This is the checklist that prevents most beginner misunderstandings:

Action What it does What it does not do
Create a network namespace Establishes a separate networking context Connect it to other namespaces
Enable lo Enables its loopback device Create a link to another host
Create a veth pair Creates two interconnected Ethernet endpoints Assign their IPs or build a multi-port switch
Move an endpoint into a namespace Changes where that interface belongs Change its peer into a different kind of device
Bring an interface up Administratively enables it Assign an address or guarantee end-to-end reachability
Assign an address with a prefix Configures the address; normally also creates a connected route Supply a default gateway, DHCP service, or DNS server
Create a bridge Creates the software switching device Attach every interface to it automatically
Attach a port to a bridge Adds that interface to the bridge relationship Enable routing between different IP subnets
Add a route Describes how to reach a destination prefix Make a nonexistent next hop respond
Enable IPv4 forwarding Allows the routing stack to forward, subject to other configuration Add routes, perform NAT, or override firewall rules

These distinctions follow from the separate namespace, link, address, route, and forwarding operations described in the Linux manuals. ip-netns · ip-link · ip-address · ip-route · Forwarding

Before continuing, answer these without commands

Question: host1 and host2 both have lo and 127.0.0.1. Are they connected to each other?

Reveal the answer

No. Each address refers to its own network namespace. We have not yet supplied any link between them.

Question: a veth endpoint has been renamed from veth3 to eth3. Is it now a physical NIC?

Reveal the answer

No. Its name changed; its device type did not.

Question: br1 has no IPv4 address. Can it still switch frames between three hosts?

Reveal the answer

Yes. Ordinary Layer-2 switching does not require the bridge itself to be an IPv4 endpoint.


Part II - Compare the architectures

An architecture describes which objects exist, how they connect, and which object is responsible for each decision. The same tools can create different architectures. Do not learn a command sequence without knowing which architecture it produces.

Architecture A - Local communication only

Objects: one namespace, its loopback interface, and local processes.

Path: client process → local networking/loopback → local server process.

There is no Ethernet connection to another namespace. The loopback illustration in Concept 5 shows two separate examples side by side, not a connection between them. A second namespace can use the same loopback address independently.

What this architecture is for: local services and the first lab checkpoint.

What it cannot prove: that another host is reachable.

Architecture B - Two hosts directly connected

One veth pair connects host1 eth1 directly to host2 eth2, without a bridge or router.

Objects: host1, host2, and one veth pair. Each host also has its own lo.

Path: host1/eth1 → the veth peer connection → host2/eth2.

Both endpoint addresses are in 10.0.0.0/24, so the normal connected routes send traffic directly over that link. ARP resolves the other host's MAC when needed. There is no bridge FDB to inspect because there is no bridge, and no gateway is required for this direct exchange. veth · ARP

What this architecture is for: understanding an interface, its peer, and direct connectivity before adding a switch.

Its limitation: this pair has two ends. A third host requires a different topology, not another address magically turning the pair into a three-way cable.

Architecture C - Three hosts on one switched LAN

host1, host2, and host3 each have a separate veth pair to a port of br1 inside bridge1.

Objects: four namespaces, three veth pairs, and one Linux bridge. The dashed rectangle marks a namespace boundary. Each amber connection is a different veth pair. The blue boxes inside bridge1 are the switch-side endpoints, not the hosts' own interfaces.

Host interface Its peer, owned by bridge1 Bridge membership
host1/eth1 veth1-br veth1-br is a port of br1
host2/eth2 veth2-br veth2-br is a port of br1
host3/eth3 veth3-br veth3-br is a port of br1

The complete host1-to-host2 path is:

host1 process
  → host1 IP stack
  → eth1
  → veth1-br              (its peer in bridge1)
  → br1 forwarding logic
  → veth2-br             (the selected outgoing bridge port)
  → eth2                 (its peer in host2)
  → host2 IP stack
  → host2's recipient

br1 does not need an IPv4 address. Neither do veth1-br, veth2-br, or veth3-br. They provide Layer-2 connectivity; the hosts originate and receive the IP traffic.

Follow the first ping, not just the result

Assume the relevant ARP mappings are absent, the bridge uses its ordinary learning behaviour, and nothing filters the traffic.

Sequence of ARP broadcast, ARP reply, ICMP request, and ICMP reply through a learning bridge.

First, choose the path. Host1's route lookup identifies 10.0.0.12 as on-link through eth1.

Next, discover the Ethernet destination. Host1 emits an ARP request. The bridge sees host1's source MAC on veth1-br, learns that location, and forwards the broadcast to the other eligible ports. Host2 recognises its own IP; host3 receives the broadcast but is not the requested owner.

Then learn the reply direction. Host2 replies with its MAC. The bridge learns host2's source MAC on veth2-br and can forward the reply towards host1. Host1 can now address its Ethernet frame to host2.

Finally, exchange ICMP. The echo request and echo reply cross the bridge as unicast frames. While usable neighbour mappings remain, another ping need not start with another broadcast ARP exchange. ARP exchange · ARP cache behaviour · Bridge learning

This is why a capture can show ARP before the first ICMP request but show only ICMP during a later run. A cached mapping is an explanation, not missing traffic.

What this architecture is for: a shared Ethernet LAN with multiple hosts, without a router.

Architecture D - Two IP subnets connected by a router

The existing three-host LAN connects through router1 to host4 in another IPv4 subnet.

This is a compact view of Architecture C plus an extension. The left-hand switch still has the three host ports shown in the previous diagram. We add a fourth bridge port, veth-r-br, whose peer is the router's r-left interface. A second new veth pair connects router1/r-right directly to host4/eth4.

Endpoint Address Role
host1/eth1 10.0.0.11/24 Host in LAN A
host2/eth2 10.0.0.12/24 Host in LAN A
host3/eth3 10.0.0.13/24 Host in LAN A
router1/r-left 10.0.0.1/24 Router interface on LAN A
router1/r-right 10.0.1.1/24 Router interface on LAN B
host4/eth4 10.0.1.14/24 Host in LAN B

The router's interfaces are not attached to one shared bridge. It handles traffic between the subnets through IP forwarding. LAN B uses a direct Ethernet link; it does not require another switch for its two endpoints.

What happens to a ping from host1 to host4?

Host1's explicit route says to reach 10.0.1.0/24 through 10.0.0.1. Host1 therefore resolves the router's LAN A MAC, puts the packet in an Ethernet frame addressed to that MAC, and sends it through the bridge.

Router1 receives the frame as an Ethernet recipient. The enclosed IP destination is 10.0.1.14, not one of the router's own addresses. With forwarding enabled and no blocking policy, it consults its route for LAN B, resolves host4's MAC there if needed, and sends a new Ethernet frame through r-right.

The reply requires a route back. Host4 must know that 10.0.0.0/24 is reachable through 10.0.1.1; knowing only its connected LAN B route is not enough. IPv4 router forwarding · Kernel forwarding configuration

Across the router, the source and destination IP addresses remain the same, the Ethernet MAC addresses change, and TTL decreases.

Read the important contrast: the source and destination IP addresses remain 10.0.0.11 and 10.0.1.14 in this no-NAT example. The Ethernet source and destination addresses change between LANs. The router also decrements the IPv4 TTL and updates the IPv4 header checksum; the entire packet is not byte-for-byte unchanged. Ordinary bridge forwarding does not perform that router operation. IP header · Router requirements

ARP broadcasts from LAN A are not forwarded as Ethernet broadcasts into LAN B by this router. Each LAN has its own neighbour resolution.

What this architecture is for: understanding gateways, routes, forwarding, separate broadcast domains, and return paths.

Architecture E - Where the same building blocks appear in containers and VMs

A bridged container example uses a veth pair and a shared kernel, while a bridged VM example uses a virtual NIC and TAP with a separate guest kernel.

A container-style design can put an application in a network namespace, connect it to a host-side bridge with a veth pair, and optionally route beyond that bridge. That is similar to our lab, although our switch has its own namespace to make the boundaries visible. Containers share the host kernel; a network namespace alone is only the networking part of container isolation. Network namespaces · Red Hat namespace walkthrough

A VM has its own guest kernel. In one common bridged design, its guest-visible virtual NIC exchanges traffic through a virtual-machine monitor and a host-side TAP device, which is attached to a host bridge. This is not the same mechanism as a veth pair. Other VM and container network architectures also exist; the diagram shows examples, not universal rules. Kernel TUN/TAP documentation · QEMU networking

We will not connect the lab to a physical NIC. That keeps all experiments within lab-owned devices and namespaces.

Architecture comparison: the same word can hide a different path

Architecture Link between separate hosts? Switch? Router? Main lookup to add to your mental model
A. Loopback only No No No Local delivery
B. Direct veth One veth pair No No Connected route and neighbour resolution
C. Switched LAN One veth pair per host br1 No Bridge FDB, in addition to host routes and ARP
D. Routed subnets Several separate links br1 on LAN A router1 Forwarding route and next-hop resolution on each LAN

Before the lab: you should now be able to trace Architecture C without calling bridge1 a switch, and explain why Architecture D needs routes that Architecture C does not.


Part III - Build the lab, one idea at a time

This is one cumulative lab in four stages, not four independent scripts. Stage 2 starts from Stage 1. Stage 3 replaces the direct cable built in Stage 2. Stage 4 extends Stage 3 without removing its three-host LAN.

You will enter individual commands. There are no helper functions hiding the networking operations.

Preparation - A safe, repeatable starting point

Use a Linux machine or a Linux VM where you have permission to create network namespaces and virtual devices. A restricted container may refuse these operations even when its shell says root; privileges and kernel restrictions still matter. Capabilities

For Debian or Ubuntu, install the tools when they are missing:

sudo apt-get update
sudo apt-get install -y iproute2 iputils-ping tcpdump procps util-linux python3 curl

Other distributions use their own package managers and may use different package names. ip and bridge belong to iproute2; sysctl is provided by procps on Debian/Ubuntu. The HTTP experiment uses Python's simple development server, not a production web server. iproute2 commands · Python HTTP server

Check what is available:

command -v ip bridge ping tcpdump sysctl python3 curl
sudo ip netns list

Reserved lab namespace names: host1, host2, host3, bridge1, router1, and host4.

If any of those already exist, stop before creating anything. Determine whether they are your previous lab or another workload. Use a fresh environment, or use the cleanup section only after confirming ownership and stopping the lab's processes. Do not remove a namespace merely because its name matches this document.

Execution rules

Run commands from your normal Linux shell. Each namespace-targeting command includes -n NAME or ip netns exec NAME. Use a second terminal only when a server or packet capture is explicitly running in the first one.

The lab creates and modifies interfaces only inside the lab namespaces. It does not attach a physical NIC, alter the normal shell's default route, flush a firewall, or connect the lab to an external network. Never substitute your real management interface for one of the lab interface names.

Commands are not idempotent: an add operation can correctly fail if you run it twice. An unexpected error is a reason to inspect the current state, not to continue pasting the remaining steps. Temporary names and interface indices can differ from the illustrative outputs below.

Stage 1 - Create two isolated hosts and understand lo

Starting point: none of the reserved namespaces exists.

Goal: prove that loopback works independently in each namespace and does not connect them.

1A. Create the network namespaces

sudo ip netns add host1
sudo ip netns add host2

We have created two network contexts, not connected two hosts. Inspect them:

sudo ip netns list
sudo ip -n host1 -br link
sudo ip -n host2 -br link

Expected observation: each has a lo device, normally down at this point, and no lab Ethernet interface. You have not created eth1 or eth2 yet. Named namespace operations

1B. Enable each loopback device

sudo ip -n host1 link set dev lo up
sudo ip -n host2 link set dev lo up

Inspect only the IPv4 view:

sudo ip -n host1 -br -4 addr show dev lo
sudo ip -n host2 -br -4 addr show dev lo

A typical result is:

lo               UNKNOWN        127.0.0.1/8

UNKNOWN is the operational-state field, not a statement that loopback is broken. Operational states

1C. Predict, observe, explain

Predict: can both commands succeed without any connection between the namespaces?

sudo ip netns exec host1 ping -n -c 3 127.0.0.1
sudo ip netns exec host2 ping -n -c 3 127.0.0.1

Observe: both should receive replies.

Explain: each ping stays within its own network namespace. Neither command reached the other host. The success is not evidence of an Ethernet connection.

1D. Make “localhost is separate” visible with a service

In Terminal A, create a temporary directory containing only our test page:

LAB_WEB=$(mktemp -d)
printf 'Hello from the host1 lab server\n' > "$LAB_WEB/index.html"

mktemp -d creates a new directory. LAB_WEB stores its path in this shell. Keep this terminal open; we reuse the directory later. The directory is on the ordinary filesystem-network namespaces do not provide filesystem isolation.

Start a server listening only on host1's IPv4 loopback address:

sudo ip netns exec host1 python3 -m http.server 8000 --bind 127.0.0.1 --directory "$LAB_WEB"

The command stays in the foreground. Leave it running. Python server options

In Terminal B, test from host1:

sudo ip netns exec host1 curl --noproxy '*' --max-time 2 http://127.0.0.1:8000/

Expected: Hello from the host1 lab server.

Now test exactly the same address from host2:

sudo ip netns exec host2 curl --noproxy '*' --max-time 2 http://127.0.0.1:8000/

Expected: failure because there is no listener on host2's own loopback port 8000. It did not try to reach host1. --noproxy '*' prevents an inherited proxy setting from changing this experiment; --max-time 2 bounds the request time. curl options

Stop the server with Ctrl+C in Terminal A before proceeding.

Stage 1 checkpoint: two namespaces, two working loopback devices, zero links between the hosts.

Stage 2 - Connect host1 directly to host2 with a veth pair

Starting point: Stage 1 is complete; the HTTP server is stopped.

Goal: build Architecture B and separate device creation, placement, addressing, and link state.

2A. Create two endpoints, initially in host1

sudo ip -n host1 link add eth1 type veth peer name eth2

Read the operation slowly: inside host1, create a device named eth1 of type veth, whose connected peer is named eth2.

Both endpoints currently belong to host1. Confirm that before changing the layout:

sudo ip -n host1 -br link
sudo ip -n host2 -br link

2B. Move one endpoint into host2

sudo ip -n host1 link set dev eth2 netns host2

This moves eth2; it does not create another pair. The connection to eth1 remains. veth peer placement

sudo ip -n host1 -d link show dev eth1
sudo ip -n host2 -d link show dev eth2

A display name such as eth1@if4 means the peer has interface index 4; the exact value may differ. @if4 is not part of the name to use in commands. Continue using dev eth1.

2C. Assign addresses and enable the endpoints

sudo ip -n host1 addr add 10.0.0.11/24 dev eth1
sudo ip -n host2 addr add 10.0.0.12/24 dev eth2
sudo ip -n host1 link set dev eth1 up
sudo ip -n host2 link set dev eth2 up

These are separate operations: address assignment and administrative state. Inspect both:

sudo ip -n host1 -br -4 addr
sudo ip -n host2 -br -4 addr
sudo ip -n host1 -4 route
sudo ip -n host2 -4 route

Host1 should have a connected route resembling:

10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.11

Predict: do we need a default gateway or bridge for this exchange?

sudo ip netns exec host1 ping -n -c 3 10.0.0.12
sudo ip netns exec host2 ping -n -c 3 10.0.0.11

Observe: both directions should work.

Explain: the connected routes and the direct Ethernet link are sufficient. The endpoints use ARP as needed; no bridge or router exists in this architecture.

Inspect the mapping learned by host1:

sudo ip -n host1 -4 neigh show

A line for 10.0.0.12 should contain dev eth1, a MAC address after lladdr, and a neighbour state. The actual MAC and state can differ between runs.

2E. Reveal the “pinging my own IP” trap

Compare these route lookups:

sudo ip -n host1 route get 10.0.0.12
sudo ip -n host1 route get 10.0.0.11

The peer address should use eth1. The own-address lookup normally shows a local route using lo. That is why pinging 10.0.0.11 from host1 is not evidence that its cable to host2 works.

To inspect the separate local table:

sudo ip -n host1 -4 route show table local

The normal ip route view principally shows the main table, not every route Linux maintains. Route tables and lookup

sudo ip -n host2 link set dev eth2 down
sudo ip netns exec host1 ping -n -c 2 -W 1 10.0.0.12
sudo ip netns exec host1 ping -n -c 2 127.0.0.1

Predict the contrast: communication to host2 fails while host1's own loopback still works. The exact failure message can depend on link and neighbour state.

Restore the link before continuing:

sudo ip -n host2 link set dev eth2 up
sudo ip netns exec host1 ping -n -c 3 10.0.0.12

Stage 2 checkpoint: two hosts, one veth pair, working direct IPv4 communication, no bridge, no router.

Stage 3 - Replace the cable with a three-host switched LAN

Starting point: Stage 2 works and no foreground ping, server, or capture is left running.

Goal: build Architecture C using the original names host1, host2, host3, bridge1, and br1.

3A. Remove the old direct pair

This is an intentional topology change, not a generic cleanup command:

sudo ip -n host1 link del dev eth1

Deleting this veth endpoint also removes its peer, host2/eth2. Their address assignments disappear with those interfaces. The two namespaces and their loopback devices remain.

sudo ip -n host1 -br link
sudo ip -n host2 -br link

Expected: neither eth1 nor eth2 is present now. veth lifecycle

3B. Create host3 and the switch namespace

sudo ip netns add host3
sudo ip netns add bridge1
sudo ip -n host3 link set dev lo up
sudo ip -n bridge1 link set dev lo up

Bringing up bridge1/lo makes its local networking available; it is not a prerequisite for the bridge's transit frame switching.

Create the actual bridge device inside the switch namespace:

sudo ip -n bridge1 link add br1 type bridge

We now have a namespace called bridge1 containing a bridge called br1. We have not attached any ports yet.

3C. Create one veth pair for each host

For host1:

sudo ip -n host1 link add eth1 type veth peer name veth1-br
sudo ip -n host1 link set dev veth1-br netns bridge1

For host2:

sudo ip -n host2 link add eth2 type veth peer name veth2-br
sudo ip -n host2 link set dev veth2-br netns bridge1

For host3:

sudo ip -n host3 link add eth3 type veth peer name veth3-br
sudo ip -n host3 link set dev veth3-br netns bridge1

Notice the difference from Stage 2. eth1 and eth2 are no longer peers of each other. Their peers are now veth1-br and veth2-br, respectively.

3D. Attach the switch-side endpoints to br1

sudo ip -n bridge1 link set dev veth1-br master br1
sudo ip -n bridge1 link set dev veth2-br master br1
sudo ip -n bridge1 link set dev veth3-br master br1

This creates the bridge-port relationships. Without them, the endpoints being in the same namespace would not automatically make a switch between them. Bridge port attachment

Enable the bridge and its ports:

sudo ip -n bridge1 link set dev br1 up
sudo ip -n bridge1 link set dev veth1-br up
sudo ip -n bridge1 link set dev veth2-br up
sudo ip -n bridge1 link set dev veth3-br up

3E. Configure the host-side endpoints

sudo ip -n host1 addr add 10.0.0.11/24 dev eth1
sudo ip -n host2 addr add 10.0.0.12/24 dev eth2
sudo ip -n host3 addr add 10.0.0.13/24 dev eth3
sudo ip -n host1 link set dev eth1 up
sudo ip -n host2 link set dev eth2 up
sudo ip -n host3 link set dev eth3 up

Do not assign these host addresses to the bridge-side ports. We do not assign an IPv4 address to br1 either.

3F. Prove that the intended objects exist

sudo ip -n host1 -br -4 addr
sudo ip -n host2 -br -4 addr
sudo ip -n host3 -br -4 addr
sudo ip -n bridge1 -br -4 addr
sudo ip -n bridge1 link show master br1
sudo ip netns exec bridge1 bridge link show

Expected: each host's Ethernet endpoint has its own address; br1 has three attached ports; the bridge and those ports have no IPv4 address. bridge1/lo does have its loopback address. IPv6 link-local addresses may appear when you omit -4; they do not mean you configured IPv4 on the bridge.

3G. Verify host-to-host connectivity

sudo ip netns exec host1 ping -n -c 3 10.0.0.12
sudo ip netns exec host1 ping -n -c 3 10.0.0.13
sudo ip netns exec host2 ping -n -c 3 10.0.0.13

Predict: does the traffic need an IP address on br1, a gateway in host1, or IPv4 forwarding enabled in bridge1?

Observe: the pings should work without those additions.

Explain: this is Layer-2 switching between hosts with connected routes for the same /24, not routing between different subnets.

3H. Inspect two different tables

Host1's IPv4 neighbour table:

sudo ip -n host1 -4 neigh show

The bridge's forwarding database:

sudo ip netns exec bridge1 bridge fdb show br br1

Find entries corresponding to the hosts' actual MAC addresses, which you can read with:

sudo ip -n host1 link show dev eth1
sudo ip -n host2 link show dev eth2
sudo ip -n host3 link show dev eth3

The FDB will normally also contain local/permanent and other entries, not only the three learned host entries. Do not assume its entire output must contain exactly three lines. Follow the host MACs you identified. FDB output

3I. Watch ARP and ICMP instead of imagining them

In Terminal A, capture on host2's Ethernet interface:

sudo ip netns exec host2 tcpdump -l -n -i eth2 -e 'arp or icmp'
Option Meaning here
-l Line-buffer printed output, useful for seeing lines promptly
-n Do not resolve addresses into names
-i eth2 Capture on this interface
-e Include link-layer header information, such as Ethernet MACs
'arp or icmp' Restrict this capture to ARP or ICMP traffic

These are tcpdump options, not ip options. tcpdump manual

In Terminal B, clear only the relevant lab mapping and send a small ping:

sudo ip -n host1 neigh flush to 10.0.0.12 dev eth1
sudo ip netns exec host1 ping -n -c 2 10.0.0.12

You should observe the ARP request, ARP reply, and ICMP exchange. Below is an illustrative capture; MAC-H1 and MAC-H2 stand for your actual generated MAC addresses:

MAC-H1 > ff:ff:ff:ff:ff:ff, ARP, Request who-has 10.0.0.12 tell 10.0.0.11
MAC-H2 > MAC-H1, ARP, Reply 10.0.0.12 is-at MAC-H2
MAC-H1 > MAC-H2, IPv4, 10.0.0.11 > 10.0.0.12: ICMP echo request
MAC-H2 > MAC-H1, IPv4, 10.0.0.12 > 10.0.0.11: ICMP echo reply

Read the first line as: “Host1 is broadcasting a question: who owns 10.0.0.12? Tell the sender at 10.0.0.11.” The word tell identifies the sender's protocol address; it does not identify a router.

Repeat the ping without clearing the mapping:

sudo ip netns exec host1 ping -n -c 2 10.0.0.12

Expected: often just ICMP while the cached mapping is usable. Additional neighbour maintenance traffic is possible; the important point is that there is not a compulsory new ARP broadcast for every echo request.

Stop the capture with Ctrl+C in Terminal A.

3J. Why host3 sees a broadcast but not all unicast

Start this capture in Terminal A:

sudo ip netns exec host3 tcpdump -l -n -p -i eth3 -e 'arp or icmp'

In Terminal B:

sudo ip -n host1 neigh flush to 10.0.0.12 dev eth1
sudo ip netns exec host1 ping -n -c 2 10.0.0.12

Host3 should see host1's ARP broadcast. With the lab's ordinary learning behaviour and no mirroring, it should not see the subsequent host1-to-host2 unicast ICMP exchange. The switch learns the needed MAC locations during the exchange. -p tells tcpdump not to request promiscuous mode on host3's interface. Capture options · Bridge learning

A production capture can differ if unknown unicast is flooded, a monitor port is configured, or the forwarding settings differ. Our observation is about the defined lab, not a guarantee for every switched network.

Stop the capture with Ctrl+C.

3K. Separate network reachability from the listening address

In Terminal A, using the same LAB_WEB variable from Stage 1:

sudo ip netns exec host1 python3 -m http.server 8000 --bind 127.0.0.1 --directory "$LAB_WEB"

In Terminal B, try both network and application tests from host2:

sudo ip netns exec host2 ping -n -c 2 10.0.0.11
sudo ip netns exec host2 curl --noproxy '*' --max-time 2 http://10.0.0.11:8000/

Predict: the ping succeeds, but the HTTP request fails. The server listens on host1's loopback address, not its Ethernet address.

Stop the server in Terminal A, then start it with an IPv4 wildcard listener:

sudo ip netns exec host1 python3 -m http.server 8000 --bind 0.0.0.0 --directory "$LAB_WEB"

Repeat the HTTP request from Terminal B:

sudo ip netns exec host2 curl --noproxy '*' --max-time 2 http://10.0.0.11:8000/

Expected: the page is now reachable. You changed the listener, not the bridge, the route, or the veth pairs. Clients still use the server's concrete address, 10.0.0.11, not 0.0.0.0. Socket binding · Python server binding

Stop the server with Ctrl+C before continuing.

Stage 3 checkpoint: you can explain the namespace/interface/bridge distinction, follow ARP, locate a learned MAC, and distinguish a listener problem from a link problem.

Stage 4 - Add a router and a second subnet

Starting point: the Stage 3 LAN works; captures and the HTTP server have stopped.

Goal: demonstrate why different IP subnets need routes, forwarding, and a return path-without adding NAT.

4A. Create the router and the new host

sudo ip netns add router1
sudo ip netns add host4
sudo ip -n router1 link set dev lo up
sudo ip -n host4 link set dev lo up

Make the forwarding experiment explicit by starting with IPv4 forwarding disabled inside router1:

sudo ip netns exec router1 sysctl -w net.ipv4.ip_forward=0

Do not omit ip netns exec router1; we are not changing the normal shell's network namespace. Namespace networking resources · Forwarding setting

4B. Connect the router's left side to the existing bridge

sudo ip -n router1 link add r-left type veth peer name veth-r-br
sudo ip -n router1 link set dev veth-r-br netns bridge1
sudo ip -n bridge1 link set dev veth-r-br master br1
sudo ip -n bridge1 link set dev veth-r-br up
sudo ip -n router1 link set dev r-left up
sudo ip -n router1 addr add 10.0.0.1/24 dev r-left

This is one new veth pair: r-left ↔ veth-r-br. The bridge now has four attached ports: three hosts and one router interface.

4C. Connect the router's right side directly to host4

sudo ip -n router1 link add r-right type veth peer name eth4
sudo ip -n router1 link set dev eth4 netns host4
sudo ip -n router1 link set dev r-right up
sudo ip -n host4 link set dev eth4 up
sudo ip -n router1 addr add 10.0.1.1/24 dev r-right
sudo ip -n host4 addr add 10.0.1.14/24 dev eth4

This is another new pair, not another bridge port. r-left and r-right remain separate routed interfaces in router1.

Inspect the router:

sudo ip -n router1 -br -4 addr
sudo ip -n router1 -4 route

Expected: two connected routes, one for 10.0.0.0/24 and one for 10.0.1.0/24.

4D. Verify each directly attached side

sudo ip netns exec host1 ping -n -c 2 10.0.0.1
sudo ip netns exec host4 ping -n -c 2 10.0.1.1

Both should work even though router1 is not yet forwarding between the LANs. The pings are addressed to the router's own interfaces.

Now ask host1 how it would reach host4:

sudo ip -n host1 route get 10.0.1.14

Expected: no route to that destination in this lab yet. Merely connecting the router to the switch did not install a route in host1.

4E. Add explicit routes to the other subnet

For each host in LAN A:

sudo ip -n host1 route add 10.0.1.0/24 via 10.0.0.1 dev eth1
sudo ip -n host2 route add 10.0.1.0/24 via 10.0.0.1 dev eth2
sudo ip -n host3 route add 10.0.1.0/24 via 10.0.0.1 dev eth3

For the return path from host4:

sudo ip -n host4 route add 10.0.0.0/24 via 10.0.1.1 dev eth4

The router already has both connected routes, so it does not need a default route to forward between these two directly attached subnets.

Check both endpoint decisions:

sudo ip -n host1 route get 10.0.1.14
sudo ip -n host4 route get 10.0.0.11

Host1 should select via 10.0.0.1 dev eth1; host4 should select via 10.0.1.1 dev eth4. Extra output fields can vary.

4F. Prove that routes alone do not enable forwarding

sudo ip netns exec host1 ping -n -c 2 -W 1 10.0.1.14

Expected: failure while IPv4 forwarding is disabled in router1, even though the endpoint routes now exist.

Enable forwarding in the router namespace:

sudo ip netns exec router1 sysctl -w net.ipv4.ip_forward=1

The kernel documents that changing ip_forward also resets some IPv4 configuration parameters to host/router defaults; this is another reason to do the experiment only in the new lab namespace, not on a configured production router. Kernel sysctl documentation

Retry in both directions:

sudo ip netns exec host1 ping -n -c 3 10.0.1.14
sudo ip netns exec host4 ping -n -c 3 10.0.0.11

Also test the other LAN A hosts:

sudo ip netns exec host2 ping -n -c 2 10.0.1.14
sudo ip netns exec host3 ping -n -c 2 10.0.1.14

Expected: successful connectivity. We configured no NAT, external network, or default route.

4G. Verify the next-hop MAC, not just the destination IP

sudo ip -n host1 -4 neigh show
sudo ip -n router1 -4 neigh show

Host1 should have a neighbour entry for its local gateway, 10.0.0.1. It normally has no entry for host4's 10.0.1.14, because that destination is not directly attached to host1. Router1 can have neighbour entries on each LAN, including host1 on r-left and host4 on r-right.

This is the difference between “I know the final IP destination” and “I know the Ethernet neighbour to send to next”.

4H. Observe the Ethernet rewrite and TTL decrement

Use three terminals for this short capture experiment.

In Terminal A, capture the router's LAN A interface:

sudo ip netns exec router1 tcpdump -l -n -e -v -i r-left 'icmp'

In Terminal B, capture its LAN B interface:

sudo ip netns exec router1 tcpdump -l -n -e -v -i r-right 'icmp'

In Terminal C, send one ping:

sudo ip netns exec host1 ping -n -c 1 10.0.1.14

Compare the echo request on the two interfaces, not the request on one side with the reply on the other.

Field Request seen on r-left Request seen on r-right
Source IP 10.0.0.11 10.0.0.11
Destination IP 10.0.1.14 10.0.1.14
Source Ethernet MAC Host1's MAC Router's r-right MAC
Destination Ethernet MAC Router's r-left MAC Host4's MAC
IPv4 TTL For example, 64 One less, for example 63

-v adds detail, including IPv4 TTL. Your initial TTL need not be assumed to be exactly 64; the important observation is the router's decrement. tcpdump output · IPv4 forwarding

Stop both captures with Ctrl+C in their respective terminals.

4I. Remove the return route and explain the failure

Delete only host4's explicit route back to LAN A:

sudo ip -n host4 route del 10.0.0.0/24 via 10.0.1.1 dev eth4

From host1:

sudo ip netns exec host1 ping -n -c 2 -W 1 10.0.1.14

Expected: no successful echo exchange. A request can still reach host4, but host4 lacks a route to send the reply to 10.0.0.11.

Inspect the missing decision:

sudo ip -n host4 route get 10.0.0.11

Restore the return route and retest:

sudo ip -n host4 route add 10.0.0.0/24 via 10.0.1.1 dev eth4
sudo ip netns exec host1 ping -n -c 3 10.0.1.14

Stage 4 checkpoint: you can explain why gateway reachability, forwarding, and a return route are three different requirements.

Cleanup - Remove only the resources you created

Stop each lab tcpdump, Python HTTP server, and interactive namespace shell first. Ctrl+C stops the foreground captures and servers; exit leaves a shell. Removing a namespace's registered name does not necessarily destroy the namespace if processes or other references still keep it alive. Namespace deletion behaviour

Check for processes in every namespace you actually created:

sudo ip netns pids host1
sudo ip netns pids host2
sudo ip netns pids host3
sudo ip netns pids bridge1
sudo ip netns pids router1
sudo ip netns pids host4

An empty result is expected before deletion. If a command returns process IDs, identify and stop your lab processes first. Do not kill unfamiliar processes or delete a namespace you do not own. A namespace not created because you stopped at an earlier stage will produce a “not found” error; omit that namespace from cleanup.

After Stage 4, remove the six lab namespaces explicitly:

sudo ip netns del host1
sudo ip netns del host2
sudo ip netns del host3
sudo ip netns del host4
sudo ip netns del router1
sudo ip netns del bridge1

Their virtual devices disappear when the namespaces are released; veth peer deletion also removes the connected peer. We did not create lab devices in the normal shell's network namespace, so there is no physical interface to restore. Network namespace device lifecycle · veth

In the same Terminal A that created LAB_WEB, after the HTTP server has stopped, remove the test page and its now-empty temporary directory:

rm -- "$LAB_WEB/index.html"
rmdir -- "$LAB_WEB"
unset LAB_WEB

Do this only for the temporary directory created during Stage 1. There is no reason to use rm -rf or remove other temporary files.

Finally:

sudo ip netns list

The lab names should be absent. Other namespaces, if any, should remain untouched.


Part IV - Remember and troubleshoot

The one-minute reconstruction

Before opening a terminal, describe the network in these terms:

The namespace owns the networking context. The interface is a connection point. A veth pair connects two such points. A bridge joins multiple Ethernet links by switching frames. An IP route selects the outgoing path. ARP finds the local next-hop MAC. The bridge FDB locates that MAC on a switch port. A router forwards packets between IP networks. Loopback stays local to its namespace.

Those sentences summarise the concepts and the paths you built; they are not a substitute for knowing which object owns each piece of configuration.

Troubleshoot by asking a question at each layer

Use this table against the known lab topology. Do not “fix” everything at once: find the first observation that disagrees with the design.

Ask this question Inspect What a discrepancy suggests
Am I looking in the right namespace? sudo ip netns list; sudo ip -n host1 -br addr You may be inspecting a different network stack.
Do the expected interfaces exist? sudo ip -n host1 -d link show Device was not created, was moved elsewhere, or its veth peer was deleted.
Are both ends of the link enabled? Inspect the host endpoint and its bridge-side peer A cable exists but one endpoint is down.
Are the addresses and prefixes correct? sudo ip -n host1 -br -4 addr Wrong address, wrong prefix, or an address assigned to the wrong device.
What path does Linux select? sudo ip -n host1 route get 10.0.1.14 Missing route, wrong next hop, or an unintended local/on-link decision.
Can the local next hop be resolved? sudo ip -n host1 -4 neigh Repeated INCOMPLETE/FAILED suggests trouble reaching or resolving that neighbour.
Is the switch port actually attached? sudo ip -n bridge1 link show master br1 Veth endpoint is present but not a port of the bridge.
Has the switch learned the expected MAC location? sudo ip netns exec bridge1 bridge fdb show br br1 Check traffic, port state, MAC addresses, and topology.
Is the router forwarding? sudo ip netns exec router1 sysctl net.ipv4.ip_forward Local router reachability may work while transit traffic does not.
Can the reply return? sudo ip -n host4 route get 10.0.0.11 Forward-path delivery alone does not guarantee a round trip.
Is the application listening on the right address? sudo ip netns exec host1 ss -lntp A working network can still have no listener, a loopback-only listener, or an unhealthy application.

The inspection commands correspond to Linux's separate device, address, route, neighbour, bridge, forwarding, and socket interfaces. Links · Routes · Neighbours · Bridge · Sockets

ss -lntp means listening TCP sockets, numeric addresses/ports, and process information when permissions permit. Firewall policy can also block a correct path; on an existing system, inspect the relevant namespace's rules rather than indiscriminately flushing them. Our newly built lab does not install filtering rules. ss manual · Network-namespace isolation

Useful distinction: “Network is unreachable” commonly points you towards a route decision; repeated unanswered ARP points towards local next-hop resolution; an HTTP connection refusal can mean that the network delivered the request but no suitable listener accepted it. These are starting clues, not universal diagnoses-use the route lookup and packet capture to establish the actual path.

A compact command reference

These commands are for the completed relevant lab stage; router1 and host4 do not exist before Stage 4.

Task Command
Interfaces in the current namespace ip -br link
Addresses in the current namespace ip -br addr
Named network namespaces sudo ip netns list
Visible namespaces of all types sudo lsns
Visible network namespaces sudo lsns -t net
Addresses in a lab namespace sudo ip -n host1 -br addr
Main IPv4 routes sudo ip -n host1 -4 route
Local IPv4 route table sudo ip -n host1 -4 route show table local
Route lookup for a particular destination sudo ip -n host1 route get 10.0.1.14
IPv4 neighbour mappings sudo ip -n host1 -4 neigh
Bridge membership sudo ip -n bridge1 link show master br1
Bridge MAC forwarding database sudo ip netns exec bridge1 bridge fdb show br br1
Link counters sudo ip -n host1 -s link show dev eth1
Listening TCP sockets sudo ip netns exec host1 ss -lntp
ARP and ICMP capture sudo ip netns exec host1 tcpdump -l -n -e -i eth1 'arp or icmp'

ip netns list enumerates registered names under /var/run/netns; it is not a universal list of every network namespace. The initial namespace normally has no registered name there. lsns can reveal namespaces associated with processes, including unnamed ones, but its view depends on privileges and accessible namespace references. Use the two tools together rather than assuming the lists must match. Named namespaces · lsns manual

Read interface output without guessing

An illustrative line can look like this:

3: eth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... state UP
    link/ether 02:00:00:00:00:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.11/24 scope global eth1

The leading number is the local interface index. eth1 is the interface name. In this veth example, @if4 identifies the peer's interface index, not an IP address. The flags and state describe link properties; link/ether introduces the Ethernet MAC; inet introduces the IPv4 address. scope global here does not mean that the private 10.0.0.11 address is publicly reachable from the Internet. veth peer index · Address scope · Private addressing

Your indices, MACs, and additional output fields will differ. Match the relationships, not the incidental numbers.

Retrieval practice - Answer before revealing

Question 1: host1 can ping 127.0.0.1, but not host2. What did the successful ping prove?

Reveal the answer

Only that host1's loopback path works. It did not exercise the veth pair, bridge, or remote host. Compare Stage 1 with the link-down experiment in Stage 2.

Question 2: why does the three-host bridge topology need three veth pairs?

Reveal the answer

Each host needs a separate link to a bridge port. A veth pair has two endpoints, not an arbitrary number of endpoints. The bridge switches between those three links.

Question 3: in the switched topology, is host1's eth1 the peer of host2's eth2?

Reveal the answer

No. Host1's eth1 is paired with veth1-br. Host2's eth2 is paired with veth2-br. The bridge connects the switch-side ports. eth1 and eth2 were peers only in the earlier direct-link stage.

Question 4: why can br1 forward a ping without an IPv4 address?

Reveal the answer

It is switching the Ethernet frame that carries the IP packet. It does not need to be an IPv4 recipient merely to perform that Layer-2 function.

Question 5: what is learned from the source MAC, and what is looked up using the destination MAC?

Reveal the answer

The bridge learns the source MAC's location from the incoming port. It looks up the destination MAC to select the outgoing port. Host ARP learning is a different mechanism.

Question 6: host1 pings host4. Whose MAC should host1 resolve?

Reveal the answer

The MAC of its next-hop router on LAN A, at 10.0.0.1. Router1 separately resolves host4's MAC on LAN B. Host1 does not need a direct neighbour entry for host4 in this design.

Question 7: the router can ping both LANs. Does that prove it forwards between them?

Reveal the answer

No. Traffic originated by the router and traffic forwarded on behalf of other hosts are different cases. The forwarding-disabled experiment demonstrated that distinction.

Question 8: all routes exist on host1 and the router. Why might a ping to host4 still fail?

Reveal the answer

Host4 may lack a return route. Other possibilities include a disabled link, neighbour failure, filtering, or disabled router forwarding. Use the actual route and packet observations rather than choosing one diagnosis automatically.

Question 9: why did HTTP start working after changing --bind 127.0.0.1 to --bind 0.0.0.0?

Reveal the answer

The server began accepting IPv4 connections addressed to host1's non-loopback address as well. The links, bridge, and routes were already working. This was a listener-binding issue.

Question 10: what changes when an IP packet crosses the router in our no-NAT lab?

Reveal the answer

The Ethernet header is rebuilt for the outgoing LAN, using different source and destination MAC addresses. The IP source and destination remain the endpoint addresses; TTL decreases and the IPv4 header checksum changes.

The final teach-back exercise

Without looking at the commands, sketch the switched topology. Put every interface inside the correct namespace, connect the exact veth peers, and mark which endpoints are bridge ports. Explain why enabling loopback does not connect the hosts.

Then add the router and host4. Write the two IP prefixes, the gateway on each LAN, and a route for each direction. Describe the first echo request using three separate questions: Which route? Which neighbour MAC? Which bridge port?

Return to the relevant diagram when you cannot answer one of those questions. That missing relationship is the concept to revisit-not another command to memorise.


Sources and validation

How the references are used

The lesson uses original explanations, diagrams, and worked examples, with links to the relevant primary documentation beside the technical concepts. The Linux man-pages and iproute2 manuals define the command behaviour; kernel documentation explains forwarding, bridging, and device semantics; RFCs define the protocol mechanisms. The source pages were checked while preparing this edition.

Subject Primary references
Linux network isolation network_namespaces(7), namespaces(7), ip-netns(8), lsns(8)
Interfaces and addressing netdevice(7), ip-link(8), ip-address(8), operational states
Virtual links and switches veth(4), kernel bridge documentation, bridge(8), TUN/TAP
Routing and neighbours ip-route(8), ARP implementation, ip-neighbour(8), IPv4 forwarding sysctl
Protocols IPv4, ARP, ICMP, TCP, UDP, CIDR, router requirements
Practical inspection ping, tcpdump, ss, curl

You do not need to read all the specifications before doing the lab. Use a linked manual when you want to verify a detail or explore an option beyond the lesson.

Validation record

The documented setup commands were exercised in disposable Linux user, mount, and network namespaces, not on the reader's machine. 43 checks passed, covering separate loopback contexts, direct veth connectivity, the link-down experiment, all six host-to-host directions on the three-host bridge, bridge membership and MAC learning, ARP/ICMP behaviour, listener binding, and cleanup. The Stage 4 interfaces, address plan, routes, and forwarding-disabled failure were also checked.

Testing limits: this sandbox denies writes to /proc/sys, so enabling router forwarding and the subsequent successful routed exchanges, routed packet captures, and missing-return-route experiment were not runtime-validated here. Those commands and explanations were reviewed against the kernel and routing documentation. tcpdump was unavailable in the validation environment: the switched-LAN packet observations were verified using native Linux packet sockets, while the documented tcpdump options were checked against its manual.

The validation environment used 6.18.44 and ip utility, iproute2-6.15.0, libbpf 1.5.0. Detailed check results are included as validation.json in the bundle. Shell syntax, internal links, and image references were checked separately.

Illustrative outputs in the teaching sections remain labelled as examples. Interface indices, automatically generated MAC addresses, exact link states, and neighbour-cache timing should not be treated as fixed values.