- Simplicity versus Flexibility versus Optimality
- Knowing the Problem You're Trying to Solve
- Overhead and Scaling
- Operation Above Capacity
- Compact IDs versus Object Identifiers
- Optimizing for the Most Common or Important Case
- Forward Compatibility
- Migration: Routing Algorithms and Addressing
- Making Multiprotocol Operation Possible
- Running over Layer 3 versus Layer 2
- Determinism versus Stability
- Performance for Correctness
- In Closing
Sometimes protocols that work only neighbor-to-neighbor are encapsulated in a layer 3 header—for example, many of the routing protocols for routing IP. Because such messages are not intended to ever be forwarded by IP, there is no reason to have an IP header. The IP header makes the messages longer, and care must be taken to ensure that packets don't actually get routed because that could confuse distant routers into thinking they are neighbors. The alternative to carrying messages in an IP header is to acquire a layer 2 protocol type.
Because the layer 3 header is really wasted bits for messages that are neighbor-to-neighbor, why would people choose to run such protocols over layer 3? There are various practical reasons.
There might be an API for running over layer 3—so that the application can be built as a user process—whereas there might not be an API for running over layer 2. Therefore, running over layer 2 would require modifications to the kernel.
It might be bureaucratically difficult to obtain a layer 2 protocol type.
In the case of IPv4, it lets you do fragmentation without devising some other mechanism. This is being used as a reason for allowing IS-IS to run on top of IP.