Loading learning content...
When you ask for directions to a coffee shop, the simplest response might be: "It's four blocks away." Not "0.8 miles through heavily trafficked streets" or "a 12-minute walk with a 3-minute wait at the traffic light"—just four blocks. This intuitive simplicity is exactly what RIP's hop count metric provides for routing.
In RIP, every path's cost is measured in hops—the number of routers a packet must traverse to reach its destination. A directly connected network is 1 hop away. A network two routers away is 2 hops. This couldn't be simpler.
But simplicity has trade-offs. A 10 Gbps fiber path and a 56 Kbps dialup connection both count as "1 hop" in RIP's eyes. The ancient modem and the cutting-edge backbone are considered equivalent. This radical simplification is simultaneously RIP's greatest strength and its most significant limitation.
By the end of this page, you will understand why RIP uses hop count as its metric, the mathematical properties that make 16 the "infinity" value, how the 15-hop limit constrains network design, and how hop count compares to more sophisticated metrics used by OSPF and EIGRP.
The choice of hop count as RIP's metric wasn't arbitrary—it emerged from the networking context of the 1980s and the specific design goals of the protocol.
Historical Context
When RIP was developed:
Design Goals That Led to Hop Count
The Metric Formula
RIP's metric calculation is trivially simple:
Metric to destination = Metric from neighbor + 1
That's it. No bandwidth consideration, no delay measurement, no reliability assessment. Each router-to-router transition adds exactly one to the path cost.
Directly Connected Networks
For directly connected networks, RIP assigns metric 1 (not 0) because a packet must still enter the router to be processed before delivery:
Router R1 connected to Network 10.0.0.0/8:
10.0.0.0/8 → Metric 1 (directly connected)
Router R2 receives update from R1:
10.0.0.0/8 → Metric 1 + 1 = 2 (via R1)
Router R3 receives update from R2:
10.0.0.0/8 → Metric 2 + 1 = 3 (via R2)
In RIP, metric 0 is never used for normal routes. A metric of 0 would indicate 'no cost to reach,' which only makes sense for the router itself. Some implementations use metric 0 in special contexts (like route request messages), but standard route advertisements always start at metric 1.
A fundamental challenge in distance vector routing is representing "unreachable" destinations. The Bellman-Ford algorithm needs an infinity value to handle missing paths, but computers can't truly represent infinity. RIP's solution: define 16 as infinity.
Why 16?
The choice of 16 balances several considerations:
Mathematical Properties:
1234567891011121314151617181920212223242526272829303132333435363738394041424344
# Why is 16 the optimal choice for RIP's infinity? # Consideration 1: Packet size efficiency# =========================================# Metric field is 4 bytes (32 bits), but smaller values are more efficient# 16 can be represented in 5 bits, leaving headroom for future use# Values 0-15 = 4 bits (valid metrics), 16+ = infinity # Consideration 2: Count-to-infinity bounds# ==========================================# Counting from 1 to infinity takes (infinity - starting_metric) iterations# Each iteration = 30 seconds (update interval)# # If infinity = 16 and starting metric = 1:# Worst case = 15 iterations × 30s = 450 seconds = 7.5 minutes## If infinity = 128:# Worst case = 127 iterations × 30s = 3,810 seconds = 63.5 minutes! def calculate_worst_case_convergence(infinity, update_interval=30): """Calculate worst-case counting-to-infinity time.""" max_iterations = infinity - 1 # Starting from metric 1 total_seconds = max_iterations * update_interval return total_seconds print(f"Infinity=16: {calculate_worst_case_convergence(16)} seconds")print(f"Infinity=32: {calculate_worst_case_convergence(32)} seconds")print(f"Infinity=128: {calculate_worst_case_convergence(128)} seconds") # Output:# Infinity=16: 450 seconds (7.5 minutes) - Acceptable# Infinity=32: 930 seconds (15.5 minutes) - Excessive# Infinity=128: 3810 seconds (63.5 minutes) - Unacceptable # Consideration 3: Network diameter trade-off# ============================================# Maximum valid metric = infinity - 1 = 15 hops# This limits network diameter but bounds convergence time # Consideration 4: Historical precedent# =====================================# ARPANET used similar values# BSD routed implementation chose 16# Became de facto standard before formal specificationThe Trade-Off Matrix
Choosing an infinity value involves balancing competing concerns:
| If Infinity Too Low | If Infinity Too High |
|---|---|
| Network diameter is limited | Count-to-infinity takes forever |
| Valid paths marked unreachable | Routing loops persist longer |
| Network must be subdivided | Memory usage for tracking increases |
| Simple network design required | Convergence time unbounded |
Metric 16: The Line Between Reachable and Unreachable
In RIP, metric 16 is special:
When a router processes an update:
if received_metric + 1 >= 16:
metric = 16 # Mark as unreachable
do not install in routing table for forwarding
else:
metric = received_metric + 1
install/update routing table
Advertising Unreachable Routes
When advertising routes, metric 16 explicitly means "I cannot reach this destination":
# Poison reverse example
Router R1 to R2: "Network 10.0.0.0/8, metric 16"
R2 interprets: "R1 says this is unreachable through it"
R2 action: Do not use R1 as next-hop for 10.0.0.0/8
Because 16 is infinity and each hop adds 1, the maximum valid metric is 15. Any network where the longest path exceeds 15 hops simply cannot use RIP. This isn't a configuration option—it's a protocol limitation baked into every RIP implementation.
The 15-hop limit has profound implications for network design. Understanding these constraints is essential for proper RIP deployment.
What is Network Diameter?
Network diameter is the longest shortest path between any two nodes in the network. It represents the maximum number of hops between the two most distant points.
Example: Linear topology
R1 -- R2 -- R3 -- R4 -- R5
Diameter = 4 hops (R1 to R5 or vice versa)
| Topology Type | Number of Routers | Typical Diameter | RIP Viable? |
|---|---|---|---|
| Star (hub and spoke) | Any | 2 | ✓ Yes |
| Full mesh | Any | 1 | ✓ Yes |
| Ring | 10 | 5 | ✓ Yes |
| Ring | 30 | 15 | ✓ Barely |
| Ring | 32 | 16 | ✗ No |
| Linear chain | 8 | 7 | ✓ Yes |
| Linear chain | 16 | 15 | ✓ Barely |
| Linear chain | 20 | 19 | ✗ No |
| Hierarchical tree | 100 | 6 | ✓ Yes (if well-designed) |
| Arbitrary mesh | 50 | 8-12 | ✓ Usually |
Practical Impact on Network Design
1. Branch Office Connectivity
Consider a company with headquarters, regional offices, and branch offices:
HQ (core routers) → Regional (3 hops) → Branch (2 more hops)
Max path: Branch → Regional → HQ → Regional → Branch
Total: 2 + 3 + 3 + 2 = 10 hops (safe for RIP)
But if branches must communicate via dual-regional:
Branch → Regional1 → HQ → Regional2 → Branch
With more layers, 15 hops is quickly exceeded
2. Data Center Architectures
Modern data center designs (leaf-spine, fat-tree) typically have:
But with east-west traffic patterns and multiple DC interconnects, hop counts can spiral.
3. Campus Networks
Large university or corporate campuses:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
# Tool to calculate network diameter and RIP viability from collections import deque def calculate_diameter(adjacency_list): """ Calculate network diameter using BFS from each node. Args: adjacency_list: {node: [list of neighbors]} Returns: diameter: Maximum shortest path length endpoints: Tuple of nodes at maximum distance """ max_distance = 0 endpoints = None for start in adjacency_list: # BFS from each node distances = {start: 0} queue = deque([start]) while queue: current = queue.popleft() for neighbor in adjacency_list[current]: if neighbor not in distances: distances[neighbor] = distances[current] + 1 queue.append(neighbor) if distances[neighbor] > max_distance: max_distance = distances[neighbor] endpoints = (start, neighbor) return max_distance, endpoints def check_rip_viability(diameter): """Determine if RIP can operate on this network.""" if diameter <= 14: return "SAFE: Diameter well within RIP limits" elif diameter == 15: return "MARGINAL: Exactly at RIP limit, no room for growth" else: return f"INVALID: Diameter {diameter} exceeds RIP maximum of 15" # Example: Ring network of 30 routersring_30 = {i: [(i-1) % 30, (i+1) % 30] for i in range(30)}diameter, endpoints = calculate_diameter(ring_30)print(f"30-router ring: Diameter = {diameter}")print(f" Endpoints: R{endpoints[0]} to R{endpoints[1]}")print(f" RIP Status: {check_rip_viability(diameter)}") # Output:# 30-router ring: Diameter = 15# Endpoints: R0 to R15# RIP Status: MARGINAL: Exactly at RIP limit, no room for growthWhen designing RIP networks, aim for diameter ≤ 12, leaving room for backup paths that might add hops. If your network diameter approaches 14-15, consider OSPF or evaluate if network redesign can reduce diameter through additional links.
Beyond the 15-hop maximum, hop count as a metric has inherent limitations that affect routing quality. Understanding these limitations explains why more sophisticated protocols use composite metrics.
The Bandwidth Blindness Problem
In the diagram above:
RIP's calculation:
RIP's decision: All three paths are equal! Traffic may be distributed across them.
Reality:
The fiber path has 178,571 times more capacity than the dialup paths, yet RIP treats them identically.
Problematic Scenarios
1. Asymmetric Network Design
Networks with high-speed cores and slow edge links:
2. Geographic Distribution
Transcontinental links vs. local connections:
3. Redundancy Architecture
Primary high-speed path plus backup slow path:
The most dangerous scenario is when hop count leads RIP to select a clearly inferior path. Users experience poor performance, but the network appears "working" to administrators checking connectivity. The problem is invisible at layer 3 but obvious at layers above.
Modern routing protocols use more sophisticated metrics that address hop count's limitations. Understanding these alternatives provides context for RIP's design trade-offs.
| Protocol | Metric Type | Components | Formula/Calculation |
|---|---|---|---|
| RIP | Hop Count | Hops only | Metric = hops (max 15) |
| OSPF | Cost | Bandwidth | Cost = Reference_BW / Interface_BW |
| EIGRP | Composite | BW, Delay, (Load, Rel.) | Metric = f(BW, Delay, K-values) |
| IS-IS | Cost | Configurable | Sum of link costs (default 10) |
| BGP | Path attributes | AS Path, etc. | Complex policy-based selection |
OSPF Cost Metric
OSPF calculates cost based on bandwidth:
Cost = Reference_Bandwidth / Interface_Bandwidth
Default Reference_Bandwidth = 100 Mbps (10^8 bps)
Examples:
10 Gbps link: 100,000,000 / 10,000,000,000 = 0.01 → 1 (minimum)
1 Gbps link: 100,000,000 / 1,000,000,000 = 0.1 → 1
100 Mbps: 100,000,000 / 100,000,000 = 1
10 Mbps: 100,000,000 / 10,000,000 = 10
1 Mbps: 100,000,000 / 1,000,000 = 100
56 Kbps: 100,000,000 / 56,000 = 1,785
With OSPF, our earlier example becomes:
OSPF correctly prefers the high-speed path.
EIGRP Composite Metric
EIGRP uses a complex formula:
Metric = 256 × [(K1 × BW) + (K2 × BW)/(256 - Load) + (K3 × Delay)] × [K5/(Reliability + K4)]
Default K-values: K1=1, K2=0, K3=1, K4=0, K5=0
Simplified: Metric = 256 × (BW + Delay)
Where:
BW = 10^7 / minimum_bandwidth_in_kbps
Delay = sum of delays / 10 (in microseconds)
EIGRP considers both bandwidth bottlenecks and cumulative delay.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
# Compare path selection across protocols def rip_metric(hops): """RIP: Simple hop count.""" return min(hops, 16) def ospf_cost(bandwidths_bps, reference_bw=100_000_000): """OSPF: Sum of interface costs based on bandwidth.""" total_cost = 0 for bw in bandwidths_bps: cost = max(1, int(reference_bw / bw)) total_cost += cost return total_cost def eigrp_metric_simplified(min_bandwidth_kbps, total_delay_us, k1=1, k3=1): """EIGRP: Composite metric (simplified, K2=K4=K5=0).""" bw_component = (10_000_000 / min_bandwidth_kbps) * 256 delay_component = (total_delay_us / 10) * 256 return int(k1 * bw_component + k3 * delay_component) # Scenario: Two paths to destination# Path 1: 10 Gbps fiber, 2 hops, 1ms delay each# Path 2: 56 Kbps dialup, 1 hop, 50ms delay print("Path 1 (10 Gbps, 2 hops, 2ms total):")print(f" RIP Metric: {rip_metric(2)}")print(f" OSPF Cost: {ospf_cost([10_000_000_000, 10_000_000_000])}")print(f" EIGRP Metric: {eigrp_metric_simplified(10_000_000, 2000)}") print("Path 2 (56 Kbps, 1 hop, 50ms):")print(f" RIP Metric: {rip_metric(1)}")print(f" OSPF Cost: {ospf_cost([56_000])}")print(f" EIGRP Metric: {eigrp_metric_simplified(56, 50000)}") print("Best Path Selection:")print(" RIP chooses: Path 2 (lower hop count)")print(" OSPF chooses: Path 1 (lower cost)")print(" EIGRP chooses: Path 1 (better composite)") # Output:# Path 1 (10 Gbps, 2 hops, 2ms total):# RIP Metric: 2# OSPF Cost: 2# EIGRP Metric: 256256## Path 2 (56 Kbps, 1 hop, 50ms):# RIP Metric: 1# OSPF Cost: 1785# EIGRP Metric: 46995970Even sophisticated metrics have limitations. OSPF's cost is static (doesn't reflect current load). EIGRP can oscillate if load/reliability are included. The "best" metric depends on network requirements—RIP's simplicity remains valuable when its assumptions match reality.
Despite its limitations, hop count can work well when network design accommodates its characteristics. Here are strategies for effective RIP deployment.
Strategy 1: Homogeneous Link Speeds
If all inter-router links have similar bandwidth, hop count becomes a reasonable proxy for path quality:
All links: 1 Gbps
Path 1: A → B → C (2 hops, 2 Gbps potential)
Path 2: A → D → E → F → C (4 hops, 4 Gbps potential)
RIP selects Path 1: Fewer hops = less latency, acceptable
Strategy 2: Topology Design for RIP
Strategy 3: Offset Lists (Where Supported)
Some RIP implementations allow offset lists—manually adding to the metric of specific routes:
# Cisco IOS example
# Add 5 to metric for routes learned from slower interface
router rip
offset-list 10 in 5 Serial0/0
access-list 10 permit any
# Effect: Routes via Serial0/0 are 5 hops "worse"
# RIP prefers faster interfaces (shorter effective hop count)
This workaround lets administrators influence path selection when topology alone isn't sufficient.
Strategy 4: Passive Interfaces and Filtering
# Don't advertise routes on undesired interfaces
router rip
passive-interface FastEthernet0/0 # No RIP on this interface
# Filter specific networks
router rip
distribute-list 1 out Serial0/0
access-list 1 deny 10.0.0.0 0.255.255.255
access-list 1 permit any
# Routes to 10.0.0.0/8 not advertised via Serial0/0
| Scenario | Challenge | Strategy |
|---|---|---|
| Mixed link speeds | RIP ignores bandwidth | Uniform core links, offset-lists for slow links |
| Deep hierarchy | 15-hop limit approached | Flatten topology, add direct links |
| Remote branches | Many hops to central | Hub-and-spoke design, dedicated WAN links |
| Backup slow links | RIP uses backup inappropriately | Offset-list +8 on backup, force primary use |
| Multiple paths exist | RIP load-balances across unlike paths | Filter routes, manual redistribution |
If you find yourself using many offset-lists and filters to make RIP behave correctly, consider migrating to OSPF or EIGRP. The complexity of workarounds can exceed the complexity of running a proper link-state protocol.
Understanding how the metric field appears in actual RIP messages helps with troubleshooting and packet analysis.
Message Structure Review
Each route entry in a RIP message contains a 4-byte metric field (bytes 17-20 of the entry):
Route Entry (20 bytes):
Bytes 0-1: Address Family (0x0002 for IP)
Bytes 2-3: Route Tag (RIPv2) or Must Be Zero (RIPv1)
Bytes 4-7: IP Address
Bytes 8-11: Subnet Mask (RIPv2) or Must Be Zero (RIPv1)
Bytes 12-15: Next Hop (RIPv2) or Must Be Zero (RIPv1)
Bytes 16-19: Metric (1-16)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
# Wireshark/tcpdump analysis of RIP metric field # Sample RIP Response packet (hex dump)# Command: 02 (Response)# Version: 02 (RIPv2)# # Route Entry 1:# 00 02 Address Family: IP# 00 00 Route Tag: 0# 0a 00 01 00 IP Address: 10.0.1.0# ff ff ff 00 Subnet Mask: 255.255.255.0# 00 00 00 00 Next Hop: 0.0.0.0 (use sender)# 00 00 00 02 Metric: 2 <-- This network is 2 hops away # Route Entry 2:# 00 02 Address Family: IP# 00 00 Route Tag: 0# c0 a8 00 00 IP Address: 192.168.0.0# ff ff 00 00 Subnet Mask: 255.255.0.0# 00 00 00 00 Next Hop: 0.0.0.0# 00 00 00 10 Metric: 16 <-- UNREACHABLE (0x10 = 16) # Python: Parse RIP metric from packet bytesdef parse_rip_entry(entry_bytes): """Parse a single RIP route entry.""" import struct af, tag = struct.unpack('!HH', entry_bytes[0:4]) ip = '.'.join(str(b) for b in entry_bytes[4:8]) mask = '.'.join(str(b) for b in entry_bytes[8:12]) nexthop = '.'.join(str(b) for b in entry_bytes[12:16]) metric = struct.unpack('!I', entry_bytes[16:20])[0] # Interpret metric if metric == 16: status = "UNREACHABLE" elif 1 <= metric <= 15: status = f"{metric} hops" else: status = f"INVALID ({metric})" return { 'address_family': af, 'ip': ip, 'mask': mask, 'next_hop': nexthop, 'metric': metric, 'status': status } # Example usageentry_hex = bytes.fromhex('0002 0000 0a000100 ffffff00 00000000 00000002'.replace(' ', ''))result = parse_rip_entry(entry_hex)print(f"Network: {result['ip']}/{result['mask']}")print(f"Metric: {result['status']}") # Output:# Network: 10.0.1.0/255.255.255.0# Metric: 2 hopsCommon Metric Patterns in Packet Captures
| Metric Value (Hex) | Metric Value (Dec) | Interpretation |
|---|---|---|
| 0x00000001 | 1 | Directly connected network |
| 0x00000002 | 2 | One router away from sender |
| 0x0000000F | 15 | Maximum valid metric (15 hops) |
| 0x00000010 | 16 | Unreachable (infinity) |
0x00000010 | 16 | Invalid (should be treated as 16) |
When troubleshooting RIP, watching metric values in packet captures reveals the network's understanding of topology. If you see metric 16 for a network that should be reachable, track upstream to find where it was poisoned. If metrics seem wrong, trace the path to find where the calculation diverged.
We've thoroughly examined RIP's hop count metric—its design rationale, mathematical properties, and practical implications. Let's consolidate the key insights:
What's Next
Now that we understand RIP's metric, we'll examine its timer mechanisms. RIP uses multiple timers to control update frequency, route expiration, and garbage collection. These timers define RIP's convergence behavior and are critical for network stability.
You now understand the hop count metric in depth—why it was chosen, how infinity is defined, what the 15-hop limit means for network design, and how it compares to more sophisticated metrics. You can design networks that work well with hop count and recognize when to consider alternative protocols.