Topic 1.2
CIDR Notation and Subnet Math
In one line
CIDR writes the mask as a prefix length (/24); a /n network has 2^(32−n) addresses, and splitting or combining networks is just moving that number.
Key ideas
- 01
CIDR (Classless Inter-Domain Routing) writes
192.168.1.0/24: the/24means the first 24 bits are the network. It replaced the old fixed Class A/B/C scheme, which wasted huge address blocks. - 02
Size rule: a /n block has 2^(32 − n) addresses. /32 = 1 address (one host), /30 = 4, /28 = 16, /24 = 256, /20 = 4,096, /16 = 65,536, /8 = 16.7 million. Each step of 1 in the prefix halves or doubles the size.
- 03
Splitting: a /24 contains two /25s, four /26s, eight /27s, and so on.
10.0.0.0/24=10.0.0.0/25+10.0.0.128/25. Aggregating works the other way: adjacent, aligned blocks combine into a larger one (route SUMMARISATION). - 04
Mask conversions worth memorising: /24 = 255.255.255.0, /16 = 255.255.0.0, /20 = 255.255.240.0, /26 = 255.255.255.192, /28 = 255.255.255.240.
- 05
Is an address inside a range? Compare the first n bits.
10.0.5.9is inside10.0.0.0/16(the first 16 bits are 10.0) and also inside10.0.4.0/23, which covers 10.0.4.0–10.0.5.255, but not inside10.0.6.0/23. Ranges that don't end on an octet boundary are where mistakes happen, so check withipcalcor Python'sipaddressmodule rather than guessing. - 06
Practical planning (the same rule as the AWS and Terraform courses): give every environment a non-overlapping block, size subnets generously for container workloads, and leave room to grow. Overlapping ranges make peering and VPNs impossible later.
Code & diagrams
Python's standard library does subnet math reliably, which makes it handy in scripts and reviews.
import ipaddress
net = ipaddress.ip_network("10.20.0.0/16")
print(net.num_addresses) # 65536
print(list(net.subnets(new_prefix=20))[:3]) # first three /20s
print(ipaddress.ip_address("10.20.33.7") in ipaddress.ip_network("10.20.32.0/20")) # True
# Do two ranges overlap?
a, b = ipaddress.ip_network("10.20.0.0/16"), ipaddress.ip_network("10.20.128.0/17")
print(a.overlaps(b)) # TrueExplain it without notes
Why does increasing the prefix length by one halve the number of addresses?
Practice
Split 172.16.0.0/22 into four equal subnets. Write them in CIDR.
Does 192.168.10.200 belong to 192.168.10.128/26?
Trade-offs
- ↔
Large subnets are simple and leave room for growth but waste address space; small ones conserve space but run out, and resizing a subnet in the cloud usually means recreating it.
Done when you can
I can compute the size of any /n block.
I can split a block into smaller subnets and write them in CIDR.
I can check whether an address is in a range (and use a tool to confirm).