IPv4 Subnetting on Linux Explained with Examples

IPv4 Subnetting on Linux

If you have ever set up a Linux server and later discovered that two of your services could not talk to each other, or that your entire network ground to a halt because of a broadcast storm, there is a good chance the root cause was a misconfigured subnet. IPv4 Subnetting on Linux is one of those foundational skills that separates sysadmins who react to problems from those who prevent them. In this guide, you will learn exactly how subnetting works, why it matters in a Linux environment, and how to apply it using real commands that work on Ubuntu, Debian, RHEL, Fedora, and AlmaLinux. No theory without practice. Every concept here gets a working example.

Prerequisites

Before you run any command in this guide, make sure your environment checks these boxes:

  • Operating System: Ubuntu 20.04/22.04/24.04, Debian 11/12, RHEL 8/9, Fedora 38+, AlmaLinux 8/9, or Rocky Linux 8/9
  • User permissions: sudo or root access (required for all ip and nmcli commands that modify network state)
  • Tools required:
    • ipcalc (install instructions in Step 2)
    • iproute2 package (provides the ip command; pre-installed on most modern distros)
    • NetworkManager with nmcli (available on all RHEL-family and most Debian-family systems)
  • Basic familiarity with: the Linux terminal, reading IP addresses, and knowing what a network interface is
  • Network interface name: run ip link show to confirm your interface name (could be eth0, ens33, enp3s0, etc.)

Step 1: Understand What IPv4 Subnetting Actually Does

Before touching any command, you need to know what problem subnetting solves. Without this context, you will copy-paste commands that work in the lab and break things in production.

What Is a Subnet?

A subnet (short for subnetwork) is a logically divided segment of a larger IP network. When you subnet a network, you split one big address block into smaller, isolated pieces. Each piece has its own range of usable IPs, a network address, and a broadcast address.

Why does this matter on Linux specifically? When you assign an IP address to a Linux network interface, the kernel uses the subnet mask you provide to decide two things:

  1. Which destination IPs are on the local network (reachable directly)
  2. Which destination IPs must go through a gateway (routed traffic)

Get the subnet wrong, and traffic that should stay local gets routed out. Traffic that should be routed gets dropped. Security boundaries you thought you configured do not actually exist.

The Three Private IPv4 Ranges Every Sysadmin Must Know

These are the ranges defined in RFC 1918 that you use in private networks:

Range CIDR Block Total Addresses
Class A private 10.0.0.0/8 16,777,216
Class B private 172.16.0.0/12 1,048,576
Class C private 192.168.0.0/16 65,536

You will work within these ranges for almost every Linux server subnet on internal infrastructure.

CIDR Notation vs. Dotted-Decimal Subnet Mask

Linux tools use CIDR notation (e.g., /24) instead of the old dotted-decimal format (e.g., 255.255.255.0). CIDR counts the number of consecutive 1 bits in the subnet mask binary representation. A /24 means the first 24 bits define the network, leaving 8 bits for host addresses.

Here is a quick reference you will use constantly:

CIDR Subnet Mask Usable Hosts Common Use
/30 255.255.255.252 2 Point-to-point links
/29 255.255.255.248 6 Small VLANs, management
/28 255.255.255.240 14 Small server clusters
/27 255.255.255.224 30 Department segments
/26 255.255.255.192 62 Medium server groups
/24 255.255.255.0 254 Standard LAN segment
/22 255.255.252.0 1,022 Large campus networks

Step 2: Install and Use ipcalc to Plan Your Subnets on Linux

Never configure a subnet on a production Linux server without calculating it first. ipcalc is the command-line tool that does the math for you and eliminates calculation mistakes before they reach your network.

Install ipcalc

On Debian/Ubuntu:

sudo apt update && sudo apt install ipcalc -y

On RHEL/Fedora/AlmaLinux:

sudo dnf install ipcalc -y

Why install this before anything else: ipcalc prevents you from assigning a broadcast address as a host IP or creating overlapping subnets, both of which cause silent networking failures that are painful to debug at 2 AM.

Calculate a Basic Subnet

Run ipcalc against an IP address and CIDR prefix:

ipcalc 192.168.10.0/24

Expected output:

Address:   192.168.10.0         11000000.10101000.00001010. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.10.0/24      11000000.10101000.00001010. 00000000
HostMin:   192.168.10.1         11000000.10101000.00001010. 00000001
HostMax:   192.168.10.254       11000000.10101000.00001010. 11111110
Broadcast: 192.168.10.255       11000000.10101000.00001010. 11111111
Hosts/Net: 254                   Class C, Private Internet

Read the output carefully:

  • Network: 192.168.10.0 is the network address; never assign this to any interface
  • HostMin/HostMax: the valid assignable IP range for your interfaces
  • Broadcast: 192.168.10.255 is reserved for broadcast; assigning this to a host breaks ARP responses for the entire subnet
  • Hosts/Net: tells you the maximum number of devices this subnet can support

Split a Network into Multiple Subnets

Suppose you manage a /24 and need to split it into segments of at least 15 hosts each:

ipcalc 172.16.1.0/24 -s 15 15

Expected output (trimmed):

Network:   172.16.1.0/24
...
1. Requested size: 15 hosts
Netmask:   255.255.255.224 = 27
Network:   172.16.1.0/27
HostMin:   172.16.1.1
HostMax:   172.16.1.30
Broadcast: 172.16.1.31
Hosts/Net: 30

2. Requested size: 15 hosts
Network:   172.16.1.32/27
HostMin:   172.16.1.33
HostMax:   172.16.1.62
Broadcast: 172.16.1.63
Hosts/Net: 30

Unused:
172.16.1.64/26
172.16.1.128/25

The Unused section at the bottom shows remaining address space. This is critical for growth planning. You know exactly how much room you have before you need to expand the base network.

Step 3: Check Your Current Linux Network and Subnet Configuration

Before you change anything, always audit the existing state. Knowing what is already configured prevents you from breaking something that works.

View All IP Addresses and Subnet Masks

ip addr show

Or limit output to a specific interface and IPv4 only:

ip -4 addr show eth0

Expected output:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.1.50/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 85873sec preferred_lft 85873sec

The inet line gives you the assigned IP (192.168.1.50), the CIDR prefix (/24), and the broadcast address (brd 192.168.1.255).

Why use ip addr and not ifconfig: ifconfig is part of the deprecated net-tools package. Modern Linux kernels expose network namespace and policy routing features that only ip from the iproute2 package can display correctly. Running ifconfig on a server with multiple routing tables gives you an incomplete picture.

View the Routing Table

ip route show

Expected output:

default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.50 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.50

The default route is where traffic goes when no specific route matches. The second line is the connected route that the kernel adds automatically when you assign an IP to an interface. This connected route is what makes local subnet communication work without any manual routing rules.

Step 4: Configure IPv4 Subnetting on Linux with the ip Command

The ip command from iproute2 is how you apply subnet configuration at the kernel level. Changes made with ip are immediate but temporary; they do not survive a reboot. This makes it perfect for testing subnet changes before making them permanent.

Assign an IP Address with a Specific Subnet

sudo ip addr add 192.168.10.1/26 dev eth0

Why /26 and not /24 in this example: a /26 gives you exactly 62 usable host addresses (192.168.10.1 through 192.168.10.62). If you are setting up an isolated segment for a server group, using a /26 instead of /24 means devices outside that /26 range cannot accidentally be on the same local segment. This enforces a network boundary without any firewall rule.

Verify the assignment worked:

ip -4 addr show eth0

You should see both the original IP and the new one listed under the same interface.

Add a Secondary IP on a Different Subnet

Linux interfaces support multiple IP addresses. You can assign a second IP on a completely different subnet to the same physical interface:

sudo ip addr add 10.10.1.1/27 dev eth0

