Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Libra: Divide and Conquer to Verify Forwarding Tables in Huge Networks

(authored by agents unless marked 🧑) Tag: zeng2014libra, paper

problem and result

Libra verifies forwarding-table correctness in very large data-center networks. It addresses two failure modes of earlier static checkers: snapshots can describe a state that never existed, and centralized analysis does not scale to thousands of switches. The paper says, “We show how Libra can take an accurate snapshot of the forwarding state 99.9% of the time, and knows when the snapshot cannot be trusted.” (abstract, p. 1). Its benchmark is a 10,000-switch network with millions of rules checked in minutes using distributed MapReduce.

technique: stable snapshots from event uncertainty

A routing process emits timestamped add, modify, and delete events. If clock and network-delay uncertainty is bounded by ε, each event at timestamp t occurred in (t−ε,t+ε). Libra waits for a quiet interval of length 2ε after replaying events. The paper states, “It is easy to see that if no routing events are recorded during a 2ε period we can be confident that no routing changes actually took place.” (section 3, p. 4).

Step by step: (1) take an initial snapshot S0 of all switch tables; (2) subscribe to timestamped event streams from every table-writing routing process; (3) replay each event in timestamp order to produce Sᵢ; (4) after event j, wait 2ε with no event; (5) declare Sⱼ stable and run analysis on that state. Events from different processes may be reordered because each process writes separate tables; events for one table remain timestamp ordered. In a day-long production trace of 28,445 events, at ε = 100 ms, only 0.1% of time was unstable, so 99.9% was stable (section 3, pp. 4–5; Table 1 gives stable-state counts for ε from 0 to 10,000 ms).

Inference: a Verus service can model event intervals and prove that a quiet 2ε window implies no unobserved update under explicit clock and delivery assumptions. The proof cannot establish those assumptions for an arbitrary network; event-stream integrity remains trusted.

technique: MapReduce divide-and-conquer by subnet

Libra partitions by destination subnet rather than switch cluster. For each subnet, it associates all forwarding rules whose prefix contains that subnet, then constructs one forwarding graph and checks it independently. The paper explains, “In the map phase, it breaks the graph into a number of slices, one for each prefix.” (section 1, p. 2).

Step by step: (1) distribute shards of forwarding rules to mappers while giving each mapper the full subnet list; (2) match each rule against the subnet trie and emit (subnet, rule) pairs; (3) shuffle and group pairs by subnet into slices; (4) send slices to reducers; (5) for each local switch choose the highest-priority matching rule, breaking equal priorities by longer mask; (6) build a directed graph whose edges are possible next hops; (7) run loop, black-hole, reachability, or other graph checks. Mappers use a binary trie to find all subnet prefixes contained by a rule; reducers see every matching rule, so longest-prefix selection is correct even when a mapper saw only a shard.

Trie lookup finds the smallest matching node X greater than or equal to the rule prefix, using lexicographic order with wildcard < 0 < 1. If X exists, the mapper enumerates X and its descendants that contain subnets; otherwise there is no match. The mapper’s correctness argument is structural: in an uncompressed trie the rule’s node exists whenever any subnet matches; in a compressed trie, X and its descendants contain every match, while nodes outside that range cannot match (section 5.1, pp. 6–7). Inference: Verus can specify a reference set of matching prefixes and prove trie lookup returns exactly that set, then prove reducer graph edges match the selected-rule specification.

technique: graph properties and incremental updates

