Thuta Learning
BasicDevOps & Toolsbeginner

Subnetting in Practice

What you'll walk away with

  • Explain the core ideas behind Subnetting in Practice
  • Read the diagram and trace how data actually moves through it
  • Run the sample code and verify its output

Build the mental model

Subnetting is taking one network and splitting it into several smaller ones by borrowing bits from the host portion and giving them to the network portion. A /24 has 8 host bits; borrow 2 and you get a /26 — four networks of 64 addresses each instead of one network of 256.

There are three separate reasons to do it, and they are often confused. The first is broadcast containment: a broadcast reaches every host in its subnet and is processed by every one of them, so a flat network of thousands of machines burns real CPU and bandwidth on traffic almost nobody wanted. The second is isolation and policy — traffic between subnets must pass through a router, and a router is exactly where you can apply filtering, so putting printers, servers, and guest Wi-Fi in separate subnets gives you somewhere to enforce rules. The third is address efficiency: a point-to-point link between two routers needs exactly two addresses, and handing it a whole /24 wastes 254 of them.

Inside each subnet, two addresses are reserved. The all-zeros host is the network address, the name of the subnet itself; the all-ones host is the directed broadcast address. Neither can be assigned to a machine, and that is exactly where 2^n - 2 comes from: n host bits give 2^n addresses, minus those two. The formula has exceptions. RFC 3021 lets a /31 use both of its addresses on point-to-point links, because a two-host link has no use for a broadcast, and a /32 is a single host route. So do not memorize "a /24 has 254 hosts" — compute it from the actual prefix every time.

text
SPLITTING 192.168.1.0/24 INTO FOUR /26 SUBNETS
----------------------------------------------
BEFORE: one /24 -- 256 addresses, 254 usable, ONE broadcast domain

 +-------------------------------------------------------------+
 |                      192.168.1.0/24                         |
 |   .0 = network        .1 - .254 usable        .255 = bcast  |
 +-------------------------------------------------------------+

Borrow 2 host bits (8 host bits -> 6), giving 2^2 = 4 subnets:

 AFTER:
 +--------------+--------------+--------------+--------------+
 | .0    - .63  | .64   - .127 | .128  - .191 | .192  - .255 |
 |     /26      |     /26      |     /26      |     /26      |
 +--------------+--------------+--------------+--------------+
   network .0     network .64    network .128   network .192
   first   .1     first   .65    first   .129   first   .193
   last    .62    last    .126   last    .190   last    .254
   bcast   .63    bcast   .127   bcast   .191   bcast   .255
   usable  62     usable  62     usable  62     usable  62

Each block loses 2 addresses (network id + broadcast), so
4 x 62 = 248 usable -- six fewer than the original 254.

Connect it to a real scenario

Say you are given 192.168.1.0/24 for a small office and asked to separate staff machines, servers, and guest Wi-Fi. Splitting into four /26 blocks gives you 192.168.1.0/26, .64/26, .128/26, and .192/26, each holding 64 addresses. Assign staff the first, servers the second, guests the third, and keep the fourth for growth.

Now work through one block carefully, because this is exactly where mistakes happen. In 192.168.1.64/26, the network address is 192.168.1.64 and the broadcast address is 192.168.1.127. The usable hosts are 192.168.1.65 through 192.168.1.126 — 62 of them. A common bug is assigning .64 or .127 to a machine because they "look free": .64 will be rejected or behave strangely, and .127 will make every host in the subnet process traffic aimed at it. The block boundaries move with every subnet, which is why .64 is a network address here but a perfectly ordinary host address in a plain /24.

Notice the arithmetic cost too. One /24 gave 254 usable addresses; four /26s give 4 x 62 = 248. Subnetting always loses two addresses per subnet, so splitting aggressively into many tiny subnets burns address space fast. The code below computes all four ranges, then shows how the usable count falls as the prefix grows — including the /31 exception.

Try the working example

python
import ipaddress

parent = ipaddress.ip_network("192.168.1.0/24")
print("parent %s: %d addresses, %d usable"
      % (parent, parent.num_addresses, parent.num_addresses - 2))
print()

print("%-17s%-14s%-15s%s"
      % ("subnet", "network", "broadcast", "usable range"))
print("-" * 72)
for sub in parent.subnets(new_prefix=26):
    hosts = list(sub.hosts())
    print("%-17s%-14s%-15s%s - %s"
          % (sub, sub.network_address, sub.broadcast_address,
             hosts[0], hosts[-1]))
print()

# Why "2^n - 2": the all-zeros host is the network id and the
# all-ones host is the broadcast address, so neither is assignable.
for prefix in (24, 26, 28, 30, 31, 32):
    net = ipaddress.ip_network("10.0.0.0/%d" % prefix)
    usable = len(list(net.hosts()))
    print("/%-3d %5d addresses -> %5d usable" % (prefix, net.num_addresses,
                                                 usable))
You should see
parent 192.168.1.0/24: 256 addresses, 254 usable

subnet           network       broadcast      usable range
------------------------------------------------------------------------
192.168.1.0/26   192.168.1.0   192.168.1.63   192.168.1.1 - 192.168.1.62
192.168.1.64/26  192.168.1.64  192.168.1.127  192.168.1.65 - 192.168.1.126
192.168.1.128/26 192.168.1.128 192.168.1.191  192.168.1.129 - 192.168.1.190
192.168.1.192/26 192.168.1.192 192.168.1.255  192.168.1.193 - 192.168.1.254

/24    256 addresses ->   254 usable
/26     64 addresses ->    62 usable
/28     16 addresses ->    14 usable
/30      4 addresses ->     2 usable
/31      2 addresses ->     2 usable
/32      1 addresses ->     1 usable

5-minute try-it

Change new_prefix=26 to 28 and see how many subnets you get and how many usable hosts each holds. Then compute how many total usable addresses you lose splitting a /24 into /26s versus into /28s, and compare using /30 versus /31 for router-to-router links.

One important caution

Assuming a /24 always means 254 usable hosts without checking the actual mask — the same arithmetic gives 62 on a /26 and 2 on a /30, so an unchecked assumption corrupts the whole address plan

Assigning a subnet's first address (network id) or last address (broadcast) to a host — .64 is a network address in a /26 but an ordinary host address in a /24, which is why the boundary is easy to miss

RFC 3021 — Using 31-Bit Prefixes on IPv4 Point-to-Point LinksComputer Networking

Easy traps

  • Assuming a /24 always means 254 usable hosts without checking the actual mask — the same arithmetic gives 62 on a /26 and 2 on a /30, so an unchecked assumption corrupts the whole address plan
  • Assigning a subnet's first address (network id) or last address (broadcast) to a host — .64 is a network address in a /26 but an ordinary host address in a /24, which is why the boundary is easy to miss
  • Validate sample code in a local or test environment before applying it to a production network.

Exercise

Change new_prefix=26 to 28 and see how many subnets you get and how many usable hosts each holds. Then compute how many total usable addresses you lose splitting a /24 into /26s versus into /28s, and compare using /30 versus /31 for router-to-router links.

You'll know it worked when: parent 192.168.1.0/24: 256 addresses, 254 usable subnet network broadcast usable range ------------------------------------------------------------------------ 192.168.1.0/26 192.168.1.0 192.168.1.63 192.168.1.1 - 192.168.1.62 192.168.1.64/26 192.168.1.64 192.168.1.127 192.168.1.65 - 192.168.1.126 192.168.1.128/26 192.168.1.128 192.168.1.191 192.168.1.129 - 192.168.1.190 192.168.1.192/26 192.168.1.192 192.168.1.255 192.168.1.193 - 192.168.1.254 /24 256 addresses -> 254 usable /26 64 addresses -> 62 usable /28 16 addresses -> 14 usable /30 4 addresses -> 2 usable /31 2 addresses -> 2 usable /32 1 addresses -> 1 usable

Subnetting in Practice | Thuta Learning