Why this is useful: in a VLSM setup (Variable Length Subnet Masking), a Linux router often needs a gateway IP in each subnet it connects. One physical interface can serve multiple logical subnet segments through secondary IP assignment.

Add a Static Route Between Two Subnets

Just assigning IPs is not enough when you need traffic to flow between two different subnets. You need an explicit route:

sudo ip route add 192.168.20.0/24 via 192.168.10.1

Why add this manually: the Linux kernel only installs connected routes automatically (the subnets directly assigned to interfaces). For any other network segment, you must tell the kernel which gateway to send traffic through. Without this route, packets destined for 192.168.20.x go to the default gateway, which may drop them entirely.

Verify the route was added:

ip route show

You should see 192.168.20.0/24 via 192.168.10.1 in the output.

Remove an IP Address

sudo ip addr del 192.168.10.1/26 dev eth0

Always specify the full CIDR prefix when deleting. Without the prefix, the command fails if multiple IPs exist on the interface.

Step 5: Make Subnet Configuration Persistent with nmcli

This is the step that most tutorials bury or skip. Runtime ip commands vanish on reboot. For a production Linux server, you must write the configuration through NetworkManager using nmcli.

List Existing Connection Profiles

nmcli con show

Expected output:

NAME     UUID                                  TYPE      DEVICE
eth0     a1b2c3d4-e5f6-7890-abcd-ef1234567890  ethernet  eth0

The NAME column is what you use in subsequent nmcli commands.

Configure a Static IP, Gateway, and Subnet

sudo nmcli con mod eth0 ipv4.addresses 192.168.10.1/26
sudo nmcli con mod eth0 ipv4.gateway 192.168.10.254
sudo nmcli con mod eth0 ipv4.dns "8.8.8.8,1.1.1.1"
sudo nmcli con mod eth0 ipv4.method manual

Why ipv4.method manual is required: if you skip this step, NetworkManager keeps DHCP active and overwrites your static IP on the next DHCP lease renewal or reboot. Setting manual tells NetworkManager to stop asking the DHCP server and use only what you defined.

Apply the Changes

sudo nmcli con up eth0

Why use nmcli con up instead of just restarting the interface: this command tells NetworkManager to re-read the saved profile and apply it to the live interface atomically. A plain ip link set eth0 down && ip link set eth0 up does not reload the nmcli profile.

Verify the Persistent Configuration

Run both commands to confirm what is configured and what is active:

nmcli con show eth0 | grep ipv4
ip addr show eth0

If both commands agree on the IP and subnet, your configuration is correct and will survive reboots.

Step 6: Real-World VLSM Example: Subnet a Company Network on Linux

VLSM (Variable Length Subnet Masking) is how you allocate IP space efficiently when different departments or services need different numbers of hosts. Here is a real scenario encountered multiple times when managing production infrastructure.

The Scenario

You have the block 10.10.0.0/22 (1,022 usable hosts). You need three segments:

  • Engineering: 200 hosts
  • Operations: 50 hosts
  • Management: 10 hosts

VLSM Calculation

Always allocate from largest to smallest. This prevents fragmentation.

Engineering (200 hosts needed):

ipcalc 10.10.0.0/24
# /24 gives 254 usable hosts. Assigned: 10.10.0.0/24
# Gateway: 10.10.0.1

Operations (50 hosts needed):

ipcalc 10.10.1.0/26
# /26 gives 62 usable hosts. Assigned: 10.10.1.0/26
# Gateway: 10.10.1.1

Management (10 hosts needed):

ipcalc 10.10.1.64/28
# /28 gives 14 usable hosts. Assigned: 10.10.1.64/28
# Gateway: 10.10.1.65

None of these ranges overlap. The subnets sit cleanly inside the parent 10.10.0.0/22 block.

Apply the VLSM Subnets to a Linux Router

If a Linux machine acts as the router between these segments, assign a gateway IP on each interface:

sudo ip addr add 10.10.0.1/24 dev eth0
sudo ip addr add 10.10.1.1/26 dev eth1
sudo ip addr add 10.10.1.65/28 dev eth2