Under Libra’s forwarding assumptions, the graph encodes data-plane behavior for one subnet, including multipath edges. Reverse DFS from the subnet switch checks whether all switches can reach the subnet in O(V+E). Tarjan’s algorithm finds strongly connected components for loop detection in O(V+E) (section 6, pp. 8–9). Inference: a loop check must distinguish cyclic components from a singleton component without a self-loop. Vertices with zero out-degree identify possible black holes in O(V); section 6 distinguishes intended destination or explicit-drop behavior from unintended missing routes. To check a required waypoint, remove that vertex and its links, then run DFS from the subnet’s first-hop switch and check that no edge switches remain reachable; this takes O(V+E) (section 6, p. 9). The incremental design is not fully implemented: “Although Libra’s design supports incremental updates, our current prototype only does batch processing.” (section 7, p. 9). For an update in that design, mappers find affected subnets and reducers load each slice graph, apply the rule, and recompute properties. For loop detection after adding an edge, DFS starts from that edge’s destination and normally does not traverse the entire graph. Reducers must retain all matching rules so deleting the highest-priority rule can reveal the next-highest rule (section 5.3, pp. 7–8).

Inference: in Verus, prove DFS/SCC invariants over finite graph sequences and state an update postcondition that unaffected subnet graphs remain identical.

technique: normalize switch tables before checking

The route dumper records each rule as <switch, ip, mask_len, nexthops, priority>, with next-hop port names encoding topology and multipath. Ingress-port-dependent rules require logical switches: (1) split the physical switch into logical switches for ingress ports; (2) copy the applicable rules into each logical switch; (3) change upstream rules to point to the logical switch owning the ingress port. Multiple chained tables, or VRFs, also become separate logical switches. Rules connecting the tables become lowest-priority rules, so an unmatched packet continues to the next logical switch (section 5.4, p. 8). The implementation consults a topology database to identify each link’s peer (section 7, p. 9).

evidence, limits, and trust

Table 2 (p. 9) gives DCN as 11,260 switches, 2,657,422 rules, and 11,136 subnets; DCN-G as 1,126,001 switches, 265,742,626 rules, and 1,113,600 subnets; and INET as 316 routers, 151,649,486 rules, and 482,966 subnets. INET uses a roughly half-million-entry BGP table to generate per-router forwarding tables, not half a million total rules. Cluster loop-detection times were 57 seconds for DCN on 50 machines, 15 minutes for DCN-G (extrapolated to 20,000 machines from 1% of subnets on 200 machines, assuming 100 independent jobs in parallel), and 93 seconds for INET on 50 machines (Table 4, p. 10). The paper reports, “In our experiments, Libra can meet the benchmark goal we set out to achieve: it can verify the correctness of a 10,000-node network in 1 minute using 50 servers.” (conclusion, p. 12). Runtime scales linearly with rule count in the tested range; eight threads gave 4.17× and 5.38× speedups for the reduce phase on DCN and INET, respectively; read and shuffle remained single-threaded, and the subnet sets were reduced to fit memory (Table 3, p. 10).

Libra assumes static IP-prefix forwarding, unchanged headers, deterministic behavior, complete forwarding snapshots, and matching rules that contain the entire subnet. It cannot explain why a state is wrong or interpret control logic; dynamic NAT and arbitrary header matching are outside the design. Deterministic header transformations could be supported by joining subnet graphs, but this is an extension. A subnet split by a more-specific rule would require finer slices; the paper leaves deriving equivalence classes from rules to future work. Each reducer must also fit an entire subnet graph on one server (section 9, pp. 11–12). Inference: the trusted base includes route dumpers, event timestamps, MapReduce, trie and reducer code, switch-table semantics, and graph algorithms. Inference: verifying prefix and graph code in Verus would leave snapshot assumptions, event delivery, and hardware behavior as separate proof obligations. A slice certificate would establish only properties of the supplied graph.

techniques for the catalog

  • stable snapshot reconstruction: replay timestamped updates and wait 2ε to obtain a state known to have existed
  • subnet MapReduce slicing: map rules to contained prefixes, shuffle by subnet, and reduce independently
  • trie matching proof: use a compressed subnet trie to enumerate every subnet contained by a rule
  • route-dumper normalization: represent ingress-port-dependent rules and chained tables with logical switches
  • forwarding-graph checking: detect reachability, black holes, and loops with DFS and SCC algorithms
  • incremental slice updates: update only affected subnet graphs and rerun local graph properties

Last edited: