Lesson 09 / 18
Variable-Length Subnetting
The method of splitting with different masks, the alignment rule, building the example organization's plan with an overlap test, and route summarization.
Contents
The previous lesson showed that equal splitting could not stretch the 192.168.10.0/24
block to cover the organization’s requirements: the method needed 640 addresses, and only
256 were on hand. The source of the flaw was the requirement that every subnet carry the
same mask.
CIDR removes this requirement. In the variable length subnet mask (VLSM) approach, each subnet is sized to its own requirement. This lesson’s question is what rule governs this split and how the result is tested.
The Alignment Rule
Variable splitting carries exactly one constraint: a subnet’s starting address must be a multiple of its own size.
The rule is not a formatting preference; it is the forced consequence of mask arithmetic.
A /27 block’s last five bits are host bits, and all of them must be zero in the network
address; this only holds when the address is a multiple of 32. The notation
192.168.10.200/27 does not define a valid network, because 200 is not a multiple of
32 — that address is a host inside the 192.168.10.192/27 network.
| Prefix | Block size | Valid starting points (last byte) |
|---|---|---|
| /25 | 128 | 0, 128 |
| /26 | 64 | 0, 64, 128, 192 |
| /27 | 32 | 0, 32, 64, …, 224 |
| /28 | 16 | 0, 16, 32, …, 240 |
| /30 | 4 | 0, 4, 8, …, 252 |
The rule’s consequence for planning is this: larger blocks must be placed first. If smaller blocks are placed first, the next larger block is forced to jump ahead to its own alignment point, leaving an unusable gap in between.
Building the Plan
The method is three steps:
- Sort the sections by host requirement in descending order.
- For each section, pick the longest prefix satisfying .
- Place the blocks in order, respecting alignment.
The organization’s requirements, already sorted: guest wireless 100, lab 50, administration 20, server room 10, point-to-point link 2 hosts.
Guest wireless, 100 hosts. Since , /25 is sufficient; /26
gives only 62. Block 192.168.10.0/25, range .1 – .126, broadcast .127.
Lab, 50 hosts. /26 gives 62 hosts. The next aligned address is 128. Block
192.168.10.128/26, range .129 – .190, broadcast .191.
Administration, 20 hosts. /27 gives 30 hosts. The next aligned address is 192.
Block 192.168.10.192/27, range .193 – .222, broadcast .223.
Server room, 10 hosts. /28 gives 14 hosts. The next aligned address is 224. Block
192.168.10.224/28, range .225 – .238, broadcast .239.
Point-to-point link, 2 hosts. /30 gives exactly 2 hosts. The next aligned address
is 240. Block 192.168.10.240/30, range .241 – .242, broadcast .243.
Verifying the Plan
A hand computation must be tested with a program. The program below encodes the method and produces the plan.
import ipaddress import math BLOCK = ipaddress.ip_network("192.168.10.0/24") REQUIREMENTS = [ ("Guest wireless", 100), ("Lab", 50), ("Administration", 20), ("Server room", 10), ("Link", 2), ] def required_prefix(hosts: int) -> int: """Longest sufficient prefix for `hosts` usable addresses.""" return 32 - math.ceil(math.log2(hosts + 2)) def vlsm_plan(block: ipaddress.IPv4Network, requirements: list[tuple[str, int]]) -> list[tuple]: sorted_reqs = sorted(requirements, key=lambda k: k[1], reverse=True) cursor = int(block.network_address) plan = [] for name, hosts in sorted_reqs: prefix = required_prefix(hosts) size = 2 ** (32 - prefix) if cursor % size: # alignment: the block must land on its own size cursor += size - (cursor % size) subnet = ipaddress.ip_network((cursor, prefix)) if not subnet.subnet_of(block): raise ValueError(f"no room left for {name}") plan.append((name, hosts, subnet)) cursor += size return plan plan = vlsm_plan(BLOCK, REQUIREMENTS) print(f"{'Section':18s} {'Hosts':>7s} {'Block':<19s} {'Mask':<16s} " f"{'Broadcast':<15s} {'Range':<31s} {'Spare':>4s}") for name, hosts, subnet in plan: d = list(subnet.hosts()) rng = f"{d[0]} - {d[-1]}" print(f"{name:18s} {hosts:7d} {str(subnet):<19s} {str(subnet.netmask):<16s} " f"{str(subnet.broadcast_address):<15s} {rng:<31s} {len(d) - hosts:4d}") used = sum(subnet.num_addresses for _, _, subnet in plan) print(f"\naddresses used: {used} / {BLOCK.num_addresses} " f"spare: {BLOCK.num_addresses - used}") networks = [subnet for _, _, subnet in plan] for i in range(len(networks)): for j in range(i + 1, len(networks)): assert not networks[i].overlaps(networks[j]), (networks[i], networks[j]) print("overlap test: passed")
Section Hosts Block Mask Broadcast Range Spare Guest wireless 100 192.168.10.0/25 255.255.255.128 192.168.10.127 192.168.10.1 - 192.168.10.126 26 Lab 50 192.168.10.128/26 255.255.255.192 192.168.10.191 192.168.10.129 - 192.168.10.190 12 Administration 20 192.168.10.192/27 255.255.255.224 192.168.10.223 192.168.10.193 - 192.168.10.222 10 Server room 10 192.168.10.224/28 255.255.255.240 192.168.10.239 192.168.10.225 - 192.168.10.238 4 Link 2 192.168.10.240/30 255.255.255.252 192.168.10.243 192.168.10.241 - 192.168.10.242 0 addresses used: 244 / 256 spare: 12 overlap test: passed
The hand computation is fully confirmed. Where equal splitting demanded 640 addresses, variable splitting made do with 244, leaving 12 addresses spare.
The hosts + 2 term inside required_prefix encodes the fact that every network spends
its own network and broadcast addresses. The call to math.ceil(math.log2(...)) rounds
the required host count up: for 102, , giving prefix
.
The overlap test is not a formality. The most common mistake in hand-built plans is one
block falling inside the previous one; the overlaps call catches this mistake instead
of letting it pass silently.
The Finalized Plan
This is the plan the course uses from here on:
| Section | Block | Mask | Gateway | Usable range | Broadcast |
|---|---|---|---|---|---|
| Guest wireless | 192.168.10.0/25 |
255.255.255.128 | .1 |
.1 – .126 |
.127 |
| Lab | 192.168.10.128/26 |
255.255.255.192 | .129 |
.129 – .190 |
.191 |
| Administration | 192.168.10.192/27 |
255.255.255.224 | .193 |
.193 – .222 |
.223 |
| Server room | 192.168.10.224/28 |
255.255.255.240 | .225 |
.225 – .238 |
.239 |
| Link | 192.168.10.240/30 |
255.255.255.252 | — | .241 – .242 |
.243 |
In each section, the first usable address is reserved for the router interface. The
client introduced in the course’s first lesson, 192.168.10.196, is in the
administration network, and its gateway is 192.168.10.193 — the plan confirms both
values.
The 12 spare addresses lie between 192.168.10.244 and 192.168.10.255 and correspond
to three /30 blocks: .244/30, .248/30, .252/30. These are available for
point-to-point links added later.
The Effect of Ordering
What would happen if the sections were placed in ascending order? The smallest block goes first, and each subsequent block jumps ahead to align:
| Order | Section | Block | Gap skipped |
|---|---|---|---|
| Ascending | Link | 192.168.10.0/30 |
— |
| Ascending | Server room | 192.168.10.16/28 |
.4 – .15 (12 addresses) |
| Ascending | Administration | 192.168.10.32/27 |
— |
| Ascending | Lab | 192.168.10.64/26 |
— |
| Ascending | Guest | 192.168.10.128/25 |
— |
The plan still fits, but the spare 12 addresses sit in the middle of the block and split into two separate pieces. Under descending order, the same 12 addresses sit at the end of the block, contiguous.
The difference shows up in growth. A contiguous gap sitting at the end can be converted into a larger subnet; a fragmented gap left in the middle can only be used at its own size. This is the address-space counterpart of the fragmentation problem introduced in the context of allocators in the Memory Layout — Stack and Heap lesson of the How Computers Work course.
Route Summarization
Variable splitting’s second benefit is in the routing table. Contiguous, aligned subnets can be summarized into a single prefix — a technique called route summarization.
The organization’s five subnets are all inside the 192.168.10.0/24 block. The
provider’s router does not need to know these five networks individually; a single line
is enough:
192.168.10.0/24 -> 203.0.113.10
Summarization is a direct consequence of the alignment rule. Four contiguous /24
blocks — 192.168.8.0, 192.168.9.0, 192.168.10.0, 192.168.11.0 — can be referred
to with a single 192.168.8.0/22 prefix, because all four form an aligned group of four
starting at a multiple of 8. The same group of four could not be summarized if it started
at 192.168.9.0.
The gain from summarization is direct: the number of rows in the routing table drops, lookups get cheaper, and a change inside the internal network does not affect external tables. This is the rationale for distributing addresses hierarchically.
Documenting the Plan
An address plan is used not only at the moment it is computed but at every subsequent change. The fields that must be documented are: section name, block, mask, gateway address, the range reserved for static assignments, the range left for dynamic distribution, and growth headroom.
Growth headroom is easy to overlook. In the plan above, the guest network has 26 spare
addresses, the lab has 12, and administration has 10; the server room network has only 4
spare addresses left. If the number of servers rises to 15, the /28 is not enough and
the block must be resized. Whoever builds the plan should note upfront which section
overflows at which threshold.
Summary
- In variable-length splitting, each subnet is sized to its own requirement; the only constraint is that the starting address be a multiple of the block size.
- The method is three steps: sort requirements in descending order, pick the longest sufficient prefix for each, and place them respecting alignment.
- The organization’s five networks fit inside
192.168.10.0/24using 244 addresses; equal splitting would have needed 640 addresses for the same job. - Descending order leaves the spare addresses at the end of the block, contiguous; ascending order fragments the gap in the middle.
- Contiguous, aligned subnets can be summarized into a single prefix; the five subnets
are advertised outward as
192.168.10.0/24. - Growth headroom must also be recorded when documenting the plan; in the example plan, the tightest headroom is 4 addresses, in the server room network.
Next Step
This plan is one way of coping with the scarcity of the 32-bit address space: using private addresses and splitting them carefully. There is another way that removes the scarcity itself — expanding the address space. The next lesson covers 128-bit addresses, their notation rules, how interfaces configure their own addresses, and the methods by which the two versions interoperate.
To keep your progress and take notes, Log in
My notes
Log in to take notes.