IP Addressing and Subnetting Questions
Working with IP address space: IPv4 and IPv6 addressing, subnet masks and CIDR notation (including why classful addressing was abandoned), VLSM calculation, route summarization from an addressing standpoint, private (RFC1918), ULA, link-local (including 169.254 self-assigned) and public ranges, and multicast address ranges. Covers designing hierarchical addressing schemes for sites, VLANs, security zones, DMZs and data centers, laying out prefixes so ACL and QoS policy stays compact, NAT and CGNAT for address conservation, static versus DHCP-assigned addressing, IPAM practice, renumbering after mergers or overlaps, and IPv4-to-IPv6 transition (dual-stack, tunneling, NAT64/DNS64). Boundary: routing protocol operation, cloud VPC topology, DNS and DHCP service operation, and firewall design are covered elsewhere.
A company must keep PCI, HR, Dev/Test and Production systems separated. You own the addressing plan, not the firewall rules. How do you lay out subnets and management addressing for these zones so that enforcement and monitoring stay simple and growth does not force a redesign?
Sample Answer
Direct answer
Make each zone exactly one contiguous, bit-aligned prefix, so "is this address in PCI?" is a single prefix match. Example: is 10.35.4.9 in PCI? Its second octet is 35, which lies in 32 to 47, so it falls inside 10.32.0.0/12; 10.52.4.9 does not. Then every firewall object, access list, flow-log filter and monitoring dashboard needs one entry per zone instead of one per subnet, and growth happens inside the zone's block rather than by adding new, scattered ranges. Management addresses get their own block, sliced per zone, so administrative traffic is also one recognisable prefix. The firewall owner enforces; the addressing plan makes their rules short and your monitoring unambiguous.
PCI means the Payment Card Industry Data Security Standard, the rules for systems that store, process or transmit payment card data. The systems in scope are called the cardholder data environment (CDE), and keeping the CDE one recognisable prefix is what makes its boundary easy to show and to monitor.
Zone blocks (inside 10.0.0.0/8)
Each zone gets a /12 (bit-aligned: the block starts on a boundary that is a multiple of its own size, so 10.32.0.0 is a valid /12 start because 32 is a multiple of 16). A /12 spans second octets in steps of 16, which is why PCI covers 32 to 47. It is 16 consecutive /16 networks (65,536 addresses each, so one /16 per site, cloud network or environment fits naturally).
| Zone | Block | Second octet | Management slice for that zone (a /20 inside 10.1.0.0/16) |
|---|---|---|---|
| Infrastructure | 10.0.0.0/12 | 0 to 15 | n/a |
| Production | 10.16.0.0/12 | 16 to 31 | 10.1.16.0/20 |
| PCI | 10.32.0.0/12 | 32 to 47 | 10.1.32.0/20 |
| HR | 10.48.0.0/12 | 48 to 63 | 10.1.48.0/20 |
| Dev/Test | 10.64.0.0/12 | 64 to 79 | 10.1.64.0/20 |
Reserved and unassigned: 10.80.0.0/12 up to 10.240.0.0/12 (11 further /12 blocks), which is where a new zone goes without disturbing anything.
The tag is readable from the address itself: second octet 16 to 31 is Production, 32 to 47 is PCI, 48 to 63 is HR, 64 to 79 is Dev/Test, and the management slices repeat the same numbers in the third octet (10.1.32.x is PCI management).
A short check confirms nothing overlaps and the management slices sit inside the infrastructure block:
import ipaddress as ip
zones = {"Production": "10.16.0.0/12", "PCI": "10.32.0.0/12", "HR": "10.48.0.0/12", "Dev/Test": "10.64.0.0/12"}
mgmt = {"Production": "10.1.16.0/20", "PCI": "10.1.32.0/20", "HR": "10.1.48.0/20", "Dev/Test": "10.1.64.0/20"}
infra = ip.ip_network("10.0.0.0/12")
allnets = [infra] + [ip.ip_network(v) for v in zones.values()]
for a in allnets:
for b in allnets:
if a < b: assert not a.overlaps(b), (a, b)
print("workload zone blocks do not overlap each other or 10.0.0.0/12")
for z, c in zones.items():
n = ip.ip_network(c)
print(f"{z}: {n} {n[0]} - {n[-1]} /16s: {n.num_addresses // 65536} second octets {n[0].packed[1]}-{n[-1].packed[1]}")
for z, c in mgmt.items():
n = ip.ip_network(c)
assert n.subnet_of(ip.ip_network("10.1.0.0/16")) and n.subnet_of(infra)
print(f"{z} mgmt: {n} {n[0]} - {n[-1]} usable {n.num_addresses-2}")
print("reserved for new zones: 10.80.0.0/12 through 10.240.0.0/12 =", len(range(80, 256, 16)), "x /12")
workload zone blocks do not overlap each other or 10.0.0.0/12
Production: 10.16.0.0/12 10.16.0.0 - 10.31.255.255 /16s: 16 second octets 16-31
PCI: 10.32.0.0/12 10.32.0.0 - 10.47.255.255 /16s: 16 second octets 32-47
HR: 10.48.0.0/12 10.48.0.0 - 10.63.255.255 /16s: 16 second octets 48-63
Dev/Test: 10.64.0.0/12 10.64.0.0 - 10.79.255.255 /16s: 16 second octets 64-79
Production mgmt: 10.1.16.0/20 10.1.16.0 - 10.1.31.255 usable 4094
PCI mgmt: 10.1.32.0/20 10.1.32.0 - 10.1.47.255 usable 4094
HR mgmt: 10.1.48.0/20 10.1.48.0 - 10.1.63.255 usable 4094
Dev/Test mgmt: 10.1.64.0/20 10.1.64.0 - 10.1.79.255 usable 4094
reserved for new zones: 10.80.0.0/12 through 10.240.0.0/12 = 11 x /12
Inside a zone
Allocate /16s from the bottom of the block upward, one per site, cloud network or environment, and keep the top eight /16s of each /12 as reserve. Inside a /16, give each tier its own /24 (254 usable addresses) and keep the same tier in the same position in every /16, for example web as the /24 with third octet 0, application with third octet 1 and data with third octet 2, so an address reveals its zone, site and tier. In PCI, put the CDE tiers in the first /16 (10.32.0.0/16) and systems that merely connect to it in the second (10.33.0.0/16), so the most sensitive boundary is one /16.
Management addressing
Note that the management slices (10.1.x.x) sit inside the infrastructure block 10.0.0.0/12, not inside the zone blocks; the slice only repeats the zone's number in its third octet so it is easy to read.
- Network device management and loopbacks: 10.0.0.0/16, in the infrastructure block, one address per device.
- Server out-of-band management (the separate management path to a server that works even when its operating system is down: baseboard controllers, the small built-in management chips on server motherboards, plus hypervisor management interfaces): 10.1.0.0/16 sliced per zone as in the table. Because 10.0.0.0/16 and 10.1.0.0/16 are adjacent, all management traffic (device management plus server out-of-band) collapses to the single prefix 10.0.0.0/15. Admin access rules, the monitoring collector and the logging pipeline then match on 10.0.0.0/15 for all management traffic, on 10.1.0.0/16 for server out-of-band only, and on one /20 for a single zone's server management.
- Jump hosts (hardened servers that administrators connect to first and then reach other machines from): one per zone, addressed inside that zone's block, so reaching a zone's management slice requires coming through a host that belongs to the zone. This keeps zone separation intact for administration instead of creating a flat management network.
Why enforcement and monitoring stay simple
- A firewall policy between zones is one rule per zone pair on the zone prefix, not a list of subnets that goes stale.
- Flow logs (records of which address talked to which, filtered here by zone prefix) and SIEM (security information and event management) tools classify traffic by source and destination prefix: the zone name comes from a five-line table (infrastructure plus the four zones).
- A new site or application adds a /16 or /24 inside an existing block, and nothing in firewall or monitoring configuration changes.
- Showing an assessor (the auditor who checks PCI compliance) the PCI boundary is one prefix; anything that has a route into 10.32.0.0/12 is in question.
An address plan does not segment by itself. It only makes the enforcement that the firewall owner builds easy to write, audit and monitor. What you ask of them: policy written on the zone prefixes, default deny between zones, and an exceptions list that names source and destination prefixes.
Trade-offs and what would change them
A /12 per zone is generous: 5 of the 16 /12 blocks in 10.0.0.0/8 are in use and HR will never fill its block. Private space is cheap, and the generosity is what avoids a redesign. If the organisation must share 10.0.0.0/8 with a partner or acquisition (overlapping ranges), shrink each zone to a /14 so the four zones together fit in one /12, keeping the same one-prefix-per-zone rule. If a cloud provider caps network sizes, keep one /16 per cloud network so the rule still holds. Never place a system in another zone's range "temporarily": the exception becomes the permanent hole that breaks the one-prefix property.
Design an IPv6 addressing plan for 200 branch sites, each needing up to 2,000 hosts. Also propose an IPv4 fallback strategy for legacy devices. Recommend per-site allocations, summarization to regional routers, and a plan to minimize NAT complexity while supporting legacy IPv4-only services.
Sample Answer
Direct answer
Give every branch one /48 (65,536 /64 subnets), grouped by region so that each region is one /40 and the whole organisation is one prefix at the top. Run dual-stack (IPv4 and IPv6 side by side) so IPv6 is end to end with no translation, keep a bounded IPv4 plan for legacy devices, and confine NAT to exactly two places: IPv4 internet egress at the regional hubs, and NAT64 for IPv6-only clients that must reach IPv4-only services. The addresses below use 2001:db8::/32, the documentation prefix, standing in for the organisation's real allocation.
IPv6 plan
Why a /48 per site. 200 sites need 200 site blocks. A /48 per site means the organisation needs at least a /40 overall if all sites sit in one block (a /40 contains 2^(48-40) = 256 /48s, enough for 200; a /41 would contain only 128). The plan below gives each of four regions its own /40, which is generous: four /40s need a /38 at minimum, and the /32 has room for 256 of them. The LAN rule is one /64 per VLAN (SLAAC, the self-configuration of hosts from router advertisements, needs a 64-bit host part, so a VLAN prefix shorter or longer than /64 is a design error). A site of 2,000 hosts is, say, five user VLANs of up to about 400 devices each (a sensible Layer 2 domain size in practice, not an IPv6 limit), plus voice, guest, printers, servers and management: ten /64s out of 65,536. RFC 6177 deliberately gives no single mandatory size and says sites should get at least a /64 and in most cases significantly more, so /48 here is a local policy chosen for simple arithmetic, not a standards requirement. If only a /40 is available in total, it still holds 256 /48 sites, so 200 sites fit flat, but with just 56 spare and no room for four regional /40s. Give each site a /56 instead (256 /64s, still ample for 2,000 hosts): /48 to /56 is 8 more bits, two hex digits, and the /40 then holds 2^(56-40) = 65,536 sites, with room to subdivide it into regions.
Hierarchy on hex (nibble) boundaries. A nibble is one hex digit, which is 4 bits, so prefixes that fall on multiples of 4 bits (/32, /36, /40, /44, /48, /52, /56, /60, /64) read directly off the address with no binary arithmetic.
| Level | Prefix | Example | Count |
|---|---|---|---|
| Organisation | /32 | 2001:db8::/32 | 1 |
| Region | /40 | 2001:db8:100::/40 (NA), 2001:db8:200::/40 (EMEA), 2001:db8:300::/40 (APAC), 2001:db8:400::/40 (LATAM) | 4 used, 256 possible |
| Site | /48 | 2001:db8:301::/48 (APAC site 1) | 256 per region |
| VLAN | /64 | 2001:db8:301:10::/64 users, :11:: users 2, :20:: voice, :30:: guest, :40:: servers, :1:: management | 65,536 per site |
The third group is 16 bits, four hex digits, written 0RSS with the leading zero dropped: the first byte (8 bits) is the region and the second byte is the site. So 2001:db8:301::/48 is really 2001:0db8:0301::/48: region byte 03 (APAC), site byte 01. The /40 boundary falls exactly between the two bytes (first 40 bits = 2001:0db8:03), which is why the region is a /40 and the site a /48; 2001:db8:305::/48 is the fifth site in the APAC region. The fourth group is the function, using the same numbers at every site. Each /40 holds 256 sites, so 200 sites spread over four regions fills about a fifth of the capacity and several new sites a year never exhausts it.
Summarisation. (Summarising means advertising one covering prefix instead of many.) The regional router advertises its /40 toward the backbone and the organisation advertises the /32 to its ISPs; branches advertise nothing outside their region. A new site takes the next free /48 in its region's /40, so no summary changes. Loopbacks come from a separate /48 (for example a reserved site number) and router links from /127s (RFC 6164).
IPv4 fallback for legacy devices
Legacy devices (old printers, building controllers, applications without IPv6) stay on IPv4 in the dual-stack period, so keep a simple IPv4 plan with the same shape. 200 sites x one /20 (4,094 usable, about twice a 2,000-host site) fits in 10.0.0.0/12: going from /12 to /20 adds 8 bits, so the /12 holds 2^8 = 256 /20s, and 200 is fewer than 256. Regions get a /14 each (from /14 to /20 is 6 bits, so 2^6 = 64 site slots per region, and four /14s use exactly the 256 /20s of the /12): NA 10.0.0.0/14, EMEA 10.4.0.0/14, APAC 10.8.0.0/14, LATAM 10.12.0.0/14. Fifty sites per region leaves 14 free slots; anything beyond that goes in a further /14 taken from outside the full /12 (for example 10.16.0.0/14), which needs one more summary route per region and is the only part of the IPv4 plan that does not scale for free, which is acceptable because the IPv4 footprint is meant to shrink.
Keeping NAT minimal
| Traffic | Mechanism | Where |
|---|---|---|
| Dual-stack host to IPv6 service | None: native routing, protected by stateful firewall policy | Everywhere |
| IPv4 host to the internet | NAT44 (IPv4-to-IPv4 translation; PAT is the form where many private addresses share one public address, told apart by port) | Regional hubs only, not at each branch |
| IPv6-only host to an IPv4-only service | NAT64 with DNS64 (DNS64 is a DNS server that, when a name has only an A record (an IPv4 address), creates an AAAA record (an IPv6 address) for it by putting the IPv4 address after a 96-bit translation prefix; 64:ff9b::/96 is the well-known prefix reserved for this in RFC 6052) | Regional hubs |
| IPv4-only device to an IPv6-only service | Avoided: put a dual-stack proxy or load balancer (a front-end that accepts both IPv4 and IPv6 connections and talks to the service itself) in front of the service | Service edge |
Do not use IPv6 NAT to hide the site structure. NPTv6 (RFC 6296) is a stateless one-to-one swap of one IPv6 prefix for another, so it keeps no per-connection table, but it still rewrites addresses: every host then has an inside and an outside address, applications that embed addresses and logs see the wrong one, and the mapping must be maintained and changed on renumbering. A stateful, port-translating IPv6 NAT would also recreate the translation state that IPv4 NAT needs. Neither is warranted because the internal plan is already stable. Security comes from the firewall, not from address hiding. Sequence: dual-stack the WAN and sites first, move user VLANs to IPv6-preferred, then convert VLANs to IPv6-only behind NAT64 as the legacy list shrinks; legacy IPv4-only VLANs remain until each device is replaced.
Pitfalls
- A /64 per site "to conserve": breaks the VLAN model.
- Mixing sizes at a site so region summaries stop covering it.
- Leaving DNS64 out: IPv6-only clients then cannot resolve IPv4-only names even though the NAT64 box works.
- Forgetting IPv4 firewall rules do not apply to IPv6: every site needs a matching IPv6 policy, or the new protocol is open by default.
You have four contiguous IPv4 networks: 10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24 and 10.0.3.0/24. What single prefix covers them, and how do you work it out bit by bit? Then explain when summarizing a set of subnets like this would not be possible or would be risky.
Sample Answer
Direct answer
10.0.0.0/22 covers all four networks exactly: it spans 10.0.0.0 to 10.0.3.255, which is the same 1,024 addresses as four /24s (4 x 256). Summarization is risky or impossible when the networks are not contiguous and aligned, or when the summary would claim addresses you do not own or route elsewhere.
Bit-by-bit derivation
Write the differing octet (the third) in binary for each network. The first two octets (10.0) are identical, which is 16 common bits.
| Network | Third octet |
|---|---|
| 10.0.0.0/24 | 00000000 |
| 10.0.1.0/24 | 00000001 |
| 10.0.2.0/24 | 00000010 |
| 10.0.3.0/24 | 00000011 |
The first six bits of the third octet (000000) are the same in all four; only the last two vary. Common bits: 16 + 6 = 22. Mask for /22 is 255.255.252.0 (252 = 11111100). Check: the block size is 256 - 252 = 4 in the third octet. The last two bits of that octet are free in a /22, so the first network must have those two bits at 00, which means its third octet is a multiple of 4. 10.0.0.0 is, so four /24s fit exactly.
When summarizing fails or is risky
- Not aligned. A set must start on a multiple of its block size and be a power-of-two count. 10.0.1.0/24 to 10.0.4.0/24 are also four consecutive networks, but their third octets in binary are 00000001, 00000010, 00000011 and 00000100, which already disagree at the sixth bit, so they share only 16 + 5 = 21 bits, and 10.0.1.0 is not a multiple of 4. They collapse to 10.0.1.0/24 + 10.0.2.0/23 + 10.0.4.0/24. One covering prefix would have to be 10.0.0.0/21 (10.0.0.0 to 10.0.7.255), eight /24s, four of which are not yours.
- Gaps. Three networks 10.0.0.0/24 to 10.0.2.0/24 summarize only as 10.0.0.0/23 plus 10.0.2.0/24. A single /22 would cover 10.0.3.0/24, which is not part of the set.
- Too coarse a summary. It advertises addresses you do not own or that live elsewhere. If 10.0.3.0/24 is at another site and that site also advertises its /24, longest-prefix match saves you. Longest-prefix match means a router forwards each packet using the matching route with the longest prefix, the most specific one: a packet for 10.0.3.5 matches both 10.0.0.0/22 and 10.0.3.0/24, and the /24 wins. If the other site does not advertise it, traffic for that /24 is pulled to you and dropped or looped (a blackhole, where packets silently disappear).
- Hidden failures. A summary stays up while one component subnet is down, so the rest of the network keeps sending traffic toward a router that cannot deliver it. For example, if 10.0.2.0/24 loses its link, the /22 is still advertised, so distant routers keep sending 10.0.2.x packets to you, where they are dropped, instead of failing fast or switching to a backup path. The specific /24 withdrawal is hidden inside the summary.
- Non-contiguous design. Subnets of the same block split across two sites cannot be summarized at either site.
Why aggregation is worth doing
One /22 route replaces four /24 routes, so routing tables and updates shrink and flaps (a route repeatedly going down and up) of one /24 stop propagating beyond the summarizing router. At large scale that cuts memory and CPU use and makes convergence (all routers agreeing on the new topology after a change) faster. The price is precision, which is why summaries should be planned in the addressing scheme: give each site or region an aligned block and summarize at its edge.
Practice
The summarizing router needs a discard (null) route for the summary so traffic to unused parts of the block is dropped there rather than looped back out a default route. Some protocols install it for you, as described at the end of this section; when you originate the summary yourself, for example with a static route that is then redistributed, you add it by hand. Without it, a packet for an unused address such as 10.0.3.77 reaches the router because of the advertised summary, finds no specific route, follows the default route back toward the upstream router that sent it, and bounces until its TTL (hop limit) expires. With the discard route, the /22 matches (it is more specific than the default route, which matches everything) and the packet is dropped at once. On Cisco IOS this is ip route 10.0.0.0 255.255.252.0 Null0, where Null0 is a virtual interface that discards everything sent to it. The advertisement itself is configured separately: in OSPF, an area range command on the router at the area edge; in BGP, an aggregate-address command. Both of those install the discard route automatically: Cisco documents that an OSPF ABR (area border router) or ASBR installs a discard route to Null0 for a summary, with a discard-route setting that can turn this off, and that BGP aggregate-address inserts a route toward Null0 into the routing table to prevent forwarding loops. So the manual Null0 line is for summaries you create by static configuration or by other means. Do not disable the automatic discard route unless you have another route that makes unused space in the summary drop safely.
Your team tracks IP space in spreadsheets and keeps running into conflicts. You are asked to introduce an IPAM system. What should it record about each prefix and address, and why does each piece matter for day-to-day operations and audits?
Sample Answer
Direct answer
An IPAM (IP address management) system is the single database of record for who owns which address space. Record, for every prefix: the CIDR (classless inter-domain routing, the /24 style of notation) block, its parent, its routing context (VRF, a separate routing table; see below), status, role, location and VLAN, owner, and links to the DHCP scope and DNS zone. For every address: the address, status, DNS name, the device and interface it belongs to, owner, and the date and ticket that assigned it. Add a change history on everything. Five fields prevent collisions on their own: for a prefix, the CIDR block, its parent, its VRF, its status and an owner; the remaining fields answer troubleshooting and audit questions. Each field exists to answer a question someone asks daily ("who owns this?", "is this free?") or an auditor asks yearly ("who approved this and when?").
Per prefix
| Field | Why it matters |
|---|---|
| Prefix (CIDR) and parent/child hierarchy | Shows what each block was carved from and what remains free, so a new allocation does not collide with a neighbour. |
| VRF (virtual routing and forwarding, an independent routing table) | The same 10.1.0.0/24 can legitimately exist in two VRFs (for example corporate and guest); an overlap check that ignores the VRF raises false alarms or misses real ones. |
| Status (container, active, reserved, deprecated) | A container may hold child prefixes, an active prefix is in use, a reserved one is spoken for but not deployed, and a deprecated one is awaiting removal. This is what lets the system tell a planned block from a live one. |
| Role / purpose (users, voice, servers, management, point-to-point) | Lets engineers and ACLs (access control lists) reason by function and keeps loopbacks out of user space. |
| Site / region, VLAN ID and name | Ties the layer-3 block to the layer-2 domain and the place, which speeds troubleshooting and decommissioning. |
| Gateway address and mask | The one fact needed to build or verify an interface or DHCP scope. |
| Owner (team and contact), tenant (the customer or business unit the space is allocated to) | Someone is accountable for the block; also the basis for chargeback (billing each team for the space or services it uses) and for who approves changes. |
| DHCP scope and reverse DNS zone links | Prevents a scope and a static range overlapping and makes the DNS reverse zone traceable. |
| Security zone (a group of networks treated alike by firewall policy, such as DMZ or internal) / firewall policy reference, NAT mapping | During an incident, one lookup says which policy and translation apply. |
| Cloud account / VPC identifier | Cloud address space is where most overlaps are discovered late. |
| Created date, ticket, approver, review date | The audit trail: who allocated it, under what authority, and when it was last confirmed. |
| Utilisation (computed, not typed) | Capacity planning: a subnet at 85% needs a plan before it hits 100%. |
Per address
| Field | Why it matters |
|---|---|
| Address and status (active, reserved, DHCP pool, free, deprecated) | Prevents handing the same address out twice. |
| DNS name (forward and reverse) | The address is findable by name and the PTR record (the reverse record that maps the address back to a name) matches. |
| Device and interface, MAC address | Joins the IP to the thing that holds it, for troubleshooting and replacement. |
| Owner and purpose | Who to call about 10.20.5.77 at 2 a.m. |
| Assigned date, ticket, last-seen date from discovery | Shows how long an address has been in use and whether it is stale. |
| Static vs reservation vs DHCP | Determines whether a change is a device edit or a server record edit. |
System behaviours that matter as much as fields
- Overlap prevention on write, VRF-aware: refuse a new active prefix that overlaps another active prefix in the same VRF, unless the parent is a container.
- Change history (who, what, when, before and after values) and an API, so changes are made from tickets and automation rather than by hand.
- Role-based access: all can read; only the allocating team can write.
- Discovery and reconciliation: compare recorded addresses with DHCP leases, ARP tables and cloud inventories; flag drift, and stale or unrecorded addresses.
- Integration with DNS and DHCP so records are created from IPAM, not retyped.
Migrating from spreadsheets: find the conflicts first
Run an overlap check over the existing sheet before importing. This script (all inputs inline) treats a prefix as legal inside a container parent and flags overlaps only within the same VRF:
import csv, io, ipaddress, itertools
from collections import defaultdict
SHEET = """prefix,vrf,site,status
10.20.0.0/16,corp,HQ,container
10.20.5.0/24,corp,HQ,active
10.20.5.128/25,corp,HQ,active
10.30.0.0/24,corp,Branch-A,active
10.30.0.0/24,guest,Branch-A,active
10.30.0.0/25,corp,Branch-B,active
"""
by_vrf = defaultdict(list)
for row in csv.DictReader(io.StringIO(SHEET)):
by_vrf[row["vrf"]].append((ipaddress.ip_network(row["prefix"]), row["site"], row["status"]))
conflicts = 0
for vrf, rows in sorted(by_vrf.items()):
for (a, sa, ta), (b, sb, tb) in itertools.combinations(rows, 2):
if not a.overlaps(b):
continue
parent_status = ta if a.prefixlen <= b.prefixlen else tb
if a != b and parent_status == "container":
continue
conflicts += 1
print(f"CONFLICT vrf={vrf}: {a} ({sa}) overlaps {b} ({sb})")
print(f"{conflicts} conflicts")
It prints:
CONFLICT vrf=corp: 10.20.5.0/24 (HQ) overlaps 10.20.5.128/25 (HQ)
CONFLICT vrf=corp: 10.30.0.0/24 (Branch-A) overlaps 10.30.0.0/25 (Branch-B)
2 conflicts
How the test works: a.overlaps(b) is true when two prefixes share any addresses, and two prefixes that overlap are always nested, so the one with the shorter prefix length (a.prefixlen <= b.prefixlen) is the parent and parent_status is that parent's status. If the parent is a container, a child inside it is expected and the pair is skipped. The extra test a != b means two identical prefixes are always a conflict, even if marked container, because a block cannot be its own child. Anything else (an active block containing another active block) is counted. Rows in different VRFs are never compared, because they are grouped by VRF first.
The /16 container holding both /24 and /25 is fine, the 10.30.0.0/24 present in both corp and guest is fine (different VRFs), and the two real conflicts are the HQ /25 inside an active /24 and the Branch-B /25 inside Branch-A's active /24.
Audit and daily-operations uses
- Operations: allocate the next free block safely, find the owner of an address during an incident, size a subnet from real utilisation, and decommission a site and know which blocks, DNS records and reservations go with it.
- Audit: show that every allocation has an approver and ticket, that history is complete and not editable, and that recorded space matches what discovery sees (reconciliation evidence). The review date field supports periodic attestation (each block owner formally confirming that their records are still correct).
Pitfalls
- Importing the spreadsheet as-is: duplicate and overlapping rows become permanent.
- Free-text fields for status and role: reports then cannot be trusted; use controlled lists.
- Letting engineers edit IPAM and devices independently: without reconciliation, the database is a stale copy within months.
You are designing the IPv4 addressing plan for a global enterprise with 50 sites, growing by several sites a year, all inside RFC1918 space. Walk through how you would structure the address space top-down, what you would reserve, how it stays summarizable by region, and how you would add new sites without renumbering.
Sample Answer
Direct answer
Take all of 10.0.0.0/8 as the corporate plan and divide it top-down on bit boundaries (each split fixes a few more leading bits, so every block is a power-of-two size that starts on its own boundary): first into purpose blocks (one block for each region's sites, one for data centres and cloud, one for infrastructure), then by site size class inside each region, then by function inside each site. Each level is one prefix, so a region advertises a single route to the rest of the network, and a new site is only a new block carved from space that was already reserved for its region. Nothing existing changes, so nothing is renumbered.
Level 1: the whole /8 by purpose
Going from /8 to /11 fixes 3 more bits, which cuts the /8 into 8 equal blocks. Each /11 covers 2^(32-11) = 2,097,152 addresses, which is 32 values of the second octet (256 / 8), so the first /11 is 10.0 to 10.31, the next 10.32 to 10.63, and so on.
| Block | Range | Purpose |
|---|---|---|
| 10.0.0.0/11 | 10.0.0.0 to 10.31.255.255 | Americas |
| 10.32.0.0/11 | 10.32.0.0 to 10.63.255.255 | EMEA (Europe, Middle East, Africa) |
| 10.64.0.0/11 | 10.64.0.0 to 10.95.255.255 | APAC (Asia-Pacific) |
| 10.96.0.0/11 | 10.96.0.0 to 10.127.255.255 | Held back for a fourth region or an acquisition |
| 10.128.0.0/10 | 10.128.0.0 to 10.191.255.255 | Data centres and cloud networks (VPCs and VNets) |
| 10.192.0.0/10 | 10.192.0.0 to 10.255.255.255 | Infrastructure (first /16) and unallocated reserve |
Giving the data centre and cloud space its own block keeps it separable from branch space. Cloud networks (a VPC in AWS or a VNet in Azure is a customer's private network inside the cloud provider) must not overlap anything reachable over a VPN (an encrypted tunnel across the internet) or a private link (a dedicated provider connection). Corporate use stays out of 172.16.0.0/12 and 192.168.0.0/16 on purpose: home routers and remote users' networks very often use 192.168.x.x, and an acquired company or partner may already use any RFC 1918 range, so keeping two of the three ranges free leaves somewhere to renumber into or translate when an overlap shows up.
Level 2: site size classes inside each region
Inside one region (APAC, 10.64.0.0/11, as the example), split the first three /16s by site size class instead of mixing sizes:
| Pool | Block | Site block | Slots | Usable per site |
|---|---|---|---|---|
| Large sites (campus, HQ) | 10.64.0.0/16 | /20 | 16 | 4,094 |
| Medium sites | 10.65.0.0/16 | /22 | 64 | 1,022 |
| Small sites (branches) | 10.66.0.0/16 | /24 | 256 | 254 |
| Region reserve | 10.67.0.0 to 10.95.255.255 | unallocated | 29 x /16 |
Pools by size class keep every block naturally aligned and make the free space easy to see in IPAM (IP address management, the database of who owns which prefix).
Reading an address back through the plan: take 10.65.12.5. The second octet 65 lies in 64 to 95, so it is inside 10.64.0.0/11, APAC. The block 10.65.0.0/16 is the medium-site pool. Third octet 12 falls in the /22 starting at 10.65.12.0 (slot 3 counting from 0, so the fourth medium site), and the host part .5 sits in the first /27 of the site, which the fixed-offset template below uses for management. The plan is deliberately generous: a rollout of 4 large, 16 medium and 30 small sites uses 4 x 4,096 + 16 x 1,024 + 30 x 256 = 40,448 addresses, about 0.24% of the /8.
Level 3: what to reserve, and what each site gets
- Infrastructure block: 10.192.0.0/16, for example a /24 of router loopbacks (one /32 per device, 256 devices) and a /24 of point-to-point links (/31 each, 128 links). Never allocate these from user ranges, so they stay stable when sites change.
- Fixed offsets inside every site block (a fixed offset means a function always starts the same distance into the site's block): the same function at the same offset in every site (for example the first /27 of any site block is management, then users, voice, printers, guest). Staff can read an address and know what it is, and firewall rules can be written as patterns.
- Rules reserved by policy: the unallocated 10.96.0.0/11 and 10.192.0.0/10 remainder are marked reserved in IPAM; nobody takes a "temporary" block from them without a ticket.
- Gateway convention: .1 of every subnet is the gateway.
Summarisation by region
Each regional hub advertises its /11 (10.0.0.0/11, 10.32.0.0/11, 10.64.0.0/11) into the backbone, so a router in EMEA holds two routes for the other two regions (the Americas /11 and the APAC /11) plus the detail for its own region, instead of one route per site across the company (50 and growing). Two conditions make it hold: every site in a region must come from that region's /11, and the summarising router should carry a discard route for the /11 so traffic to an unallocated address inside the region is dropped rather than looped back toward the default route. A discard route is a route for the whole /11 that points at nowhere: with it, an address inside the /11 that has no more specific route is dropped here, instead of matching the default route (the catch-all route that sends everything unknown toward the backbone), going back out, and being sent in again by the other regions' summaries. The summary also hides site flaps (a link going down and up repeatedly): a site going down changes no route outside its region.
Adding a site without renumbering
New medium site in APAC, with three medium sites already allocated (10.65.0.0/22, 10.65.4.0/22, 10.65.8.0/22): record the next free slot, 10.65.12.0/22, in IPAM, build the site from the fixed-offset template, and advertise it inside the region. The /11 summary is untouched, and no other site is touched. A site that outgrows its block gets a second block from the same pool in the same region, which is still inside the /11 summary (the site then appears as two prefixes locally, a small cost); it does not trigger renumbering.
Pitfalls
- Allocating by "next free /24" with no regional structure: after a few years the summaries are gone and every router carries 50 or more site routes.
- A size class that is too small. Pick the site block for the biggest realistic need of the class, because a changed mask means renumbering; this plan allows a second block as the release valve.
- Overlap with cloud and acquired companies: reserve cloud space now and check for overlap before any VPN or peering is set up.
- Using the whole /8 as a flat pool, with no rule for who allocates, and nothing recorded: IPAM is what stops two engineers taking the same block.
Unlock Full Question Bank
Get access to all 30 IP Addressing and Subnetting interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.