I subdivided a /24 into role-based CIDR subnets and configured a Linux host as a router to forward traffic between them. Correct subnet sizing and route tables produced verified end-to-end reachability with no overlap or black-hole routes.

Objective & Context

Subnetting controls broadcast domains and enforces segmentation; routing connects those segments. This lab plans address space with VLSM and turns a multi-homed Linux box into a forwarding router, the foundation for the VLAN and zero-trust segmentation labs.

Learning Objectives

  • Perform VLSM subnet math with ipcalc to carve a /24 into role-based subnets.
  • Enable IPv4 forwarding on Linux persistently via sysctl.
  • Add, inspect, and remove static routes with the ip route commands.
  • Verify bidirectional reachability across routed segments.
  • Explain how subnetting shrinks broadcast domains and enforces segmentation.

Environment & Prerequisites

Prerequisites

  • A Linux router VM with two interfaces; two client VMs.
  • ipcalc for subnet math; iproute2 for routes.
  • A /24 to subdivide (for example 192.168.10.0/24).
  • A Linux router VM with two network interfaces and two client VMs (or network namespaces).
  • iproute2 installed (standard on modern distributions) and ipcalc (sudo apt install -y ipcalc).
  • Privileged access (sudo) to change sysctl settings and the routing table.
  • A /24 to subdivide, for example 192.168.10.0/24.
  • Comfort reading CIDR notation and binary subnet math.

Step-by-Step Execution

1. Plan subnets with ipcalc

ipcalc 192.168.10.0/24 --split 60 60

Expected output:

1. Requested size: 60 hosts
Netmask:   255.255.255.192 = 26
Network:   192.168.10.0/26
HostMin:   192.168.10.1
HostMax:   192.168.10.62
Broadcast: 192.168.10.63
Hosts/Net: 62

2. Requested size: 60 hosts
Netmask:   255.255.255.192 = 26
Network:   192.168.10.64/26
HostMin:   192.168.10.65
HostMax:   192.168.10.126
Broadcast: 192.168.10.127
Hosts/Net: 62

What this teaches: VLSM planning turns a host-count requirement into exact network, broadcast, and usable ranges before anything is configured.

The classic Debian/Ubuntu ipcalc package takes requested host counts with --split (or -s) and rounds each up to the next prefix boundary: 60 hosts rounds up to 64 addresses, a /26. Verify with: sudo apt install -y ipcalc.

2. Enable IP forwarding [PRIVILEGED]

sysctl -w net.ipv4.ip_forward=1 && echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

Expected output:

net.ipv4.ip_forward = 1

What this teaches: Linux does not forward packets between interfaces by default; ip_forward is the single switch that makes a host a router.

Repeating the echo appends duplicate lines. Prefer a drop-in file instead: echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-router.conf, then sudo sysctl --system.

3. Add and inspect routes

ip route add 192.168.10.64/26 via 192.168.10.62 && ip route show

Expected output:

192.168.10.0/26 dev eth0 proto kernel scope link src 192.168.10.62
192.168.10.64/26 via 192.168.10.62 dev eth0 proto static

What this teaches: the routing table is consulted for every packet, and longest-prefix match decides which route wins.

How It Works

Subnetting borrows host bits to create multiple networks from one block. A /26 splits a /24 into four networks of 62 usable hosts each, and VLSM lets each subnet be sized to its actual need instead of forcing uniform splits. The network address, broadcast address, and usable range all derive mechanically from the prefix length.

Routing is the process of selecting an egress interface and next hop for each destination. Linux consults the routing table for every forwarded packet and applies longest-prefix match: among all matching routes, the one with the longest prefix (most specific network) wins. A default route (0.0.0.0/0) matches everything and therefore loses to any more specific entry.

Enabling net.ipv4.ip_forward lets the kernel move packets between interfaces, which is what turns a multi-homed host into a router. Static routes are explicit entries added by the administrator; they are simple and predictable but do not adapt to failures, which is the problem dynamic routing protocols solve.

Validation & Testing

From a client in subnet A, ping a client in subnet B and trace the path through the router. Pass criteria: successful cross-subnet ping, the router appears as the first hop, and no overlapping routes exist.

traceroute 192.168.10.70

Expected output:

traceroute to 192.168.10.70 (192.168.10.70), 30 hops max, 60 byte packets
 1  192.168.10.1   0.8 ms  0.6 ms  0.5 ms
 2  192.168.10.70  1.4 ms  1.1 ms  1.0 ms

Troubleshooting

SymptomLikely causeFix
No connectivity between subnetsIP forwarding disabled or a missing route on one sideConfirm net.ipv4.ip_forward=1 and that both the router and clients have return routes
One direction works, the other does notAsymmetric routing: the return path is missing on the far hostAdd the reverse route on the destination network's gateway, not just the source side
Wrong route is chosenA less specific route is winning because the intended one was never addedRun ip route get <dst> to see exactly which route the kernel selects
Forwarding works until rebootsysctl -w changed only the runtime valuePersist the setting in /etc/sysctl.conf or /etc/sysctl.d/
Overlapping subnetsTwo subnet plans share addresses, so longest-prefix match behaves unexpectedlyRe-run ipcalc on the full plan and confirm zero overlap before configuring
Advanced: Troubleshooting
  • No cross-subnet traffic: confirm ip_forward=1 and that clients use the router as gateway.
  • Overlapping subnets: recompute with ipcalc; overlaps cause unpredictable routing.
  • Asymmetric routing: ensure return routes exist on both segments.

Key Results

  • Segmented one /24 into 2 role-based /26 subnets with zero overlap.
  • Achieved verified bidirectional reachability across segments.
  • Reduced each broadcast domain by roughly 75% versus a flat /24.
  • Documented a reusable VLSM plan for future segments.

Key Takeaways

  • Plan the address space on paper (or with ipcalc) before touching any interface.
  • ip route get is the fastest way to see which route a packet will take.
  • Persist sysctl changes; runtime-only changes vanish on reboot.
  • Every routed path needs a return route: connectivity is always bidirectional.

Practice Challenges

Challenge 1: Add a third subnet

Goal: Carve a third /26 for a DMZ out of the same /24 and route it through the Linux router.

Hint: Re-run ipcalc with three 60-host requests and add routes on both the router and the clients.

Challenge 2: Simulate a failed link

Goal: Take down one router interface, observe which routes break, and add a backup static route with a higher metric.

Hint: Use ip route add ... metric 200 for the backup path and test with ip route get.