Skip to content

Subnetting and IP Addressing - Primer

Why This Matters

Every network decision you make in ops — VPC design, K8s pod CIDRs, Docker bridge config, firewall rules, VPN tunnels — starts with IP addressing. Get the subnetting wrong and you get overlapping ranges, exhausted address space, or routing black holes that surface at 2 AM. This is not theory. This is the math underneath every ip addr output and every Terraform cidr_block you will ever write.

IPv4 Fundamentals

Address Structure

32 bits. Four octets. Dotted decimal.

Fun fact: IPv4 was defined in RFC 791 (September 1981) by Jon Postel. The 32-bit address space provides 4,294,967,296 addresses — which seemed inexhaustible in 1981 when the internet had fewer than 300 hosts. IANA exhausted the last /8 blocks in February 2011.

  10  .   0   .   1   .  50
00001010.00000000.00000001.00110010

Address Classes (Legacy, Still Referenced)

Class First Octet Default Mask Range
A 1-126 /8 1.0.0.0 - 126.255.255.255
B 128-191 /16 128.0.0.0 - 191.255.255.255
C 192-223 /24 192.0.0.0 - 223.255.255.255

Classes are mostly dead (CIDR replaced them), but people still say "Class C" when they mean /24. Know this so you can translate.

Private Ranges (RFC 1918)

These never route on the public internet. Memorize them.

Remember: The three RFC 1918 ranges start with 10, 172, and 192. Mnemonic: "Ten, one-Seventy-two, one-Ninety-two" — TSN — "The Secret Networks."

Range CIDR Size Common Use
10.0.0.0 - 10.255.255.255 10.0.0.0/8 16.7M hosts Cloud VPCs, large corps
172.16.0.0 - 172.31.255.255 172.16.0.0/12 1M hosts Docker default, mid-size
192.168.0.0 - 192.168.255.255 192.168.0.0/16 65K hosts Home networks, labs

Special Addresses

  • 127.0.0.0/8 — Loopback. 127.0.0.1 is localhost. The entire /8 is loopback.
  • 169.254.0.0/16 — Link-local. Auto-assigned when DHCP fails. If you see this, something is broken.
  • 0.0.0.0 — "All interfaces" (bind) or "default route" (routing table).

CIDR Notation

CIDR = Classless Inter-Domain Routing. The /N tells you how many bits are the network portion.

Fun fact: CIDR was introduced in 1993 (RFC 1519) to slow the exhaustion of IPv4 addresses. Before CIDR, organizations were assigned entire Class A (/8), B (/16), or C (/24) blocks — MIT, Apple, and the US DoD each got a /8 (16.7 million addresses). CIDR allowed allocation at arbitrary prefix lengths, dramatically reducing waste.

10.0.1.0/24
         ^^
         24 bits are network, 8 bits are host
         Network: 10.0.1.0
         Hosts:   10.0.1.1 - 10.0.1.254
         Broadcast: 10.0.1.255

What the Prefix Lengths Mean

CIDR Mask Total IPs Usable Hosts Common Name
/8 255.0.0.0 16,777,216 16,777,214 "Class A"
/16 255.255.0.0 65,536 65,534 "Class B"
/20 255.255.240.0 4,096 4,094 Common VPC
/24 255.255.255.0 256 254 "Class C"
/25 255.255.255.128 128 126 Half a /24
/26 255.255.255.192 64 62 Quarter /24
/27 255.255.255.224 32 30 Small subnet
/28 255.255.255.240 16 14 Tiny subnet
/30 255.255.255.252 4 2 Point-to-point
/31 255.255.255.254 2 2* Point-to-point
/32 255.255.255.255 1 1 Single host

*/31 (RFC 3021): no broadcast, both IPs usable. Used for router-to-router links.

Subnet Math

The Fast Method

Given 10.0.1.64/26:

  1. Prefix length: /26 means 26 network bits, 6 host bits
  2. Block size: 2^6 = 64 addresses per subnet
  3. Network address: 64 is a multiple of 64, so network = 10.0.1.64
  4. Broadcast: network + block size - 1 = 10.0.1.127
  5. Usable range: 10.0.1.65 - 10.0.1.126 (62 hosts)
  6. Next subnet: 10.0.1.128/26

The Cheat: Powers of 2

/24 = 256 hosts (2^8)    block jumps at .0
/25 = 128 hosts (2^7)    block jumps at .0, .128
/26 =  64 hosts (2^6)    block jumps at .0, .64, .128, .192
/27 =  32 hosts (2^5)    block jumps at .0, .32, .64, .96, .128...
/28 =  16 hosts (2^4)    block jumps at .0, .16, .32, .48, .64...

Subtract the prefix from 32 to get host bits. 2^(host bits) = block size.

Remember: Quick subnet sizes — memorize the "magic numbers" for the last octet: /25=128, /26=64, /27=32, /28=16, /29=8, /30=4. Each is half the previous. Start from 256 and keep halving.

Gotcha: Every subnet loses 2 usable addresses: the network address (first) and the broadcast address (last). A /30 has 4 IPs but only 2 are usable — this is why /30 and /31 are used for point-to-point links.

IPv6 Fundamentals

Address Format

128 bits. Eight groups of 4 hex digits, separated by colons.

Name origin: IPv6 was defined in RFC 2460 (1998), though work began in 1994 under the name "IPng" (IP next generation). The 128-bit address space provides 3.4 x 10^38 addresses — roughly 100 addresses per atom on the surface of the Earth. The expansion from 32 to 128 bits was not just "more addresses" — it was designed to never run out, even with wasteful allocation.

2001:0db8:0000:0000:0000:0000:0000:0001
2001:db8::1                              (compressed form)

Compression rules: drop leading zeros per group, replace one run of all-zero groups with ::.

Gotcha: You can only use :: once in an address. 2001:db8::1::2 is invalid because the parser cannot determine how many zero groups each :: represents. If you have two separate runs of zeros, only compress the longer one.

Key IPv6 Addresses

Address Meaning
::1 Loopback (like 127.0.0.1)
fe80::/10 Link-local (always present on every interface)
2000::/3 Global unicast (routable)
fd00::/8 Unique local (like RFC 1918)
ff00::/8 Multicast

IPv6 Prefix Lengths

  • /128 — Single host (like /32 in IPv4)
  • /64 — Standard subnet. Every LAN/VLAN gets a /64. This is non-negotiable in most deployments.
  • /48 — Standard site allocation. Gives you 65,536 /64 subnets.
  • /32 — ISP allocation from RIR.

Dual-Stack

Interview tip: If asked about IPv6 transition strategies, lead with dual-stack. Tunneling (6to4, Teredo) and translation (NAT64/DNS64) are fallback strategies. Dual-stack is the clean path because both protocols run natively — no encapsulation overhead, no address translation complexity.

Running IPv4 and IPv6 simultaneously on the same interfaces. This is the transition strategy — not tunneling, not translation, just both stacks active.

# Interface with both stacks
$ ip addr show eth0
    inet 10.0.1.50/24 ...
    inet6 fe80::1/64 scope link
    inet6 2001:db8::50/64 scope global

Most cloud providers default to dual-stack now. K8s supports dual-stack since v1.23 GA. You will encounter it.

Key Commands

Remember: The essential networking commands mnemonic: "ip addr, ip route, ipcalc" — Addresses on interfaces, Routes between networks, Calculate subnets. These three commands answer 90% of IP addressing questions on any Linux system.

# Show all addresses on all interfaces
ip addr show

# Show routing table (IPv4)
ip -4 route show

# Show routing table (IPv6)
ip -6 route show

# Calculate subnet details
ipcalc 10.0.1.64/26
# Output: Network, Broadcast, HostMin, HostMax, Hosts/Net

# More detailed subnet info (includes binary)
sipcalc 10.0.1.64/26

# Test IPv4 connectivity
ping -4 10.0.1.1

# Test IPv6 connectivity
ping -6 fe80::1%eth0

# Which subnet does this IP belong to?
ipcalc 10.0.1.100/26
# Shows network = 10.0.1.64, confirming .100 is in the .64 block

When Subnetting Matters in Practice

  • VPC design: A /16 VPC gives you 65K IPs. Split into /24 subnets per AZ and tier.
  • K8s pod CIDRs: Cluster needs a pod CIDR (e.g., /16), service CIDR (e.g., /12), and node CIDR. They must not overlap.
  • Docker networks: Default bridge is 172.17.0.0/16. Custom networks get /16 blocks from 172.18+. This eats address space fast.
  • VPN tunnels: Both sides need non-overlapping ranges or you get asymmetric routing nightmares.
  • Multi-cloud / hybrid: Your on-prem 10.0.0.0/8 must not collide with your AWS 10.0.0.0/16 VPC.

Gotcha: The most common subnetting mistake in production: two teams independently choose 10.0.0.0/16 for their VPCs, then need to peer them. Overlapping CIDRs cannot be routed between each other. Plan your IP address space centrally before you need to connect networks.

Under the hood: When you type ipcalc 10.0.1.64/26, the tool performs a bitwise AND between the IP and the subnet mask to derive the network address. The broadcast address is the network address OR'd with the inverted mask (wildcard). This is the same math routers perform on every packet — billions of times per second.