Working out whether 192.168.1.130 is on the same network as 192.168.1.73/26 should take a few seconds. Guess wrong and you end up with a VPN range that swallows your LAN, or a firewall rule that matches far more than you meant. This guide shows how CIDR notation maps to bits, how to find network and broadcast addresses by hand, how to carve a /24 into subnets for a home lab, and how to check what your Linux hosts are configured with.
Bits, prefixes, and masks
An IPv4 address is a 32-bit number. Dotted-quad notation splits it into four 8-bit octets and writes each one in decimal, so every octet runs from 0 to 255.
192 .168 .1 .73
11000000 10101000 00000001 01001001
The prefix length after the slash says how many of those 32 bits, counted from the left, identify the network. The remaining bits identify a host inside that network. In 192.168.1.73/26, the first 26 bits are the network part and the last 6 bits are the host part.
A subnet mask is the same information written as an address: network bits set to 1, host bits set to 0. A /26 is 26 ones followed by 6 zeros, which in the last octet is 11000000, or 192.
| Prefix | Mask | Addresses | Usable hosts |
|---|---|---|---|
| /24 | 255.255.255.0 | 256 | 254 |
| /25 | 255.255.255.128 | 128 | 126 |
| /26 | 255.255.255.192 | 64 | 62 |
| /27 | 255.255.255.224 | 32 | 30 |
| /28 | 255.255.255.240 | 16 | 14 |
| /30 | 255.255.255.252 | 4 | 2 |
| /31 | 255.255.255.254 | 2 | 2 (point-to-point only) |
| /32 | 255.255.255.255 | 1 | 1 (single host) |
The octet values worth memorizing are 128, 192, 224, 240, 248, 252, 254, 255. Each step adds one network bit.
Wildcard masks
A wildcard mask is the bitwise inverse of the subnet mask: a 1 bit can be anything, a 0 bit must match. Subtract each mask octet from 255, so the wildcard for a /26 is 0.0.0.63. Cisco IOS uses wildcard masks in access lists and OSPF network statements, and typing a subnet mask there instead matches the wrong range.
access-list 10 permit 192.168.1.64 0.0.0.63
router ospf 1
network 10.10.20.0 0.0.0.255 area 0
The first line matches 192.168.1.64 through 192.168.1.127. The OSPF line enables OSPF on interfaces inside 10.10.20.0/24.
Finding the network and broadcast by hand
The one number you need is the block size: 256 minus the interesting mask octet (the one that is not 255 or 0). For a /26 that is 256 - 192 = 64, so subnets start at multiples of 64 in that octet.
Take 192.168.1.73/26 as the worked example:
- The block size is 64, so the boundaries in the last octet are 0, 64, 128, 192.
- 73 falls between 64 and 128, so the network address is
192.168.1.64. - The broadcast address is one below the next boundary:
192.168.1.127. - Usable hosts are everything in between:
192.168.1.65to192.168.1.126, which is 62 addresses.
So 192.168.1.130 sits in a different subnet (192.168.1.128/26), and traffic to it goes through a router.
The general formula for usable hosts is 2^(32 - prefix) - 2. You subtract two because the all-zeros host address names the network and the all-ones host address is the broadcast. A /27 gives 2^5 - 2 = 30, a /30 gives 2^2 - 2 = 2.
Two prefixes break that rule:
- A /31 has two addresses and, under RFC 3021, both are usable on point-to-point links such as a router-to-router connection. With only two ends, nothing is reserved.
- A /32 is a single address. You see it on loopback addresses, host routes, and WireGuard peer entries such as
AllowedIPs = 10.10.99.2/32.
For prefixes /17 to /23 the same method applies to the third octet, and the fourth octet runs from 0 on the network address to 255 on the broadcast.
Private ranges you will run into
RFC 1918 reserves three blocks for private networks. They are not routed on the public internet, so you can use them freely inside your own network:
| Block | Range |
|---|---|
| 10.0.0.0/8 | 10.0.0.0 to 10.255.255.255 |
| 172.16.0.0/12 | 172.16.0.0 to 172.31.255.255 |
| 192.168.0.0/16 | 192.168.0.0 to 192.168.255.255 |
Note that 172.16.0.0/12 stops at 172.31.255.255. An address like 172.32.0.1 is public.
A fourth range is 100.64.0.0/10 (100.64.0.0 to 100.127.255.255), reserved by RFC 6598 for carrier-grade NAT between an ISP and its customers. Tailscale also assigns device addresses from it. If your router's WAN address is in this range, you are behind CGNAT and inbound port forwarding from the internet will not work.
Splitting a /24 for a home lab
Splitting a network means borrowing host bits for the network part. Going from /24 to /26 borrows two bits, which gives 2^2 = 4 subnets of 64 addresses each:
192.168.1.0/26 hosts .1 to .62 broadcast .63
192.168.1.64/26 hosts .65 to .126 broadcast .127
192.168.1.128/26 hosts .129 to .190 broadcast .191
192.168.1.192/26 hosts .193 to .254 broadcast .255
Equal sizes rarely match real needs. Variable Length Subnet Masking (VLSM) lets each subnet have its own prefix. The method is to list what each segment needs, add headroom, round up to a block size, and allocate the largest blocks first so every block starts on its own boundary.
Here is a plan for a home lab that has one /24 to work with, 192.168.10.0/24:
| Segment | Expected devices | Subnet | Usable range | Broadcast |
|---|---|---|---|---|
| IoT | up to 100 | 192.168.10.0/25 | .1 to .126 | .127 |
| Servers | up to 50 | 192.168.10.128/26 | .129 to .190 | .191 |
| Guests | up to 25 | 192.168.10.192/27 | .193 to .222 | .223 |
| Management | up to 10 | 192.168.10.224/28 | .225 to .238 | .239 |
| Spare | none yet | 192.168.10.240/28 | .241 to .254 | .255 |
The blocks add up to exactly 256 addresses (128 + 64 + 32 + 16 + 16) and none overlap. Placing small blocks first scatters them across the boundaries larger blocks need, which wastes space. The spare block leaves room for a new segment without renumbering.
If you have plenty of private space, giving each VLAN its own /24 in 10.0.0.0/8 is simpler to read and leaves room to grow. The home lab networking article uses that layout. Carving a single /24 is what you do when space is limited, such as a small routed block from a provider or a site-to-site VPN where every range has to be unique.
Summarizing routes into a supernet
Summarizing goes the other way: adjacent networks are advertised as one shorter prefix, which means fewer routes and shorter firewall rules.
Four /24s from 192.168.0.0 to 192.168.3.0 share their first 22 bits:
192.168.0.0 third octet 000000 00
192.168.1.0 third octet 000000 01
192.168.2.0 third octet 000000 10
192.168.3.0 third octet 000000 11
The first six bits of the third octet are identical, so the summary is 192.168.0.0/22 (mask 255.255.252.0), covering 192.168.0.0 to 192.168.3.255.
Summaries only stay exact when the networks line up. If you own only 192.168.1.0/24 and 192.168.2.0/24, the smallest single prefix that covers both is still 192.168.0.0/22, which also includes 192.168.0.0/24 and 192.168.3.0/24. Advertising that summary pulls in traffic for networks you do not have. In that case, keep two routes.
Checking your configuration on Linux
The ip command shows prefix lengths directly and behaves the same on Ubuntu 24.04 and Debian 12.
ip -4 addr
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.1.73/26 brd 192.168.1.127 scope global dynamic enp1s0
The brd value is the broadcast address the kernel calculated. If it does not match your plan, the prefix is wrong.
ip route
default via 192.168.1.65 dev enp1s0 proto dhcp src 192.168.1.73 metric 100
192.168.1.64/26 dev enp1s0 proto kernel scope link src 192.168.1.73 metric 100
The second line is the connected route for the local subnet. Anything outside it goes to the default gateway. To see the route the kernel picks for one destination:
ip route get 192.168.1.130
192.168.1.130 via 192.168.1.65 dev enp1s0 src 192.168.1.73 uid 1000
cache
The via confirms that .130 is off-subnet for this host. Python's standard library can double-check your arithmetic:
python3 -c 'import ipaddress; n = ipaddress.ip_network("192.168.1.73/26", strict=False); print(n, n.netmask, n.broadcast_address, n.num_addresses - 2)'
192.168.1.64/26 255.255.255.192 192.168.1.127 62
For quick checks in the browser, the subnet calculator gives the network, broadcast, host range, and wildcard mask for any prefix.
IPv6 subnet sizes
IPv6 uses the same prefix notation, but the practical choices are narrower. A LAN segment should be a /64, because stateless address autoconfiguration (SLAAC) builds addresses from a 64-bit interface identifier. A longer prefix such as a /80 breaks SLAAC on that segment.
ISPs commonly delegate a /48 or a /56 to a customer, usually through DHCPv6 prefix delegation. A /56 contains 256 /64 subnets and a /48 contains 65,536, so you plan IPv6 by counting segments rather than hosts.
IPv6 has no broadcast address. Functions that used broadcast in IPv4, such as address resolution, use multicast and Neighbor Discovery instead, so you do not subtract two addresses per subnet.
Common mistakes
Overlapping subnets cause the classic "it works until I connect the VPN". If your home network and a VPN both use 192.168.1.0/24, the machine cannot route to both. Docker adds another trap: its default bridge uses 172.17.0.0/16, and user-defined networks take further private ranges. A LAN or VPN in those ranges becomes unreachable from the Docker host because the kernel sends that traffic to a bridge. Check it:
ip route get 172.17.5.10
If the output shows dev docker0 for an address that should be on your LAN, move Docker's ranges in /etc/docker/daemon.json:
{
"bip": "10.200.0.1/24",
"default-address-pools": [
{ "base": "10.201.0.0/16", "size": 24 }
]
}
sudo systemctl restart docker
Restarting Docker stops running containers (unless live-restore is enabled), and existing user-defined networks keep their old subnets until you recreate them (for Compose projects, docker compose down then docker compose up -d). Do it in a maintenance window.
Off-by-one errors on the broadcast address come from adding the block size instead of block size minus one. The broadcast for 192.168.1.64/26 is .127, not .128. Assigning .128 to a host puts it in the next subnet.
Using .0 or .255 of a /24 as a host address fails because those are the network and broadcast addresses. In a larger subnet such as a /23, an address ending in .255 or .0 in the middle of the range can be a valid host, so check the prefix before assuming.
A mask mismatch on one segment causes traffic that works in one direction only. A host configured as /24 sends straight to an address that a /26 host treats as remote, so the replies head for a gateway instead. Every host and the router interface on a segment need the same prefix.
Before you commit a plan
- Write down network, usable range, broadcast, and gateway for each segment.
- Allocate the largest blocks first and keep a spare.
- Check every range against your VPN, Docker, and any remote networks you connect to.
- Verify each block in the subnet calculator and on the host with
ip -4 addr. - Build VLANs from the plan, as in Home Lab Networking: DNS, VPN, VLANs, and Reverse Proxy Flow.
Top comments (0)