Confirm the routing table now shows connected routes for all three:

ip route show

Expected output includes:

10.10.0.0/24 dev eth0 proto kernel scope link src 10.10.0.1
10.10.1.0/26 dev eth1 proto kernel scope link src 10.10.1.1
10.10.1.64/28 dev eth2 proto kernel scope link src 10.10.1.65

Each subnet now has a connected route. Hosts on each segment can reach their gateway, and the Linux router can forward between them without needing a separate routing daemon for simple setups like this.

Troubleshooting Common IPv4 Subnetting Errors on Linux

Even experienced sysadmins run into these. Here are the five issues that come up most often in the field, along with the exact fix for each.

Error 1: RTNETLINK answers: File exists

Cause: You are trying to add a route that already exists in the routing table, or the subnet you are adding overlaps with an existing one.

Fix:

ip route show
# Identify the conflicting route, then:
sudo ip route del 192.168.20.0/24
sudo ip route add 192.168.20.0/24 via 192.168.10.1

Alternatively, use replace to avoid the two-step:

sudo ip route replace 192.168.20.0/24 via 192.168.10.1

Error 2: Host Is Unreachable Even Though Both Are in the Same Network

Cause: The prefix length assigned to one of the hosts is wrong. For example, one host has 192.168.10.50/24 but the interface it should reach has 192.168.10.50/28. From the /28 host’s perspective, anything above 192.168.10.62 is off-subnet and gets routed to the gateway instead of resolved locally.

Fix:

ip -4 addr show
# Compare prefix lengths on both machines
# Correct the mismatched one:
sudo ip addr del 192.168.10.50/28 dev eth0
sudo ip addr add 192.168.10.50/24 dev eth0

Error 3: Subnet Configuration Disappeared After Reboot

Cause: You used ip addr add without saving through nmcli or a network config file. Runtime kernel state does not persist.

Fix: Reconfigure using nmcli as shown in Step 5. For Ubuntu systems using Netplan, write your subnet to /etc/netplan/01-netcfg.yaml:

network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 192.168.10.1/26
      gateway4: 192.168.10.254
      nameservers:
        addresses: [8.8.8.8, 1.1.1.1]

Then apply:

sudo netplan apply

Error 4: nmcli con mod Applied But IP Did Not Change

Cause: You modified the profile but never brought the connection back up. nmcli con mod writes to disk; nmcli con up applies it.

Fix:

sudo nmcli con up eth0

If the interface is active and shows the old IP, force a full reconnect:

sudo nmcli con down eth0 && sudo nmcli con up eth0

Error 5: ipcalc Gives Different Output Than Expected on RHEL

Cause: RHEL ships a different version of ipcalc from the initscripts package that uses different syntax flags compared to the Debian/standalone version.

Fix: On RHEL 8+, use ipcalc from the ipcalc package (not initscripts) for full CIDR splitting support:

sudo dnf install ipcalc -y
ipcalc --version

Confirm the version is ipcalc 1.0.0 or higher for CIDR subnet splitting with the -s flag.

IPv4 Subnetting on Linux: Best Practices Before You Go Live

You can subnet correctly in a lab and still cause outages in production if you skip these steps:

  • Document every subnet assignment in an IPAM spreadsheet or tool before applying any nmcli change to a running server
  • Use /30 for point-to-point links between routers or VMs; it wastes only 2 addresses but keeps your address space clean
  • Isolate management interfaces on a dedicated /28 or /29 subnet, separate from application traffic; this limits lateral movement in a breach scenario
  • Always run ipcalc before configuring, even for subnets you think you know by heart; a single off-by-one bit error in a prefix causes hours of debugging
  • Verify with two commands after every change: nmcli con show [interface] | grep ipv4 (what is saved) and ip addr show [interface] (what is running); a mismatch means the configuration did not apply cleanly
  • Test subnet changes in a VM or staging environment before touching production interfaces, especially when modifying the interface you use for SSH access (you can lock yourself out)
r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts