CS 4251/6250 — Quiz 2 study notes
exam2_ipad_problems.pdf, solve that problem by hand, then open “Show solution” here.
Problems are written in the same style as Quiz 1 and HW2 (select-all MCQs + numerical problems). The last section is a full mock quiz.
0 · Exam intel (from the transcripts)
I read every transcript for hints. These are the ones that change how you should study:
| What the professor said | What it means for you |
|---|---|
| “The quiz is going to cover wherever we stop on Thursday… done with Unit 2… [Unit 3] is not going to be part of the quiz.” (L17) | Coverage = L9–L18. Network verification (L18) is in. BGP/Unit 3 is out. |
| Lecture 19 (last words before the quiz): “Quiz one was designed so that you all have enough time to flip through all the material… quiz two is not… it's gonna be long”; about 20% of questions “a little bit harder”; “how you index your open book material” matters. | Less time per question than Quiz 1. Know the core without the sheet; use the sheet's index for numbers and methods only. The plan now has a lookup drill and a 60-min mock. |
| “Pretty much… 90% of it is on material since quiz one… part of [the PCC] question is going to be connecting it to the general congestion control material. And that is actually the only question on the exam that touches on the rest… out of… eight questions.” (L19) | Part 1 = one sub-question, inside the PCC question. Study PCC vs Reno/CUBIC/Vegas/Copa/BBR (§1.4 table); don't spend more on Part 1 than that. |
| “A bunch of these questions are [multiple choice], but there is one or two that are numerical… assignment two is a good guide… variations on that.” MCQs are written to look like “seemingly confident, seemingly reasonable” LLM answers; several statements so random guessing doesn't work. Don't read the papers: “the exam is gonna be reflective of the way the material was covered in class.” (L19) | 8 questions, mostly select-all; 1–2 HW2-style numericals. Train on spotting the one wrong word in a plausible statement (MCQ sprint). Notes + slides are the right material; papers are not. |
| “Cumulative… heavily biased towards new content… some questions on congestion control because that is something we covered after quiz one [PCC]… some ideas there that depend on information we covered before quiz one.” (L18) | Expect a PCC/Vivace question that leans on BBR/Copa/utility ideas. Section 9 refreshes Quiz 1 material. |
| “Quiz two might be a little bit harder” · “the MCQs are the harder questions.” (L10, L11) | Most points are lost on select-all MCQs. Every MCQ here has a full explanation for each option. |
| “Homework questions and numerical problems we've covered in class are very good guidance on the numerical problems… the rest is MCQ logical questions… not memorization.” (L9) | The numerical problems will look like HW2 and the in-class worked examples (min-MLU, bandwidth functions, B4 waterfill, SWAN updates, TeaVaR loss). All of them are re-drilled here with new numbers. |
| HW2 is “due right before quiz two” and the model answers are released early “if you need to study them for Thursday.” Meta's heuristic “is going to be part of the covered material,” like Vegas was for Quiz 1. (L13, L14, L18) | HPRR (Meta's heuristic) and the HW2 problems are fair game. Every HW2 problem type has a twin here. |
| “The exam is going to require you to know some of these low-level details.” (L18) | Know the mechanisms: label-stack depth 3 + Binding SID, the version bit, sFlow, NIB pub-sub, SWAN's max(old,new) constraint, TeaVaR's loss definition, OneWAN's router roles. |
| Not covered: “the hardware and topology design of private WANs… you're not going to be even exposed to that in the homework”; how Meta enumerates cuts was skipped. (L14, L16) | Skip those. |
EXAM2_CHEATSHEET.pdf (10 pages) plus your Exam 1 EXAM_CHEATSHEET.pdf for Lectures 1–8. Your Exam 1 reference warns that flipping through too much paper eats time, so practise finding things with the index (Wednesday block) and take the mock with exactly these pages.
0.1 · The 3-day plan
Method: research on learning techniques (Dunlosky et al., 2013) rates practice testing and spacing as the two most effective study methods. Interleaving (mixing problem types) is also supported. Re-reading and highlighting score low. So the plan is: read the theory once → solve problems from memory → check → come back to the hard ones on a later day → finish with a timed, mixed mock quiz. Keep an error log: one line per miss, noting whether it was a concept gap or a careless slip.
| When | Block (tick when done, saved in this browser) | Time |
|---|---|---|
| Mon 11/2 evening | 20 m | |
| 5 m | ||
| 105 m | ||
| 80 m | ||
| 20 m | ||
| Tue 11/3 | 15 m | |
| 75 m | ||
| 70 m | ||
| 100 m | ||
| 130 m | ||
| 45 m | ||
| Wed 11/4 | 20 m | |
| 95 m | ||
| 65 m | ||
| 30 m | ||
| 15 m | ||
| 25 m | ||
| 45 m | ||
| 60 m | ||
| 90 m | ||
| — | ||
| Thu 11/5 AM | 30 m |
If a day runs short, cut in this order (never the MCQ sprint, the mock quiz or the error log): ① Monday's blank-page recall → do it as Tuesday's warm-up. ② The Quiz 1 bridge (P9.9 only). ③ Wednesday's warm-up → 10 min. ④ §8 Verification problems → do 8.2 and 8.6 only.
MLU = max_e load_e / c_e). Most lost points on Quiz-1-style problems are unit slips (MB vs Mb, ms vs s).
1 · Congestion control, part 3: model-based vs performance-oriented (PCC)
Lecture 9 · HW2 Q1 · the only congestion-control content after Quiz 1, so expect one question here.
1.1 The same loss event can mean four different things
Every algorithm from Quiz 1 is an event → action table: “when X happens, do Y”. Each rule quietly bakes in an interpretation of what the event means. The designer decided in advance what a loss or an RTT change “usually” means and hard-coded the right reaction for that case.
| Algorithm | Event | Prescribed response | Hidden assumption |
|---|---|---|---|
| Reno | packet loss | halve the window | loss = I overflowed the bottleneck queue |
| Scalable TCP | ACK arrives | increase the window (by a fixed fraction, so growth is faster on fast links) | ACKs flowing = there is room to grow |
| CUBIC | time passes | grow along a cubic curve of the time since the last loss (wall clock, not ACKs, which fixes RTT unfairness) | the right window is near where the last loss happened |
| FAST | RTT changes | adjust from delay feedback (aim for a target amount of queueing) | RTT above the minimum = my own queue |
| H-TCP | ACKs arrive | increase faster the longer it has been since the last loss | long loss-free periods = spare capacity |
The problem: you see “100 Mb/s, 1% loss”, but the hidden cause decides what the useful response is:
1.2 Two philosophies
BBR's evolution as a case study (the slide's example of how model-based designs grow):
- BBRv1 models the path as a pipe with two numbers: the bottleneck bandwidth (estimated as the largest delivery rate seen over the last ~10 round trips, a “windowed max”) and the propagation RTT (the smallest RTT seen over the last ~10 s, a “windowed min”). It sends at that bandwidth and periodically probes 25% higher to check whether more bandwidth appeared. It ignores loss completely. Inside Google's own network that worked, but on the Internet it was unfair to loss-based flows: CUBIC backs off on loss while BBRv1 keeps going, and in shallow buffers BBRv1 caused heavy loss.
- BBRv2 adds congestion-informed limits: loss and ECN marks now cap how much it keeps in flight. Its probing cycle got named phases: CRUISE (hold steady), REFILL (refill the pipe before a probe), UP (probe for more bandwidth), DOWN (drain the queue the probe created).
- BBRv3 refines when to stop probing, and how to tell a real bandwidth plateau (the path is full) from self-limitation (the application simply isn't giving it more data, so the delivery rate looks flat for a reason unrelated to the network).
Each fix added rules for more corner cases, and the original elegant model became less elegant. That is the critique PCC starts from: instead of an ever-growing model of the path, just measure which rate works better.
1.3 PCC Allegro (2015): randomized controlled trials on the rate
| Word | Meaning |
|---|---|
sending rate r (or x) | How fast the sender transmits, in Mb/s. PCC is rate-based: it sets the rate directly instead of a congestion window. |
| monitor interval (MI) | A stretch of time (about 1–2 RTTs) during which the sender holds one rate, so it can measure that rate's effect in isolation. |
utility u | The score computed at the end of an MI from what was measured there (throughput, loss; Vivace adds RTT). Higher = better. The utility function is the sender's definition of “good”. |
ε (epsilon) | How far the trial rates sit from r, as a fraction. ε = 5% at r = 100 → trials at 95 and 105 Mb/s. |
| RCT | Randomized controlled trial: test two “treatments” (a lower and a higher rate) under the same conditions, in random order, and compare outcomes. |
Step 1 — how a trial is scored: Allegro's utility
u(x) = T · S(L) − x · L T = x(1 − L) S(L) = 1 / (1 + e^(α(L − 0.05))), α = 100
| Term | What it is | What it does to the score |
|---|---|---|
x | the rate you sent at in this MI (Mb/s) | — |
L | loss rate in this MI (fraction of packets lost, e.g. 0.01 = 1%) | — |
T = x(1−L) | throughput that actually got through | the reward: more delivered data = higher score |
S(L) | a “soft switch” (sigmoid): ≈ 1 when L is well below 5%, exactly ½ at 5%, ≈ 0 above ≈ 7% | keeps the throughput reward only while loss is low; above ≈ 5% the reward is switched off |
−x·L | the rate you are wasting on lost packets | a penalty that grows with loss |
Worked example (x = 100 Mb/s, the same numbers as problem 1.3): L = 1% → S = 0.98, u = 99·0.98 − 1 = 96.2 · L = 4% → S = 0.73, u = 96·0.73 − 4 = 66.2 · L = 6% → S = 0.27, u = 94·0.27 − 6 = 19.3.
Why the sigmoid at all? With the plain score x(1−L), a sender that sends a bit more almost always delivers a bit more, even while everyone's loss climbs. Selfish senders all keep pushing until loss is very high (a bad Nash equilibrium: nobody gains by backing off alone). The sigmoid makes high loss wreck your own score, so everyone stops near 5%.
Step 2 — which direction to move: the trials
- Decision rule: if both pairs agree (“the lower rate scored higher” twice), move that way. If they disagree, the result is inconclusive: stay at
r, repeat, and increase ε to compare rates farther apart, where a real difference is easier to see through noise. - Slide example (r = 100, ε = 2%): pair 1 sends 98 then 102 and scores 94, 90 → lower wins. Pair 2 sends 102 then 98 and scores 96, 93 → higher wins. They disagree → stay at 100, widen ε.
- Why random order and two pairs? The network changes during the test (a queue may be building). With a fixed order, the second trial would always be measured in worse conditions and always lose. Random order turns that drift into a disagreement between pairs (detected) instead of a consistent wrong answer.
Step 3 — why comparing two nearby rates finds the best rate
The key point: the sender never sees this curve. Each MI gives it one dot. The two coloured pairs are Allegro's trials: at r₁ = 6 (below C) the right-hand dot U₊ is higher, so it moves up; at r₂ = 12 (above C) the left-hand dot U₋ is higher, so it moves down. Either way it walks toward the peak. The curve also moves when other flows join or leave (C is your share), which is why PCC never stops probing.
Step 4 — the control loop
- States: STARTING (double the rate while utility keeps rising, like slow start) → DECISION (run the trial pairs) → ADJUSTING (keep moving in the winning direction). If utility falls while adjusting, step back once and return to DECISION.
- Step size: Allegro's trials give only a direction. How far it moves follows a preset schedule; it ignores how much better the winning rate scored. This is the weakness Vivace fixes.
- Fairness among PCC flows (Q&A): for some utility functions (not all), the paper proves via game theory that competing PCC senders converge to the fair allocation. The proof assumes everyone sees comparable signals (similar loss). Real networks are messier, so convergence isn't guaranteed. Against CUBIC, PCC is unfair: it tolerates ~5% loss and grabs the bandwidth.
- Oscillation (Q&A): PCC keeps probing a bit above and below the optimum, so its rate oscillates around the peak. Only if all senders ran their trials in lockstep would the trials come out inconclusive exactly at the peak. PCC has no tendency to synchronize, unlike Reno, whose sawtooths synchronize over time.
1.4 PCC Vivace (2018): a better utility and gradient-based steps
Vivace keeps Allegro's loop (monitor intervals, trial rates, compare scores) and changes two things, which map onto Allegro's two problems:
| Allegro | Vivace | |
|---|---|---|
| Score (utility) | throughput and loss only | adds a latency term: how fast RTT is growing |
| Step (how far to move) | direction from trials, size from a fixed schedule | direction and size from the measured slope (gradient) of the score |
Change 1 — the score now includes delay: what dRTT/dt means
RTT = propagation delay (fixed for a given path) + queueing delay (waiting in the bottleneck buffer). On a fixed path, when RTT goes up the queue is growing, and when it goes down the queue is draining.
dRTT/dt (the “RTT gradient”) is how fast the RTT is changing during the MI: the slope of a line through the RTT samples, roughly (RTT at the end − RTT at the start) / MI length. Both are in ms, so it has no unit. Example: RTT goes 40 → 60 ms during a 100 ms MI → dRTT/dt = 20/100 = 0.20.
| dRTT/dt | What the queue is doing | What it says about your rate |
|---|---|---|
| > 0 | growing | you are sending faster than the bottleneck can drain |
| = 0 | steady (empty, or exactly balanced) | at or below capacity |
| < 0 | draining | you are below capacity and the backlog is shrinking |
Where (x − C)/C comes from: if you send at x into a bottleneck that drains at C, the queue grows by (x − C) bits every second. Queueing delay = queued bits / C, so the delay grows by (x − C)/C seconds every second. At x = 120 Mb/s and C = 100 Mb/s: (120 − 100)/100 = 0.2, the same 0.20 slope as above. So the slope measures how far above capacity you are right now.
u(x) = x^t − b · x · (dRTT/dt) − c · x · L 0 < t < 1 ; b, c > 0 are tuning weights whiteboard writes the same thing as U(x) = x^α₁ − α₂·x·dRTT/dt − α₃·x·L
| Term | Plain meaning |
|---|---|
x^t (e.g. t = 0.9) | Reward for sending, with diminishing returns: doubling the rate less than doubles the reward. This concave shape is what lets competing Vivace flows settle on a fair split (same idea as log utility in Part 1). |
−b·x·dRTT/dt | Penalty for growing the queue, scaled by your rate. If the queue is draining (slope < 0) this term becomes a bonus. |
−c·x·L | Penalty for loss. |
Worked example (problem 1.4, simplified u = x − 2·x·dRTT/dt, no loss, C = 100): x = 120 → slope 0.2 → u = 120 − 2·120·0.2 = 72 · x = 110 → slope 0.1 → u = 110 − 22 = 88 · x = 90 → slope −0.1 → u = 90 + 18 = 108. Sending closer to capacity, or a bit under it while a queue drains, scores better.
What to look for: the blue interval has the higher average RTT (65 vs 50 ms) even though 110 is the better rate. It starts on top of the queue the orange interval built. A score based on the RTT value would blame 110 for 120's queue. The slope judges each rate only by what it is doing to the queue now: 0.10 < 0.20, so 110 is better.
Change 2 — how far to move: the gradient
What is the gradient for? Deciding how big a step to take. After a pair of trials Vivace has two points on the score-vs-rate curve: (r₋, U₋) and (r₊, U₊). The slope between them,
g ≈ (U₊ − U₋) / (r₊ − r₋) "how much score do I gain per extra Mb/s, around my current rate"
- The sign of g gives the direction: g > 0 means the higher rate scored better, so go up.
- The size of g says how far you are from the best rate: near the peak the curve is flat (g ≈ 0); far away it is steep (|g| large).
Δr = θ · g new rate = r + Δr
- θ turns “score per Mb/s” into “Mb/s to move” (like a learning rate). It is a confidence amplifier: when several steps in a row go the same way, θ grows (bolder steps); when the direction flips, it resets (careful again).
- Bound: |Δr| is capped at a fraction of r, because measurements are noisy and one bad g could otherwise cause a huge jump.
Worked example (problem 1.5): at r = 80, trials at 76 and 84 score U₋ = 61.0 and U₊ = 58.6. g = (58.6 − 61.0)/(84 − 76) = −2.4/8 = −0.3 (the higher rate scored worse, so go down). With θ = 10: Δr = 10 · (−0.3) = −3 → new rate 77 Mb/s.
The takeaway: step size shrinks automatically as you approach the peak, so Vivace moves fast when far away and doesn't overshoot when close. Allegro's fixed schedule can't do this. This is gradient ascent: like walking up a hill in fog, you test a small step each way, feel which way is up and how steep it is, and take a stride in proportion.
PCC vs the Quiz 1 algorithms (the one Part 1 link on the quiz)
Lecture 19: the PCC question includes a part “connecting it to the general congestion control material”, and that is the only Part 1 content on the quiz.
| Algorithm | Philosophy | Signal it acts on | Random (non-congestive) loss | Next to CUBIC / Reno |
|---|---|---|---|---|
| Reno | model-based (event → rule) | loss: +1 pkt/RTT, halve on loss | backs off (misreads it as congestion) | —; RTT-unfair (rate ∝ 1/RTT) |
| CUBIC | model-based | loss; window grows on a cubic curve of time since last loss | backs off | —; RTT-fair growth; fills buffers |
| Vegas | model-based, delay | queue estimate (Expected − Actual)·BaseRTT kept between α and β | still halves on loss | starves: backs off as the loss-based flow fills the queue |
| Copa | model-based, derived from utility ln x − δ ln d | queueing-delay magnitude: target 1/(δ·dq), ≈ 1/δ packets queued | ignores (reacts to delay) | competitive mode when the queue never drains |
| BBR v1 | model-based (pipe: BtlBw, RTprop) | max delivery rate, min RTT; paces | ignores loss → robust | unfair to CUBIC (ignores the loss CUBIC obeys) |
| PCC Allegro | performance-oriented (black box) | utility of throughput and loss, compared across nearby rates | tolerates up to ≈ 5% → robust (keeps rate on lossy links) | grabs the bandwidth: CUBIC backs off, Allegro doesn't |
| PCC Vivace | performance-oriented | utility of rate, RTT gradient and loss | loss penalized in the utility, not by a fixed rule | keeps queues low (penalizes RTT growth) |
- Link to NUM (Part 1): every congestion controller implicitly maximizes some utility (Reno ≈ −1/(RTT²x), i.e. α = 2 fairness). Copa writes its utility down and turns it into a fixed target-rate rule. PCC writes its utility down and searches for the best rate online by experiment. Concave utilities (log, xt with t < 1) are what make competing senders converge to a fair split, in NUM and in PCC alike.
- Link to the model-based critique: Reno, CUBIC, Vegas, Copa, BBR each assume what a signal means (loss = overflow, delay = my queue). When the assumption is wrong (random loss, another flow's queue, shallow buffers) the hard-wired response is wrong. PCC avoids naming the cause, at the price of designing the utility, the trial length and the exploration.
- Link to bufferbloat: loss-based schemes and Allegro both fill buffers; delay-aware ones (Vegas, Copa, BBR, Vivace) keep the queue short.
Rate-based vs window-based are two views of one control. A window-based sender (BBR-style) still paces, at about 2·cwnd/RTT, i.e. a bit above cwnd/RTT. A rate-based sender (PCC) can still cap packets in flight at 2·rate·RTT, so it never piles unbounded data into the network. PCC's analytical models assume pure rate-based control, so adding the cap means revisiting the math, but in an implementation it makes sense.
1.5 Learning a rate vs learning a policy; where AI fits
| What is learned | Example | When |
|---|---|---|
| the current rate x | Allegro / Vivace | during live experiments (online) |
| a table of control rules | Remy | offline generation |
| neural policy parameters θ | Aurora | offline training |
- A policy is a function from what the sender has observed (recent RTTs, loss, rates) to an action (new rate or cwnd). Reno is a hand-written policy.
- Allegro / Vivace don't learn a policy: they learn the rate itself, live, by running experiments on the real network.
- Remy (MIT, 2013): a computer search, run offline in simulation, produces a table of rules (“if the observed conditions look like this, change the window like that”). Deployed, the table is fixed.
- Aurora: a neural network trained offline with reinforcement learning (trial and error in simulation, rewarded by a utility). Deployed, its weights θ are fixed.
A fixed learned policy still produces a changing sending rate, because its inputs (the observations) keep changing. Systems point: TCP lives inside the operating-system kernel, and kernel code generally avoids floating-point math. Neural models need floats, so they run as an ordinary program in user space. The transport reports RTT/loss/throughput through an API and the model answers with a rate or cwnd. The cost is the round trip between kernel and program: the model can't react to every ACK, only every RTT or every few RTTs.
1.6 HW2 Q1 patterns: BBR after a route change, PCC β, exploration
What to look for: the staircase. Each time the filter forgets the old high samples, the estimate drops to what was just measured (100 → 50 → 25 → 12.5), which shrinks cwnd again. That is the feedback spiral. The green jump at the end is the min-RTT filter finally expiring (≈ 10 s): BBR learns the real RTT, cwnd is sized correctly, and throughput recovers.
BBRv1 on a longer-RTT route: the min-RTT filter (10 s window) keeps the old, small RTT, so BBR underestimates the BDP and sets cwnd ≈ 2·BW·RTTold, which is too small. The sender becomes cwnd-limited, so delivery-rate samples drop. When the high samples expire from the 10-round max-BW filter, the BW estimate drops too, which shrinks cwnd further. This feedback spiral lasts until the min-RTT entry expires (≈10 s / ProbeRTT). Fix (HW answer): when several RTT samples are consistently above the stored min, temporarily drain inflight. If the RTT stays high at low load, it is a longer propagation delay: reset the min-RTT filter, recompute BDP/cwnd, and re-probe bandwidth. If the RTT falls back, it was queueing, so keep the old min. This is imperfect, because a persistent queue from other traffic also keeps the baseline high.
PCC with delay preference U = g − β·q (g = goodput in Mb/s, q = average queueing delay in ms). β is the exchange rate: how many Mb/s of goodput you are willing to give up to save 1 ms of queueing delay. Bigger β = more delay-sensitive.
The trap: a larger β does not always pick the lower-delay rate. With (80, 5) vs (100, 10), the break-even is 20/5 = 4, so both β = 0.25 and β = 1 pick the high rate. β only matters if it lands on different sides of the break-even.
Exploration vs exploitation: a trial must span at least one RTT (often several) to see its own effect. Shorter trials cause misattribution. Longer trials average out noise but cost throughput or queueing, and if conditions change during the trial the result mixes regimes or is stale. Trials should be long enough to be reliable and short enough to stay relevant.
Show solution
Correct: A, C, E
- A ✔ — Random loss isn't a congestion signal, so there's room to grow.
- B ✘ — You're the victim and haven't reached your fair share. The useful response is to maintain.
- C ✔ — Event→action tables bake an interpretation of the event into the action. That's what “model-based” means.
- D ✘ — PCC deliberately doesn't name the cause. It treats the network as a black box and compares the utility of nearby rates.
- E ✔ — Lecture table: shallow buffer → decrease slightly.
- What two rates are tested?
- Results: pair 1 (48 then 52): U = 40.1, 41.0. Pair 2 (52 then 48): U = 40.6, 39.8. What does Allegro do?
- Results: pair 1 (52 then 48): U = 41.2, 40.3. Pair 2 (48 then 52): U = 40.9, 40.2. What does Allegro do now, and what changes for the next MI?
- Why is each trial's utility only computed about one RTT after that trial's rate begins?
- Why randomize the order inside each pair?
Show solution
- r(1−ε) = 48 and r(1+ε) = 52 Mb/s.
- Pair 1: 52 wins (41.0 > 40.1). Pair 2: 52 wins (40.6 > 39.8). Both agree, so move up (to 52 Mb/s, entering ADJUSTING in that direction).
- Pair 1: 52 wins. Pair 2: 48 wins (40.9 > 40.2). The pairs disagree, so the MI is inconclusive: stay at 50, discard these trials, and increase ε so the next trials explore farther from r (noise may have hidden a small difference).
- The effect of a rate choice (queue growth, loss) only reaches the sender with ACK feedback about one RTT later. Scoring earlier would attribute the outcome of the previous rate to this trial (misattribution).
- Network conditions drift (a queue builds, a competitor arrives). With a fixed order the later trial would always be biased the same way. Random order turns drift into disagreement between pairs (detected as inconclusive) instead of a systematic wrong answer.
- Compute u for x = 100 Mb/s at L = 1%, 4%, 6%.
- Explain what this implies when Allegro shares a bottleneck with CUBIC.
- Name the metric missing from this utility and the consequence.
Show solution
- L = 0.01: exponent = 100(−0.04) = −4 → S = 1/(1+0.0183) = 0.982; T = 99 → u = 99·0.982 − 1 = 96.2.
L = 0.04: exponent −1 → S = 1/(1+0.368) = 0.731; T = 96 → u = 70.2 − 4 = 66.2.
L = 0.06: exponent +1 → S = 1/(1+2.718) = 0.269; T = 94 → u = 25.3 − 6 = 19.3. - Utility stays high until loss nears 5%, then collapses. So Allegro keeps pushing through loss rates that make CUBIC back off every time. In the lecture's words, Allegro grabs essentially all the bandwidth: PCC doesn't coexist with loss-based algorithms.
- Latency / RTT. Allegro happily fills buffers (bufferbloat). Vivace fixes this with the RTT-gradient term.
- Average RTT in each interval? Which rate would a utility penalizing average RTT prefer?
- RTT slope in each interval, and u(120), u(110)? Which rate wins?
- Show that both slopes match dRTT/dt = (x − C)/C. Using that, what is u(90)? Why is that term a reward?
Show solution
- Interval 1: (40+60)/2 = 50 ms. Interval 2: (60+70)/2 = 65 ms. A magnitude-based utility prefers 120, which is wrong, because the queue left behind by interval 1 inflates interval 2's RTT.
- Slopes: 20 ms/100 ms = 0.20 and 10/100 = 0.10. u(120) = 120 − 2·120·0.2 = 72. u(110) = 110 − 2·110·0.1 = 88. 110 wins, which is correct, since it is closer to C.
- (120−100)/100 = 0.2 ✓, (110−100)/100 = 0.1 ✓. At 90: slope = −0.1 (queue draining) → u = 90 − 2·90·(−0.1) = 108. A negative gradient is rewarded: draining the queue is even better than growing it slowly.
- Estimate the gradient g and the proposed change Δr. New rate?
- The next decision again points down with g = −0.25, and θ has doubled. New rate?
- Allegro with a fixed step of ε·r (ε = 0.05) — where does it go from 80? When is a fixed step worse?
- Why does Vivace bound Δr relative to r?
Show solution
- g = (58.6 − 61.0)/(84 − 76) = −2.4/8 = −0.3. Δr = θg = 10·(−0.3) = −3, so r = 77 Mb/s.
- θ = 20 → Δr = 20·(−0.25) = −5, so r = 72 Mb/s. Repeating the same direction raises confidence, so the steps get larger.
- It moves to 76 (step 4) whatever the slope. Far from the optimum, small fixed steps take many iterations. Near it, they overshoot and oscillate. Vivace's step shrinks as g → 0 near the peak.
- Utility measurements are noisy. A noisy, huge |g| would produce an extreme jump. The bound (a dynamic change boundary) limits fractional change per step.
- Utilities and choices for β = 0.5 and β = 2. Which gives lower delay?
- For which β are the two rates tied?
- Does a larger β always select a strictly lower-delay rate than a smaller β? Give a numerical counterexample (both configurations choose from the same two measured options).
- Interpret β's unit.
Show solution
- β = 0.5: low 60 − 1 = 59, high 72 − 7 = 65 → high. β = 2: low 60 − 4 = 56, high 72 − 28 = 44 → low. β = 2 gives the lower delay (2 ms vs 14 ms).
- 60 − 2β = 72 − 14β → 12β = 12 → β = 1 (= Δg/Δq = 12/12).
- No. Example: low (g = 50, q = 8), high (g = 70, q = 10). β = 0.5: 46 vs 65. β = 2: 34 vs 50. Both pick high, so the delay is the same. A larger β only changes the choice when β crosses the break-even Δg/Δq.
- Mb/s of goodput the operator is willing to give up to save 1 ms of queueing delay.
- Right after the change: cwnd (in Mb and in kB), the BDP the new path needs, and the throughput the flow can achieve.
- What happens to BtlBw_est when the old samples leave the BW filter? Next cwnd and throughput? Continue one more step.
- When does it recover, and why?
- Propose a modification and how it distinguishes longer propagation delay from queueing.
Show solution
- cwnd = 2·100 Mb/s·0.02 s = 4 Mb = 500 kB. New BDP = 100·0.08 = 8 Mb = 1 MB. Rate ≈ cwnd/RTT = 4 Mb/0.08 s = 50 Mb/s (cwnd-limited).
- Delivery samples are now ≈ 50, so after ~10 rounds BtlBw_est = 50 → cwnd = 2·50·0.02 = 2 Mb → 25 Mb/s. Next: 1 Mb → 12.5 Mb/s. A downward spiral, because both estimates feed each other.
- When the stale 20 ms sample expires from the 10 s min-RTT filter (ProbeRTT), RTprop_est = 80 ms. cwnd then matches the path and bandwidth probing (gain 1.25) climbs back to 100 Mb/s.
- HW answer: trigger an early RTT reassessment when the last several RTT samples are consistently above the stored min. Temporarily reduce inflight to drain queues and take fresh baseline samples. If RTT stays high under low load, it is propagation delay: reset the min-RTT filter, recompute BDP and cwnd, and re-probe bandwidth. If RTT drops back near the old value, it was queueing, so keep the old estimate. Imperfect: a persistent queue from other flows keeps the baseline elevated. Draining and resetting the filter are separate operations.
Show solution
Correct: B, D, E
- A ✘ — Remy generates its rule table offline.
- B ✔ — The policy maps observation history → action. Observations change, so the rate changes.
- C ✘ — User-space models react every RTT or every few RTTs; they can't react per ACK.
- D ✔ — Integer-only kernel math, plus the cost of kernel development.
- E ✔ — Allegro and Vivace learn the rate x online.
- F ✘ — Rate and window are linked through the RTT. A rate-based sender can cap inflight at about 2·rate·RTT, just as BBR (window-based) paces at about 2·cwnd/RTT. PCC's analysis assumes pure rate control, so the math would need revisiting.
- G ✘ — The professor's aside: big rate swings hurt other flows and make the feedback noisy. PCC compares nearby rates r(1±ε) instead.
Show solution
Correct: A, C, D
- A ✔ — Feedback lags by one RTT, so you'd score the previous rate.
- B ✘ — Not if the network changes during the trial.
- C ✔ — The core trade-off: reliable vs relevant.
- D ✔ — Mentioned in lecture as a PCC weakness.
- E ✘ — Exploration costs throughput or queueing, and long trials go stale.
2 · QUIC
Lecture 10 · HW2 Q2. Organizing question: besides “how fast?”, what must transport do for an app like a phone video page?
| App need | What can go wrong | QUIC mechanism |
|---|---|---|
| Start a secure exchange fast | TCP + TLS spend RTTs before useful data | TLS 1.3 integrated into the transport handshake (1-RTT; 0-RTT on resumption) |
| Progress on concurrent objects | head-of-line (HOL) blocking | independently ordered streams |
| Recover lost bytes without stalling others | TCP's single byte order | packet-number ACKs + loss inference + stream offsets |
| Respect receiver capacity | overrun the receiver | stream- and connection-level flow control |
| Survive Wi-Fi → cellular | TCP 4-tuple changes, so the connection dies | connection IDs + path validation |
| (Rate) | congestion | congestion control still governs everything, per connection |
2.1 Handshake: how many RTTs before the response?
- TLS = the protocol that authenticates the server and agrees on encryption keys. In TCP it runs on top of the finished TCP connection (layered, so the RTTs add up). In QUIC it is built into the transport handshake.
- Why 0-RTT is restricted: an attacker can capture and replay the first flight. Early data therefore only carries requests that are safe to repeat (e.g., a GET, not “transfer $100”), and the server must agree to accept it.
2.2 Why not just modify TCP? Ossification
A TCP change has to reach three places: the endpoint stacks (OS kernels, APIs), the peer (negotiation), and the path. The path is the real problem. Middleboxes are devices in the middle of the path that look inside packets: firewalls, NATs (which rewrite addresses and ports), load balancers, even home Wi-Fi routers. Many were built to expect TCP exactly as it looked years ago, so when they see something unfamiliar they “normalize” it (rewrite it to a standard form), strip it, or drop the packet as suspicious. Example: both endpoints support a new TCP option, but a firewall deletes it from the SYN, so the endpoints never learn the other side supports it and silently fall back to old behaviour (the slide's “the middlebox removes its signal”). The cycle: devices see a narrow set of behaviors → implementations depend on them → new values fail → fallback preserves the old assumptions. A brand-new transport protocol number would be dropped even more often.
Side effect: many implementations (Google, Cloudflare, Akamai, Meta…). Even with RFC 9000–9002, each makes its own assumptions, so interop problems appear (“Google server needs Google client” early on). IETF interop matrices helped.
2.3 Head-of-line blocking and streams
Head-of-line (HOL) blocking = data that already arrived can't be used because something in front of it in the delivery order is missing. Like a supermarket queue where everyone waits behind one person whose card was declined. TCP delivers one ordered byte stream, so if bytes 1000–1999 are lost, bytes 2000+ sit in the receiver's buffer, unusable, until the retransmission arrives, even when they belong to a completely different object.
| QUIC word | What it is |
|---|---|
| stream | an independent ordered byte sequence inside one connection (one per HTTP request/response) |
| STREAM frame | a chunk of one stream: (stream ID, byte offset, the bytes) |
| packet | one numbered transmission; holds one or more frames, possibly from different streams |
| UDP datagram | what actually crosses the network; carries one or more QUIC packets |
- HTTP/1.1: a separate TCP connection per object avoids cross-object HOL blocking, but costs handshakes, state, and CPU/threads.
- HTTP/2: many HTTP streams multiplexed over one TCP byte order. One lost TCP segment blocks all objects (TCP-level HOL).
- QUIC: congestion control, flow control, and encryption are per connection. Delivery order and reliability are per stream.
2.4 Reliability: packet numbers vs stream offsets
Why two numbering systems? They answer two different questions. Stream ID + offset answers “which bytes are these and where do they go?”, so the receiver can put data in place no matter which packet carried it. The packet number answers “which transmission is this?” and is never reused. In TCP, a retransmitted segment has the same sequence number as the original, so when an ACK comes back the sender can't tell whether it acknowledges the original or the copy. Its RTT sample is ambiguous. In QUIC every ACK names exactly one transmission, so RTT samples and loss detection are clean.
| Identifier | Names | When bytes are resent |
|---|---|---|
| TCP sequence number | byte position in the one connection stream | same numbers (so a retransmission's ACK is ambiguous) |
| QUIC stream ID + offset | byte position in one stream | same stream and offsets (reassembly, dedup) |
| QUIC packet number | one transmission | new packet number, never reused; packetization may change |
Example from the slides: packet 100 (A: offset 0, len 1000) is lost and its bytes are resent in packet 110 with the same A offset 0, len 1000. Then stream A can deliver bytes 0–1999 in order. An ACK reports packets received (“ACK 101–103”), not the next deliverable stream offset, so packet 100's fate is uncertain (delayed or lost).
- Packet threshold: a packet is declared lost when a sufficiently higher packet number is acknowledged (RFC 9002 default: 3 higher).
- Time threshold: an older unacked packet passes an RTT-based deadline (RFC: 9/8 × RTT).
- Probe timeout (PTO): when ACK progress stalls (e.g., the last packets of a short flow, or lost ACKs), send a probe to elicit ACKs. It is a shorter timer than TCP's RTO. PTO expiry alone does not declare loss.
- Cost: ACK frames list ranges of packet numbers (like SACK), plus per-stream metadata. That means more header bytes and slightly lower goodput (useful application bits per second, i.e. throughput minus headers and retransmissions) than TCP's compact cumulative ACK.
2.5 Connection migration
TCP's connection is its 4-tuple (src IP, dst IP, src port, dst port); a new IP kills it (timeout → app exception → new handshake → recover app state). QUIC uses connection IDs to locate state; packet protection authenticates the traffic. The client switches to a different issued CID (so the paths aren't trivially linkable), validates the new path, and re-learns what the new path supports (Wi-Fi 20 ms/100 Mb/s vs cellular 80 ms/10 Mb/s): “a surviving connection does not imply a surviving path model.”
- Connection ID (CID): an identifier in every QUIC packet header that the server uses to look up the connection's state. TCP looks up state by the 4-tuple, so a new IP address means “unknown connection”.
- Why switch to a different CID? Privacy: if the same ID appeared on Wi-Fi and cellular, an observer could link the two paths to one user.
- Path validation: the server sends a PATH_CHALLENGE with 8 random bytes to the new address; only the real client there can echo them in a PATH_RESPONSE. This proves the new address is reachable and really belongs to the peer, so an attacker can't redirect traffic by spoofing addresses.
- Re-learn the path: cwnd and RTT estimates from Wi-Fi (20 ms, 100 Mb/s) are wrong for cellular (80 ms, 10 Mb/s), so congestion control starts over for the new path while the streams continue.
2.6 HW2 Q2 pattern: scheduling buffered streams
Flow control vs congestion control: flow control protects the receiver (it advertises how many more bytes it can buffer: a credit per stream and one for the whole connection); congestion control protects the network (cwnd). The sender may send only what both allow.
All data is already at the sender, but the congestion window limits what is in flight, and the scheduler decides which stream gets those slots.
Prioritizing B helps B even with everything buffered. The cost is that lower-priority streams wait, and they can starve if high-priority data keeps arriving.
Method: build a table time | ACKs received | cwnd | packets sent, then add one-way delay to get arrival and display times.
| t (ms) | ACKs just received | cwnd | B-first sends | round-robin sends |
|---|---|---|---|---|
| 0 | — | 1 | B1 | A1 |
| 50 | the 1 packet sent at 0 | 2 | B2, A1 | B1, A2 |
| 100 | the 2 sent at 50 | 3 | A2, A3 | B2, A3 |
- TCP + TLS 1.3, fresh connection?
- QUIC, fresh connection?
- QUIC 0-RTT resumption, accepted by the server?
- What two conditions does 0-RTT require?
- Why can't the industry just merge TCP's SYN with the TLS ClientHello?
- For (a)–(c), when can the client send its HTTP request?
Show solution
- SYN/SYN-ACK (1 RTT) + ClientHello/ServerHello (1 RTT) + request/response (1 RTT) = 3 RTT = 90 ms.
- Combined transport + crypto handshake (1 RTT) + request/response = 2 RTT = 60 ms.
- Request in the first flight, encrypted with remembered keys = 1 RTT = 30 ms. The handshake still completes in parallel.
- ① Prior resumption state remembered from an earlier connection. ② The server accepts early data (only eligible, replay-safe requests).
- The change must reach both endpoints' OS stacks and survive the path. Middleboxes strip or reject unfamiliar TCP options or drop the packets (transport ossification). Correct endpoints don't guarantee deployability.
- One RTT before each response: TCP + TLS at 2 RTT = 60 ms, QUIC at 1 RTT = 30 ms, 0-RTT at 0 ms (in the first flight). The slide's “2 RTT” and “1 RTT” labels mark these request times.
| packet | A1 | B1 | C1 | A2 | C2 | A3 |
|---|---|---|---|---|---|---|
| arrives (ms) | lost → retransmission at 70 | 10 | 14 | 18 | 22 | 26 |
- Display times of A, B, C with one TCP connection (HTTP/2-style multiplexing).
- With QUIC, one stream per object.
- With three separate TCP connections (HTTP/1.1-style). Why not just do that?
Show solution
- TCP delivers bytes in order. Everything after A1's gap sits in the kernel buffer until 70 ms: A = B = C = 70 ms.
- Each stream is ordered independently: B = 10 ms, C = 22 ms (C1 at 14 and C2 at 22), A = 70 ms (needs A1).
- Same as QUIC (B 10, C 22, A 70). But you pay a handshake per connection, more state, CPU/threads in the app, and separate congestion controllers (more aggressive in aggregate). QUIC gets the independence inside one connection with one CC.
- What can the receiver hand to the application for stream A? For stream B?
- The sender retransmits the lost data. What packet number does it use, and which identifiers stay the same? Must it reuse the same packetization?
- What would TCP do differently with the bytes after the gap?
- Why is it useful that the retransmission has a new packet number?
Show solution
- Stream A: bytes 0–999 only (2000–2999 are buffered behind the gap). Stream B: nothing; its only bytes were in 41.
- A new, never-reused packet number (e.g., 47). Stream IDs and offsets stay the same (A off 1000 len 1000, B off 0 len 500). Packetization can change: they could be split into two packets or merged with new data.
- TCP would hold all later bytes, including other objects multiplexed in the same byte stream, until the gap is filled.
- Packet numbers identify transmissions, so an ACK for 47 is unambiguous. That gives clean RTT samples and loss detection; TCP reuses sequence numbers, so ACKs of retransmissions are ambiguous. Offsets identify bytes for reassembly and deduplication.
- B-first
- round robin, starting with A
- A-first
- Why does prioritization matter even though all the data is already buffered? What is the cost?
Show solution
| policy | t=0 (cwnd 2) | t=40 (cwnd 3) | t=80 (cwnd 4) | B shown | A shown |
|---|---|---|---|---|---|
| B-first | B1 B2 | A1 A2 A3 | A4 | 20 ms | 100 ms |
| RR (A first) | A1 B1 | A2 B2 A3 | A4 | 60 ms | 100 ms |
| A-first | A1 A2 | A3 A4 B1 | B2 | 100 ms | 60 ms |
- The congestion window, not the buffer, limits what is in flight. The scheduler decides which stream gets those scarce slots. Cost: the low-priority stream waits (A goes from 60 to 100 ms in B-first vs A-first). If high-priority data keeps arriving, low priority can starve. (In this case A ends at 100 under both B-first and RR.)
Show solution
Correct: A, B, D
- A ✔ — src IP, dst IP, src port, dst port.
- B ✔ — Connection IDs locate state; packet protection authenticates the traffic.
- C ✘ — “A surviving connection doesn't imply a surviving path model.” Re-establish what the new path supports (e.g., 20 ms/100 Mb/s → 80 ms/10 Mb/s).
- D ✔ — Explicit challenge/response before relying on the path.
- E ✘ — It switches to another issued ID (cid-X → cid-Y). The server maps both to the same connection.
- Which packets are declared lost by the packet threshold? Which are still undecided?
- A short flow's last packet's ACK is lost and nothing else is outstanding. Which mechanism helps, and what does its expiry do?
- Why does QUIC's ACK format cost some goodput compared with TCP's?
Show solution
- 20 (23 acked, 3 higher). 24 is not yet lost by packet threshold (largest acked 25 is only 1 higher); the time threshold (≈ 9/8 × RTT) may declare it. 26 is outstanding.
- The probe timeout (PTO): send a probe to elicit an ACK covering everything received. It is shorter than TCP's RTO wait. PTO expiry alone does not declare loss; the response to the probe does.
- ACKs list ranges of individual packet numbers (SACK-like), and frames carry per-stream metadata, so more header bytes per useful byte. TCP's cumulative ACK is one number.
Show solution
Correct: A, C, D, F
- A ✔ — Ordering is per stream: missing prefix → later bytes of that stream wait.
- B ✘ — Congestion control and connection flow-control credit are shared by all streams.
- C ✔ — And a brand-new transport protocol number would be dropped even more.
- D ✔ — Middleboxes see the IP and UDP headers and very little of QUIC's.
- E ✘ — QUIC lives in user space, so an application update changes the transport.
- F ✔ — Each makes its own assumptions (e.g., about path challenges and stream handling). IETF interop matrices exist because of this.
3 · Traffic engineering (TE) foundations
Lecture 11 · HW2 Q3. Unit 2 zooms into one operator's private WAN. Its inputs are aggregates (a traffic matrix), not individual flows.
The picture from the whiteboard: a content provider (Meta, Google, Microsoft) owns a private WAN that connects its data centers to each other and to PoPs, where it hands traffic to several ISPs and on to users. Because one operator owns the whole network (and often the sending hosts), it can decide where traffic goes and how much each service may send, which the public Internet cannot.
Utilization of a link = load on it / its capacity. 8 Gb/s on a 10 Gb/s link = 0.8 = 80%. Above 100% means the link can't carry it: queues grow and packets drop.
MLU (maximum link utilization) = the highest utilization over all links. It measures how close the busiest link is to overflowing. “Min-MLU TE” = choose routes so that the busiest link is as empty as possible.
3.1 Slow down, or move the traffic?
- ECMP (equal-cost multi-path) is what routers do by default when several shortest paths exist. For each packet it computes a hash (a scrambled number) of header fields (src/dst IP, ports, QoS) and uses it to pick a path. Every packet of the same flow has the same fields, so it always takes the same path, which keeps packets in order. Consequences: it splits flows, not bytes, and splits them equally, ignoring that the paths have different capacities. Equal flow counts ≠ equal load: 100 tiny flows on one path and one 100 Gb/s flow on the other is not balance.
- Min-MLU on parallel disjoint paths ⇒ equalize utilizations ⇒ split proportional to capacity;
MLU* = D / Σc. - TE vs congestion control: CC changes demand (rates). TE redistributes traffic. TE fixes an inefficient mapping but not insufficient resources (demand above the cut). Beyond the cut, CC or admission control must cut demand.
3.2 From NUM to TE, and why minimize peak utilization
| Congestion-control NUM (Unit 1) | Routing-only TE (Unit 2) | |
|---|---|---|
| Given | routing + capacities | demands + capacities |
| Choose | sending rates | where traffic goes (paths, splits) |
| Who / how | independent endpoints, distributed, must converge | one operator owns routers (and often contracts with sources), so centralized coordination is possible |
| Timescale | every RTT (ms), per flow | seconds to minutes, on aggregates |
They form a feedback loop: TE moves traffic, which changes the RTTs and bottlenecks each flow sees, which changes the rates CC picks, which changes the demand TE measures. The separation of timescales breaks the loop: CC reacts every few milliseconds and handles fast fluctuations, while TE recomputes every few minutes on averages. From TE's view CC is “already settled”; from CC's view the routes are fixed.
Why TE needs its own objective: take the 12 Gb/s example and compare the splits 8/4 and 9/3. Both fit (utilizations 0.8 & 0.8 vs 0.9 & 0.6), so every sender gets its full 12 Gb/s with no loss and no queueing. The senders' utilities are identical either way, so they can't say which split is better. The operator needs a network-level goal, such as the lowest MLU, which prefers 8/4 (busiest link 0.8, not 0.9).
min ρ
s.t. Σ_p x_kp = d_k (carry each demand)
Σ_{k,p : e∈p} x_kp ≤ ρ·c_e (every link)
x_kp ≥ 0 12-Gb/s example: a/10 = (12−a)/5 → a* = 8, ρ* = 0.8
“min ρ”: make the busiest link's utilization as small as possible.
“Σp xkp = dk”: each demand must be fully carried, split over its paths however you like.
“Σ xkp ≤ ρ·ce” for every link e: add up all traffic (from every demand) whose path uses link e; it must fit within ρ × capacity. This line is what ties the demands together: they compete for the same links.
“x ≥ 0”: no negative traffic.
The solver returns the split (x) and the resulting MLU (ρ). In the 12 Gb/s example there is one demand and two paths, and the answer is the 8/4 split with ρ = 0.8.
RFC 9522 definition: TE = performance evaluation and optimization of operational IP networks, using measurement, characterization, modeling, and control of traffic. Objectives come in two classes. Traffic performance: loss, delay, delivered throughput, service commitments. Resource use: avoid persistent hotspots, use alternate capacity, preserve headroom, minimize cost (leased or transit links). A “best” routing is best only for a stated objective. Policy can remove otherwise useful paths.
Control surfaces: traffic management (limit a sending rate / reject requests, i.e. admission), routing (move demand), resource constraints (reserve headroom, exclude paths). Which ones you have depends on the operator's authority.
3.3 The practical TE loop: five problems
| Problem | Key example from lecture |
|---|---|
| 1. Demand isn't handed to you | The R→T counter reads 10 Gb/s = A + B in an unknown mix (5+5? 8+2?). Per-link load can't reveal the matrix or how much traffic is movable (B could use idle U). And delivered rate ≠ load ≠ demand (loss later on the path). |
| 2. One split doesn't settle allocation | When demand exceeds capacity, routing alone can't fix it; someone must decide who gets less. A asks 10, B asks 8, but only 15 can cross: favor A (10, 5) or split equally (7.5, 7.5)? A policy decides. Time can help too: urgent traffic needs 12 now (8 next hour); a batch job needs 5 for one hour and may finish any time before the end of next hour. Running it now = 17 on 15 ✗; deferring it = 12 now and 8 + 5 = 13 next hour ✓. |
| 3. An allocation isn't a router config | The optimizer says “put 3 Gb/s of A's traffic on path 2”, but ordinary routers can't express that. ECMP only splits equally. Normal IP forwarding picks one next hop per destination prefix (longest-prefix match), so you can only move a whole prefix: if one prefix carries 9 Gb/s you can't move just 3 of it. You need a finer unit of traffic (e.g. MPLS trunks, §4) and router APIs that can express weighted splits. |
| 4. Feasible ≠ safe transition | Swap A (8) and B (8) on two 10 Gb/s paths: either whole move gives 16/10. With 2 Gb/s headroom: move 2 of A, then 2 of B, repeated 4×. Confirm each move before the next. The first move consumes headroom; the second restores it. |
| 5. Verify & adapt | Rerouting B via U black-holes B→T because U has a stale “discard T's prefix” route (an old rule could also create a loop). Check the candidate config before rollout, then measure loads, rate, loss, and delay after. |
3.4 Scale forces trade-offs
| Design choice | Benefit | Cost |
|---|---|---|
| Aggregate traffic | fewer rules | coarser control |
| Plan less often | less computation | staler decisions |
| Sample telemetry | less data | less visibility |
| Batch updates | fewer operations | larger transition steps |
| Design question | Choices | Trade-off |
|---|---|---|
| Where does the input come from? | historical pattern (e.g. yesterday's daily cycle) / live measurement | predictable peaks are planned well / sudden changes are caught |
| When is the plan computed? | offline (ahead of time) / online (continuously) | more time to search for a good answer / fresher decisions |
| Who decides? | centralized / distributed / hybrid | globally coordinated (but slower, a logical single point of failure) / fast local reaction (but suboptimal) / both |
| What does the decider see? | local / global information | cheap telemetry / network-wide visibility |
| Does it watch the result? | open loop / closed loop | simple / adapts to what actually happened, but risks flapping (oscillating back and forth between two routings) |
- Utilization of each path and MLU under shortest-path routing; under ECMP.
- The min-MLU split and MLU*.
- Demand becomes 55 Gb/s. What can TE do?
- Give the professor's main reason why minimizing peak utilization is a good TE objective.
Show solution
- Shortest path: P1 30/10 = 300% (P2 0%). ECMP: 15/10 = 150% on P1, 15/40 = 37.5% on P2.
- Equalize: x/10 = (30 − x)/40 → 40x = 300 − 10x → x = 6 on P1, 24 on P2; MLU* = 0.6 (= 30/50, split ∝ capacity).
- 55 > 50 (the cut), so no routing fits. TE can't create capacity. It can carry 50 (with MLU 100%, no headroom), and admission control / rate limits / congestion control must cut demand.
- Demand changes at RTT timescales, but TE reacts in seconds to minutes. Minimizing the max utilization maximizes headroom on every link to absorb spikes until the next TE cycle (with CC handling the very short term).
Show solution
- What are the possible (A, B) demand pairs?
- Why does this matter for TE?
- Why is “link load” also not the same as “delivered rate”?
Show solution
- Any a + b = 9 (e.g., 4.5/4.5, 8/1, 2/7). The counter can't separate them.
- TE needs the traffic matrix to know how much is movable: only B's traffic could use the path via U. Hence per-source measurement (sFlow, host reports) and rules or contracts at ingress.
- Load on one link may later be lost on a congested downstream link, so load ≠ delivery. And demand may exceed load if CC already throttled the senders.
- What happens if A moves entirely first?
- Give a safe sequence of moves. What is the minimum number of moves?
- What does the plan require from the network and the controller?
Show solution
- P2 = 7 + 7 = 14 Gb/s > 10 (transient overload; same if B moves first).
- Headroom = 3 per path, so move ≤ 3 at a time and alternate:
6 moves. That is the minimum, since each aggregate needs ⌈7/3⌉ = 3 moves.move P1 P2 start A7 = 7 B7 = 7 1. A −3 → P2 A4 = 4 A3+B7 = 10 2. B −3 → P1 A4+B3 = 7 A3+B4 = 7 3. A −3 → P2 A1+B3 = 4 A6+B4 = 10 4. B −3 → P1 A1+B6 = 7 A6+B1 = 7 5. A −1 → P2 B6 = 6 A7+B1 = 8 6. B −1 → P1 B7 = 7 A7 = 7 - Traffic must be divisible into smaller units (split aggregates), there must be spare headroom, and the controller must confirm each move before the next (switches update asynchronously).
- Run the batch in hour 1: utilization? Defer it to hour 2?
- If the batch may be spread over both hours at any rates, what schedule minimizes the peak utilization?
Show solution
- Hour 1: 22/20 = 110% ✗. Deferred: hour 1 16/20 = 80%, hour 2 18/20 = 90% ✓.
- Equalize: 16 + b₁ = 12 + b₂ with b₁ + b₂ = 6 → b₁ = 1, b₂ = 5; both hours 17/20 = 85%. TE becomes a scheduling problem (when, not just where).
- The controller aggregates both classes into one demand and routers use ECMP. Link loads, MLU, and RPC on the slow path?
- Find a configuration that meets the policy. What is the best MLU it can reach? Can you get it by just changing how the aggregate is split? What information and forwarding state does it need?
- RPC grows to 12 Gb/s. Redo (a) and (b).
Show solution
- Total 14 → 7/7, MLU = 0.7. ECMP splits each class in half, so 2.5 Gb/s of RPC rides the slow path (violates policy).
- RPC 5 on fast. Replication x on fast, 9 − x on slow. min max((5+x)/10, (9−x)/10) → x = 2: fast 7, slow 7, MLU = 0.7 with the policy met. No, re-splitting the aggregate can't do it: routers must classify traffic (e.g., DSCP or class labels), the controller needs per-class demand, and routers need per-class forwarding rules / split weights (more state).
- Total 21 > 20 = cut: infeasible for any routing. Aggregate ECMP: 10.5/10.5 → MLU 1.05 (overload), with 6 RPC on slow. Policy-respecting: RPC can only use fast (10 < 12), so admit/rate-limit RPC to 10 (or send 2 on slow and violate the policy). Replication 9 on slow → MLU 1.0 / 0.9. TE can't create capacity; admission or CC handles the excess.
Show solution
Correct: A, D, F
- A ✔ — This timescale separation is what breaks the NUM↔TE feedback loop.
- B ✘ — It's about headroom. Min-MLU often raises mean latency (Meta example: 10 ms vs 7.5 ms).
- C ✘ — TE fixes inefficient mapping, not insufficient resources.
- D ✔ — Hash-based per-flow splitting ignores flow sizes and path capacities.
- E ✘ — Transient states can overload (swap example) or black-hole and loop.
- F ✔ — Traffic management, routing, and resource constraints.
4 · Mechanisms that make TE possible: MPLS and SDN
Lecture 12. The professor's warning: MPLS and SDN are not separate worlds. Real networks are hybrids: a centralized controller programs an MPLS data plane.
4.1 MPLS: forward on a label, not on the IP prefix
- LSR (label-switched router) forwards using only the label. Its MPLS table is separate from the IP forwarding table (the FIB, “forwarding information base”), so its MPLS decisions can differ from what IP routing would do.
- Why: ① fixed-length exact-match lookup is faster in hardware than longest-prefix match. IP lookup must find, among many overlapping prefixes (10.0.0.0/8, 10.1.0.0/16, 10.1.2.0/24…), the most specific one that matches; a label is simply an exact key into a table. ② Flexibility: traffic to the same destination can take different paths, chosen by source, ports, QoS class, or ingress port (destination-based IP can't do this). ③ Fast reroute: backup paths are precomputed.
- LSP (label-switched path): ingress classifies and pushes a label → transit LSRs swap labels → egress (or the penultimate hop) pops. Labels are local to each router, so “10” at R3 has nothing to do with “10” at R1. Labels can be stacked (nested virtual networks, source routing).
- Signaling = how routers learn which labels to use. Distributed version: OSPF and IS-IS (link-state routing protocols, which already flood every link's status to every router) are extended (“-TE”) to also flood each link's bandwidth and how much is already reserved. With that map, the ingress computes a path that has room, then sends an RSVP-TE message along it: each router on the way reserves the bandwidth and tells its upstream neighbour which label to use. Today this is usually centralized: a controller, or a PCE (path computation element, a server whose job is computing paths), computes the paths and programs the routers.
Units of traffic: packets/flows → forwarding equivalence class (FEC, forwarded the same way) → traffic trunk (FEC + TE attributes: bandwidth, burst, priority, preemption, resilience, path preference, policing) → LSP over the physical links.
Constraint-based route selection (CSPF): ① trunk request (e.g., A→F, 6 Gb/s, exclude RED) → ② prune links with insufficient allocatable bandwidth or excluded colors → ③ run shortest path on what remains and instantiate the LSP. Trunks placed one at a time are order-dependent: e.g. two 6 Gb/s trunks and two 10 Gb/s paths, where trunk X can use either path but trunk Y can only use path 1. Place X first on its shortest path, path 1, and Y no longer fits; place Y first and both fit. So several trunks may need joint optimization. Resilience: a 100 Gb/s trunk over three 400 Gb/s links that must survive one link failure → reserve 50 on each (any two survivors carry 100). General rule: with k equal links and up to f failures, the worst case leaves k − f links, so each must hold D/(k − f); here 100/(3 − 1) = 50, i.e. 150 reserved in total for a 100 Gb/s trunk. That is wasteful, so operators oversubscribe (committed sum > capacity, e.g., 450 on 400) because a worst case on every trunk at once is unlikely. Another way to avoid waste (Q&A): program the backups into the TE solution as an ordered preference, e.g., “S→D traffic uses link 1 first; above 50 Gb/s spill to link 2; beyond that to link 3”, so the last link is rarely used. If backups aren't part of the TE solution, a failure has to wait for the next TE computation. TE is a feedback process: observe → decide → act → check. Reroute only when the expected benefit justifies the path change.
4.2 SDN refresher (the parts the case studies build on)
Traditional per-router control plane: every router runs OSPF/IS-IS/BGP and computes its own FIB. For TE that leaves only link weights as a knob: you can't steer u→z onto a non-shortest path without changing weights (which moves everyone else's traffic too), you can't split one destination's traffic across two paths, and you can't route two classes to the same destination differently.
- Controller components (3 layers): ① interface to apps: abstractions such as the network graph, a RESTful API, and an intent API (northbound) · ② network-wide state management (link, host, switch info, statistics, flow tables) as a distributed, robust database · ③ communication with devices (OpenFlow, SNMP: southbound).
- Flow table (generalized forwarding): match on L2/L3/L4 header fields (wildcards) → actions: forward, drop, modify (e.g., push or pop a label), send to the controller · priority disambiguates overlapping matches · counters (bytes, packets) feed TE measurement.
- Link-failure walk-through: ① switch sends an OpenFlow port-status message → ② the controller updates link state → ③ the routing app (registered callback) is invoked → ④ it recomputes routes from the graph → ⑤ flow tables are computed → ⑥ new tables are installed via OpenFlow. That takes hundreds of ms to seconds, slower than local distributed repair, which is why every case study uses hybrid control (local fast reaction + central global optimization).
- Why SDN: easier management, fewer misconfigurations, programmable table-based forwarding, centralized computation, open interfaces → faster innovation (the mainframe-to-PC analogy: vertically integrated and closed vs horizontal and open).
- SDN + MPLS TE architecture: service demand + TE policy → controller / PCE (TE database + constraint-based path computation) ← topology, capacity, telemetry; it programs the LSPs via RSVP-TE or per-hop programming; packets follow the installed LSP.
- List the MPLS header fields with sizes. What's the total?
- How many label values can one router distinguish?
- A packet carries a 3-label stack. Overhead in bytes, and as a % of a 1500-byte packet? How does a router know which label is the last?
- Give two reasons label switching helps TE beyond raw lookup speed.
Show solution
- Label 20 · Exp/TC 3 · S (bottom of stack) 1 · TTL 8 = 32 bits (4 bytes).
- 220 = 1,048,576 (a few low values are reserved). Labels are local to each router.
- 3 × 4 = 12 B → 12/1500 = 0.8%. The bottom label has S = 1.
- ① Traffic to the same destination can take different paths (by source, class, port, or ingress), which is impossible with destination-based IP. ② Precomputed backup LSPs give fast reroute. Also: separate tables let MPLS decisions differ from IP's.
R1:
video→D: push 17, out to R2 · backup→D: push 23, out to R3R2:
in 17 → swap 31, out to R4 · R3: in 23 → swap 44, out to R4R4:
in 31 → pop, out to D · in 44 → pop, out to D
- List the label each FEC carries on every link.
- Both FECs reach R4 and leave to D. Why do they carry different labels at R4, and is it a problem that R3 could also have used label 31 internally?
- The R2–R4 link fails. R2 has a precomputed backup “in 17 → swap 23, out to R3” (R2–R3 link exists). Trace a video packet.
Show solution
- Video: R1→R2 17, R2→R4 31, R4→D unlabeled (IP). Backup: R1→R3 23, R3→R4 44, R4→D IP.
- R4's incoming labels identify the LSP (and could carry different treatment). Each router owns its label space, so values are local: R3 using 31 for something on its own table is irrelevant to R4's 31.
- R1 pushes 17 → R2 swaps to 23 → R3 (which treats it like backup traffic) swaps to 44 → R4 pops → D. Fast reroute without waiting for a controller.
- Trunk T1: A→F, 6 Gb/s, exclude RED. Prune, then find the path. What would plain shortest path have picked?
- Then trunk T2: A→F, 5 Gb/s, no color constraint, placed after T1 is reserved. Path?
- Separate network: A→F via top path (cost 2, 10 Gb/s) or bottom path (cost 3, 6 Gb/s). Trunks X = 6 and Y = 8 Gb/s, each a single LSP. Place them X then Y, then Y then X. Lesson?
Show solution
- Prune B–F (4 < 6) and A–C (RED). Remaining A→F routes: A–B–D–F cost 1+1+2 = 4, A–D–F cost 3+2 = 5. Choose A–B–D–F and reserve 6 on each link (A–B 4 left, B–D 3, D–F 3). Plain shortest path: A–B–F or A–C–F (cost 2), which violate bandwidth or color.
- Prune links with < 5 left: B–F (4), A–B (4), B–D (3), D–F (3). Remaining: A–C (8), C–F (8), A–D (9). Path A–C–F (cost 2).
- X then Y: X takes top (10 → 4 left). Y = 8 fits neither top (4) nor bottom (6), so it fails. Y then X: Y top (→ 2 left), X bottom (6) ✓. Greedy per-trunk CSPF is order-dependent; several trunks need joint optimization.
- Reserve on one link only: what happens on a failure?
- Must survive any single link failure without recomputation: per-link reservation and total reserved?
- Any two failures?
- How do operators keep this from wasting capacity?
Show solution
- If that link fails, the trunk has no path until the controller recomputes.
- Survivors (3) must carry 120 → 40 per link, total 160 (+33%). In general D/(k−f) per link.
- 120/2 = 60 per link, total 240 (2×).
- Oversubscription: the sum of commitments exceeds capacity (e.g., 450 committed on 400), betting that not every trunk's worst case happens at once. Or prioritized/weighted backup groups (use link 2 only when link 1 is full).
- Least-cost u→z path and cost?
- The operator wants u→z on u–v–w–z. Propose weight changes that make it the unique least-cost path; check the closest competitors.
- What are the side effects, and what two TE wishes can't destination-based link-state routing express at all?
Show solution
- u–x–y–z = 1+1+2 = 4.
- u–v–w–z costs 10. One choice: u–x = 20, y–z = 20, u–w = 20. Competitors: u–v–x–y–w–z = 2+2+1+1+5 = 11, u–v–x–w–z = 12, u–v–w–y–z = 26 → u–v–w–z = 10 unique ✓ (any change of this kind works if you check all paths).
- Weights are global: they move all traffic using those links (e.g., x→z now changes too). With destination-based routing you can't split u→z over two paths (unless costs tie exactly, for ECMP's equal split), and you can't route two classes to the same destination differently at w. MPLS or SDN fixes this.
| prio | match | action |
|---|---|---|
| 30 | src = 10.1.2.3 | send to controller |
| 20 | src = 1.2.*.* | drop |
| 10 | dst = 3.4.*.* | forward(2) |
| 0 | * | forward(1) |
Show solution
Show solution
Correct: B, C, D, G
- A ✘ — The professor stressed they are not separate. Hybrids are the norm.
- B ✔ — The SDN + MPLS TE architecture slide.
- C ✔ — Hence hybrid designs with local fast reaction.
- D ✔ — Slide: “defines what is controllable, what is not.”
- E ✘ — It is replicated, with leader election. The single point of failure is logical (bugs, bad config).
- F ✘ — Labels are local; LSRs swap them hop by hop.
- G ✔ — The MPLS signaling slide: OSPF-TE/IS-IS-TE flood link and reserved bandwidth, and RSVP-TE installs the LSP.
- H ✘ — Reversed. The switch sends an OpenFlow port-status message; the controller updates link state, calls the routing app, recomputes, and installs new flow tables via OpenFlow.
5 · Meta's Express Backbone (EBB)
Lectures 12–14 · HW2 Q5. The professor's framing: Meta = the nitty-gritty details of a hybrid design (Google = nuanced allocation/fairness, Microsoft = failure handling).
5.1 Two networks, four planes
| Journey | Network | What matters |
|---|---|---|
| DC → Internet user (via PoP / ISP) | Classic Backbone (CBB) | global reach, user experience, externally compatible, so costly ISP-grade gear |
| DC → DC (replication, internal transfers) | Express Backbone (EBB) | huge, fast-growing internal traffic; Meta controls both ends, so it can customize and cut cost |
Separating them keeps large internal bursts from hurting user traffic and allows different routing and ops choices. (Google: B2/B4. Microsoft: CORE/SWAN.) All three started with cheap, less reliable internal networks that became critical, then reliable, and are now being merged. Meta was IPv6-native from day one (Google's later v4→v6 migration was a multi-year effort).
5.2 Architecture: who does what
- Estimating demand: the best short-term predictor of demand is current demand. Hosts could report per-TCP-flow counters (Google's approach), but switches keep no per-flow state at Tb/s line rate. sFlow: the router's forwarding chip (ASIC) copies the header of 1 of every N packets (e.g. 1 in 10 000) plus interface byte counters, the switch CPU agent sends sample records to a collector, and the collector estimates bytes per (DC pair, class). Sampling also lets the router run a simple counter instead of per-packet work, and report a tiny fraction of the traffic (a router carrying 1 Tb/s doesn't send 1 Tb/s to the collector). How to pick N (Q&A): methodically, from the traffic distribution and the confidence interval you want; in practice standards often settle on a conventional “magic number”. Sampling loses little because traffic is heavy-tailed (Pareto): a few heavy hitters carry most of the bytes, and those are what TE cares about. Sampling at ingress edge routers is enough to build the full matrix: every DC-to-DC byte enters EBB exactly once, at the edge router next to its source DC, so counting there counts each byte once; the destination DC comes from the sampled header. Scaling up: if 300 sampled packets in a minute were DC1 → DC2 gold, with N = 10 000 and 1 500-byte packets, the estimate is 300 × 10 000 × 1 500 B ≈ 4.5 GB per minute ≈ 0.6 Gb/s.
- Open/R is a distributed routing platform (not just a protocol) that Meta runs on every router. It replaces OSPF/IS-IS and lets TE applications add their own information. Its parts, as on the slide: Spark discovers neighbours (hello messages); LinkMonitor tracks link health and measures each link's RTT; KvStore is a key-value store replicated across all routers, holding adjacencies and prefixes; Decision computes routes from it; FIB programs them into the hardware. KvStore is eventually consistent: different routers may briefly see different versions, but they converge. That is fine for link state (like a “likes” counter that is briefly off by one) but not for something like a bank balance.
- Two-stage failure response: local recovery (LSP agent activates a preinstalled backup, hundreds of ms) → global reoptimization in a later controller cycle. Reachability after a failure doesn't guarantee capacity: several rerouted demands may pile onto the backup.
5.3 TE policy: multicommodity flow and service classes
commodity k = (source DC, destination DC, class), demand d_k, candidate paths P_k
decision x_kp = Gb/s of k on path p
carry Σ_p x_kp = d_k
share links Σ_{k,p∋e} x_kp (+ burst margins) ≤ U · c_e ← couples the demands
objective min U (MLU) — or min Σ cost·x (latency) for gold
In words: a commodity is one “kind” of traffic that must get from A to B (here: one DC pair in one service class). “Multicommodity flow” means many such demands share the same links. The decision is how many Gb/s of each commodity go on each of its allowed paths. The “carry” line says each demand is fully routed; the “share links” line adds up every commodity on each link and keeps it under the target, which is what makes the demands compete. A burst margin is extra capacity set aside on top of the average rate so short bursts of high-priority traffic don't overflow the link.
| Short/long split of 12 Gb/s (short 10 Gb/s, 5 ms; long 5 Gb/s, 20 ms) | short util | long util | feasible? |
|---|---|---|---|
| 12 / 0 | 120% | 0% | no |
| 6 / 6 | 60% | 120% | no |
| 10 / 2 (min latency) | 100% | 40% | yes: MLU 100%, mean latency (10·5+2·20)/12 = 7.5 ms |
| 8 / 4 (min MLU) | 80% | 80% | yes: MLU 80%, mean latency (8·5+4·20)/12 = 10 ms |
Constraints say what is possible; the objective chooses what is preferred.
HPRR: Meta's heuristic (HW2 Q5, explicitly examinable)
Solving the exact LP with millions of variables every minute is too slow. Heuristic Path ReRouting reroutes one LSP at a time.
It accepts a reroute only if the max utilization along the new route (after the move) is lower than the max along the current route (before).
Candidate routes come from Dijkstra with exponential link cost w_e = exp[α(u′_e/u* − 1)] (u′ = the link's utilization if the LSP uses it). The current route is also a candidate.
| Symbol | Meaning |
|---|---|
| LSP | a fixed-size chunk of one demand, pinned to one path (e.g. an 8 Gb/s demand carried as four 2 Gb/s LSPs) |
| u′e | utilization link e would have if this LSP were moved onto it: (current load of e without this LSP + LSP rate) / capacity |
| u* | target utilization, a threshold the operator picks (HW: 0.855) |
| α | how sharply cost rises past u* (HW: 66.4) |
| we | the link's cost for Dijkstra; route cost = sum of its links' w |
HW Q5.3 in these terms: one unsplittable 6 Gb/s LSP from S to D; background traffic is 3 Gb/s on the direct link and 2.95 on each of the two links via M (all 10 Gb/s). Direct: u′ = (3 + 6)/10 = 0.9 → w = 32.9. Via M: each link u′ = (2.95 + 6)/10 = 0.895 → w = 22.3, two links → route cost 44.7. Dijkstra picks direct (32.9 < 44.7) even though via M has the lower MLU (0.895 < 0.9). The sum over links charges the 2-hop route twice: the hop bias below.
- LSP granularity gap: 8 Gb/s over links of 10 and 6. Arbitrary split 5/3 gives MLU 0.5. Four 2-Gb/s LSPs force splits in {0,2,4,6,8}, so the best is 6/2 → MLU 0.6. More, smaller LSPs close the gap but cost more forwarding state and computation.
- Local optimum: moving one LSP at a time can get stuck where only a swap (two simultaneous moves) helps. HW Q5.2: link L carries 4 Gb/s of fixed background plus A (6); link R carries B (4); both 10 Gb/s. Current max = 10/10 = 1.0. Move A to R: R becomes 10/10 = 1.0, not lower, so rejected. Move B to L: 14/10 = 1.4, rejected. HPRR is stuck at 1.0, yet moving both (A → R, B → L) gives L = 8, R = 6, MLU 0.8. Fix: consider pairs of moves, at a higher combinatorial cost (still not globally optimal).
- Sum-of-costs bias: a 2-hop route pays two link costs, so HPRR can prefer a 1-hop route with a higher MLU. That is deliberate (longer isn't always better for Meta). Fix: use the route's bottleneck (post-move MLU) as the metric. That doesn't fix the joint-optimization issue.
5.4 Route programming: segment routing, Binding SIDs, versioned updates
- Baseline (install per-path rules at every router): many forwarding updates per path change.
- Static labels + source routing: every router gets fixed label→interface rules at startup, and the controller only changes the label stack at the source (headend). A packet's path is in its header.
A segment (label) can name a node (“get to router D by its shortest path”) or an adjacency (“leave through this specific link”). Slide example: A pushes
[16104, 203]. 16104 = node SID of D, so the packet goes A → B/C → D on shared shortest-path entries (popped one hop early: PHP). At D, 203 = adjacency SID for the D → E link. - Limit: EBB hardware reportedly handles a stack depth of 3 (lookups must stay shallow in the header; hashing behavior). The slide's 5-hop example needs 5 labels, so longer paths need a Binding SID: a label naming a programmed continuation at an intermediate router. A dynamic SID per (site pair, class) can point to a next-hop group, giving weighted ECMP across several continuations, i.e., a path bundle.
Without this, “eventual consistency” updates (send all messages, let them land whenever) create transient black holes (A switches before J has its rule) or loops (an old J→A rule). Meta: one version bit in the packet (it alternates 0/1, since only two versions coexist), and the source flips only after the transaction is acknowledged by all routers. This is cheap, though not the most efficient option. Google instead stages updates (e.g., downstream first) so every intermediate state is safe. Side effect: mid-update, packets of one flow may take different paths, so the sender sees an RTT change that isn't congestion.
5.5 Capacity planning uses the same TE model
Basic TE: given capacities, choose rates. Planning: choose capacities so that TE stays feasible for every demand matrix in a set H and every failure in a set S (cˢ = surviving capacity). Building fiber takes months or years, so the forecast comes from compute commitments (GPUs, CPUs, storage being bought per site), not from product teams' guesses.
Traffic between groups must cross the cut links. It is enough to check simple cuts (single or few links) rather than all exponentially many. Scale: several thousand machines; 1 M routing scenarios in < 3 min; full plan for 300+ nodes and 1000+ links in < 6 h (via decomposition and parallelism).
Left open at the end of the Meta case (answered by Google): enforcing tenant shares under unpredictability, sharing capacity across planes, solving huge LPs efficiently.
- The minimum-latency allocation: split, MLU, mean fixed latency.
- The min-MLU allocation: split, MLU, mean latency.
- Which objective does Meta use for gold, and which for silver/bronze? Why restrict silver/bronze to K-shortest paths?
Show solution
- Fill the short path first: 10 / 5. Utilizations 100% / 50% → MLU 1.0. Mean latency (10·4 + 5·16)/15 = 120/15 = 8 ms.
- Equalize: 7.5 / 7.5 → MLU 0.75. Mean latency (7.5·4 + 7.5·16)/15 = 10 ms. Same topology, demand, and constraints; a different “best”.
- Gold: shortest path (cost = measured RTT), with a protected burst margin. Silver/bronze: min utilization, restricted to K-shortest paths so load balancing never picks absurdly long paths. K-shortest limits the choices; the objective sets the split.
- Gold placement and what's left.
- Silver placement and MLU.
- Bronze placement and the final MLU.
- Later, bronze actually sends 9 Gb/s on its configured paths. What happens, and what mechanisms protect gold and silver? What does Meta add so bronze owners don't just see mysterious loss?
Show solution
- Gold 6 + margin 2 = 8 reserved on short; short has 2 left, long 10.
- Silver s on short, 8 − s on long: max((8+s)/10, (8−s)/10) is minimized at s = 0 → silver 8 on long; both links at 80% → MLU 0.8.
- Bronze b on short: max((8+b)/10, (8+2−b)/10) → 8 + b = 10 − b → b = 1: 1 short, 1 long, both 90%.
- Bronze far exceeds its budget and shares queues with gold and silver. Routers use strict-priority queues (gold dequeued first) plus buffer carving (reserved buffer per class) so bronze can't fill the memory. Bronze sees the loss. Meta adds entitlements (guaranteed bandwidth per service) with host-side rate limiting when the network has no spare capacity, so a bronze service knows exactly what it was promised.
- 9 Gb/s S→D over links L (10 Gb/s) and R (5 Gb/s), no background. Best MLU with arbitrary splitting? With the demand carried by 2, 3, or 4 equal LSPs?
- Links L and R, both 10 Gb/s, with fixed background L = 1, R = 3. Unsplittable LSPs A = 7 (currently on R) and B = 5 (currently on L). Evaluate every single-LSP move. Where does HPRR end? Is it optimal?
- Propose a fix for (b) and its cost.
Show solution
- Arbitrary: x/10 = (9−x)/5 → x = 6 → MLU 0.6. 2 LSPs of 4.5: x ∈ {0, 4.5, 9} → best max(0.45, 0.9) = 0.9. 3 LSPs of 3: x = 6 → max(0.6, 0.6) = 0.6 (optimal). 4 LSPs of 2.25: x = 6.75 → max(0.675, 0.45) = 0.675. Finer granularity approaches the optimum but isn't monotone; what matters is whether the LSP grid hits the optimal split. More LSPs = more forwarding state and computation.
- Start: L = 1 + 5 = 6 (0.6), R = 3 + 7 = 10 (1.0). MLU 1.0.
Move A → L: after, L = 1 + 5 + 7 = 13 → 1.3, not < 1.0 (A's current max) → reject.
Move B → R: after, R = 3 + 7 + 5 = 15 → 1.5, not < 0.6 → reject.
HPRR is stuck at 1.0. Optimal: swap, A on L (1 + 7 = 8) and B on R (3 + 5 = 8) → MLU 0.8. - Consider moving two LSPs at a time (swaps). That reaches 0.8 here, but evaluation cost grows combinatorially and it still doesn't guarantee a global optimum. (The joint LP would be optimal but slow.)
- Cost of the direct route and of the route via M. Which does HPRR pick?
- MLU of each choice. Which is better?
- Explain the discrepancy and propose a fix. Does your fix solve the problem in 5.3(b)?
Show solution
- Direct: u′ = (5+4)/10 = 0.9 → w = exp[50(0.9/0.8 − 1)] = exp(6.25) ≈ 518. Via M: u′ = (5+3.9)/10 = 0.89 per link → w = exp[50(0.89/0.8 − 1)] = exp(5.625) ≈ 277.3 each → route cost ≈ 554.5. HPRR keeps the direct route.
- Direct: MLU = 0.9. Via M: max(0.89, 0.89, 4/10) = 0.89, slightly better.
- Summing link costs penalizes the 2-hop route (two exponentials), even though its bottleneck is lower. That is deliberate in Meta's setting (a longer route with slightly lower MLU isn't always better), but suboptimal for pure MLU. Fix: use the route's bottleneck (max post-move utilization) as the path metric (a minimax/widest-path Dijkstra). This does not fix 5.3(b): that one comes from moving one LSP at a time, not from the per-LSP route search.
Show solution
Correct: A, B, D, E
- A ✔ — v1 packets reach J before J has a v1 rule, so they are dropped.
- B ✔ — All v1 rules are ready before any v1 packet exists. The order among the preparation steps doesn't matter.
- C ✘ — v0 packets already in flight still need M and N's v0 rules. Remove them only after the old packets drain.
- D ✔ — Version alternation.
- E ✔ — The lecture made this connection to congestion control.
- Estimate that cell of the traffic matrix in Gb/s.
- Why doesn't sampling lose the information TE needs?
- Why not keep a per-flow byte counter in the switch ASIC? Where must sampling happen to build the full DC×DC matrix?
Show solution
- 5,000 × 1,000 = 5×10⁶ packets/s × 1,500 B × 8 = 60 Gb/s.
- Traffic is heavy-tailed (Pareto): a few heavy hitters carry most bytes, and TE decisions are about those big aggregates. At billions of packets/s, 1-in-N still yields many samples.
- Switches keep no per-flow state at Tb/s (sub-ns per packet); per-packet counters plus reporting are too expensive. Sampling at the ingress edge routers is enough, since every DC-pair flow enters through one.
- How many numbers does a pipe model need for n = 3 sites? For n = 50? A hose model?
- Largest possible A→B demand allowed by the hose?
- For the cut separating {A} from {B, C}: the most traffic that can leave A across it, and the most that can enter A.
- Why is the hose model better for capacity planning months ahead? What does Meta's “segmented hose” add?
Show solution
- Pipe: n(n−1) = 6 (n = 50: 2,450). Hose: 2n = 6 (n = 50: 100).
- min(EA, IB) = min(10, 8) = 8.
- Out of A: min(EA, IB + IC) = min(10, 16) = 10. Into A: min(IA, EB + EC) = min(8, 10) = 8.
- Pairwise forecasts are brittle (does B's growth go to A or to E?). A hose keeps per-site totals but lets the pair mix change ("A sends 10 to B today and to C tomorrow"), and the plan must be TE-feasible for all of them under the failure set. Segmented hose: a few large allocations per DC for known heavy pairs, which shrinks the space of matrices to check.
- Can SRC encode it alone? How many Binding-SID routers are needed, and which (one valid choice)?
- When only the R5→DST portion changes, which routers need new state?
- Why is static-label source routing better than installing per-path rules at every router?
Show solution
- No (7 > 3). Each non-final stack covers 2 hops + 1 BSID; the final stack covers 3 hops. 2 + 2 + 3 = 7 → 2 Binding SIDs: SRC [→R1, →R2, BSID@R2]; R2 [→R3, →R4, BSID@R4]; R4 [→R5, →R6, →DST].
- Only the router owning the relevant BSID (here R4; R2 if the change reached earlier). Transit routers keep their fixed label→interface rules.
- Every path change would otherwise require updates at every router on the path (many forwarding-state updates and consistency issues). With static labels, only the headend and a few BSID routers change. A dynamic SID per (site pair, class) can also name a next-hop group (a weighted bundle of continuations).
Show solution
Correct: A, C, F
- A ✔ — Phased releases and separate failure domains.
- B ✘ — Physical plane ≠ control plane ≠ data plane ≠ traffic class. The slide calls this out.
- C ✔ — Two-stage failure response.
- D ✘ — Several rerouted demands can compete for the backup's links.
- E ✘ — It is eventually consistent.
- F ✔ — Priority order; gold uses shortest paths with RTT from LinkMonitor.
6 · Google: intent, Orion, bandwidth functions, B4, BwE, dSDN
Lectures 14–16 · HW2 Q4. Google's “DNA” is expressing desired behavior: intent, and fairness via bandwidth functions. B4 = the internal inter-DC WAN (sites become vertices, inter-site capacity becomes edges); B2 = the user-facing one.
6.1 Intent-based networking (RFC 9315)
Intent = a declarative statement of goals and outcomes: what to achieve, not how (like SQL, not Python). It separates the TE/ops people from device configuration (what the RFC calls “nerd knobs”).
| Level | Example | Still undecided |
|---|---|---|
| Intent | “Keep ≥ 8 Gb/s for service S while link e is drained for maintenance” | which paths, splits, device rules, update order |
| Policy | “Prefer path P1 when it has capacity” | the allocation under current conditions |
| Configuration | “Install these next hops and weights” | nothing; the device must realize exactly this state |
Examples of intent: steer traffic from geography X away from geography Y unless the destination is in Y · avoid vendor V's equipment for customer C even at reduced service · smart-city signal traffic on dedicated, redundant, non-fate-sharing slices. Non-examples: configure an interface's IP (configuration) · “alert when utilization > threshold” (a rule) · “deny P1 unless from P2” (an access policy tied to prefixes; if the prefixes change, the “intent” breaks).
Unwrapping an intent means making explicit its traffic scope (S, A→C), required service (8 Gb/s when S offers that much), maintenance scope (no forwarding on e), failure assumptions, and preferences (shorter paths). Lifecycle: Interpret → Check & plan (feasible?) → Fulfill (paths, splits, host limits, update order) → Assure (observe) → Respond (repair, re-plan, or report that the contract can't be met). Intents can be infeasible (8 Gb/s across a 6 Gb/s cut) or conflicting (two mandatory 8 Gb/s services on one 10 Gb/s bottleneck). Then identify the conflict and ask for a changed contract, a different maintenance plan, or more capacity.
6.2 Orion: Google's SDN controller (per domain)
- Pub-sub (publish–subscribe) = components announce changes to a shared store, and whoever cares has subscribed and gets notified. Nobody needs to know who else is listening.
- Reconciliation works like a thermostat: compare desired with actual, act to close the gap, check again. If a switch reboots and loses a rule, the Flow Manager sees “desired has rule X, observed doesn't” and reinstalls it, with no special recovery code.
- NIB as pub-sub: components subscribe to state changes. The alternative, the NIB invoking registered callbacks, would make the NIB aware of every reaction and turn it into a bottleneck that is hard to reason about.
- Reconciliation at every layer: desired state moves down, observed state moves up, and each controller acts to reduce the difference. This repairs drift, e.g., rules missing after a restart.
- A route request is a sequence of state changes: ① Request: an app writes a route intent (“prefix P reachable via these ports”) into the NIB → ② Resolve: the Routing Engine (subscribed) computes flows and node dependencies → ③ Realize: the Flow Manager programs switches → ④ Report: observed state confirms, with acks back up the chain.
- Intent depends on the layer: service contract → global TE choice (aggregate over site paths and splits) → domain routing (switches) → switch programming (entries, next-hop groups).
6.3 Sharing policies, then bandwidth functions
With source control (Google also controls the sending hosts, so it can cap how fast each app sends), TE also chooses the admitted rate r_i ≤ d_i: how much of app i's demand di is let into the network, not just where it goes. That needs a language for how to share, even within one class. The slide's bar chart splits one 8 Gb/s link three ways: equal 4 / 4, weighted + capped 6 / 2, priority to app 2 0 / 8. Same physical limit, different policy. The whiteboard example (two apps on a 10 Gb/s link):
| Policy | Demands 8 and 2 on a 10 link | Work-conserving? |
|---|---|---|
| Equal split with hard rate limits (“work-conserving” = never leaves capacity idle while someone still wants it) | 5 each, but app 2 only uses 2 → 5 / 2, so 3 is wasted | No (what ISPs do; bad in a private network you own) |
| Max-min fair (water-filling) | 8 / 2: the small demand (2) is satisfied first, the rest (8) goes to the other | yes |
| Weighted (e.g., WRR queues 2:1) | by weights, leftovers redistributed | yes (the work-conserving WRR variant) |
| Strict priority | high first | yes |
Real policies are hierarchies (Q&A). At the root: a few classes with strict priority between them, often softened by minimum guarantees (strict only beyond some allocation). Inside each class the split continues, e.g., Instagram and Facebook Marketplace are both business-critical, but Instagram gets a guarantee because it is far more bandwidth-hungry. The hierarchy is global; its configuration is nuanced. Bandwidth functions are Google's language for expressing exactly this. (A vertical bandwidth-function segment would mean infinite priority; you can write it mathematically but it makes no practical sense.)
Analogy: pouring water into differently shaped glasses connected at the bottom, so the water level (s) is the same in all of them. A wide glass (steep curve) holds more at the same level; a glass that is full (flat part, the cap) takes no more; you stop pouring when you run out of water (capacity C).
Lecture numbers (App1 = min(3s, 6), App2 = min(s, ·)): C = 4 → s = 1 → (3, 1): both unsatisfied, so the 3:1 weight shows in the rates. C = 8 → s = 2 → (6, 2): App1 hits its cap. C = 12 → s = 6 → (6, 6): the extra goes to App2. A function whose slope changes (e.g., App1 gets its first 4 Gb/s with strict priority, then App2 grows faster) expresses policies that no single fixed weight ratio can, even work-conserving. That is the punchline of HW2 Q4.
Freezing at other bottlenecks, and routing freedom
A group is frozen once any link on its path is full (or it hits its cap). The others keep growing. The routes decide where growth stops, and TE can change the operating point (both cases carry 8 Gb/s on A–B).
Aggregation: add heights at the same s
Parent P = child1 + child2 (add vertically, never add the s coordinates). Every bend has a child-level explanation: slope 4 while both grow, slope 1 after child 1 caps, slope 0 when everyone is satisfied. Decompose: read the parent backward (allocation → local s), then read each child forward at that s. Example: parent gets 11 → s = 5 → children (6, 5). Aggregates keep the policy information that a single total-demand number would lose. Solve a small problem on aggregates, then split it locally (and distributed) to children.
6.4 The B4 allocation algorithm (waterfill over paths)
Goal: max-min fairness in fair-share coordinates. Raise the smallest shares first, and keep raising the groups that can still grow. Each flow group (FG) uses its cheapest path first. When a link on that path fills, the group's rate at that point stays on the filled path and further growth spills to its next path in cost order. A group freezes when it hits its demand cap or has no path with spare capacity. Lecture example (directed links; cost 1 per link, except A–D costs 10):
The two groups' bandwidth functions (read from the slide's plot): FG1 (A→B) = 11s up to s = 1.5 (16.5 Gb/s), then slope 1 up to its cap of 20 at s = 5. FG2 (A→C) = s/2 (cap 10). FG1 is far more important at first (weight 11 vs ½).
② A–C fills: A–C now carries FG1's extra (B₁(s) − 10) plus all of FG2 (B₂(s)). Set (B₁(s) − 10) + B₂(s) = 10. Past s = 1.5, B₁ = 16.5 + (s − 1.5), so (6.5 + s − 1.5) + s/2 = 10 → s = 10/3. Then FG1 = 18.33 (10 + 8.33) and FG2 = 1.67. Both groups' next paths go through D.
③ FG1 hits its cap: at s = 5 FG1 = 20; the extra 1.67 rides A→D→C→B. FG2 = 2.5: 1.67 stays on A–C, 0.83 goes A→D→C. A–D and D–C carry 1.67 + 0.83 = 2.5 of 5. FG1 freezes (satisfied).
④ D links fill: only FG2 is still growing. A–D carries FG1's 1.67 + FG2's share; it fills when FG2's D share = 3.33, so FG2 = 1.67 + 3.33 = 5 (s = 10). FG2 freezes by the network, below its cap of 10.
| Event | s | FG1 | FG2 | What happens |
|---|---|---|---|---|
| A–B fills | 10/11 | 10 (all on AB) | 0.45 (AC) | FG1 spills to ACB |
| A–C fills | 10/3 | 18.33 (10 AB + 8.33 ACB) | 1.67 (AC) | solve (FG1(s) − 10) + FG2(s) = 10; both move to D routes |
| FG1 hits cap | 5 | 20 (+1.67 ADCB) | 2.5 (+0.83 ADC) | FG1 frozen (demand-satisfied) |
| A–D / D–C fill | 10 | 20 | 5 (1.67 AC + 3.33 ADC) | FG2 frozen by the network (its cap is 10) |
Quantization: hardware can't split 0.762
Why it's needed: the algorithm above produces exact fractions (FG1 sends 8.33/20 = 5/12 of its traffic on A→C→B). A switch splits traffic by hashing flows into a small number of equal buckets, so it can only do fractions like 0, ½, 1 (with K = 2 buckets). The allocation has to be rounded to what the hardware can express.
Switches implement splits with a finite number of equal forwarding-weight units (e.g., K = 2 → 0%, 50%, 100%). Rounding each group independently can overload a shared link: FG1 (½, 5⁄12, 1⁄12) → (½, ½, 0) and FG2 (⅓, ⅔) → (½, ½) put 20·½ + 5·½ = 12.5 Gb/s on A–C (capacity 10). B4 then greedily adjusts to fit. Final result: FG1 = 10 AB + 10 ACB, FG2 = 5 on ADC (FG1 leaves the D route, FG2 takes all of it).
6.5 BwE: the Bandwidth Enforcer (making the shares real at the sources)
| Component | Up | Down |
|---|---|---|
| Host Enforcer | task usage | task rate limits (Linux HTB, “hierarchical token bucket”, the kernel's built-in rate limiter) |
| Job Enforcer | usage per job | job budget → tasks |
| Cluster Enforcer | user demand + aggregate bandwidth functions | cluster budget → users → jobs |
| Global Enforcer | prioritized demand informs TE | cluster budgets via hierarchical network allocation (MPFA, multi-path fair allocation: the bandwidth-function waterfill of §6.4 run over the network's paths) |
TE ↔ BwE loop: TE (B4) gives paths + split weights; BwE gives prioritized demand. TE can change routing; BwE holds routing fixed and carries budgets down to sender limits. Both speak bandwidth functions. On each host, the BwE limit caps TCP. If cwnd/RTT is below the limit, congestion control is what binds; otherwise the limit binds. Benefits: predictability, protecting the network from bursts, and a clear answer to “why am I limited?” (“that's the fair share in your contract”). Costs: an enforcer on every host (a bug can cripple the fleet), complex control loops at sub-minute to minute scale, and debugging whether BwE or CC is limiting you. Delayed updates waste capacity (HW2 Q4.3): if a team's demand drops below its budget, the spare isn't redistributed until the next parent cycle. Fix: event-driven updates or demand reports, at the cost of more messages and computation.
Orion in B4: the global TE chooses paths network-wide. In each domain, a TE app turns those choices into RouteAdverts for the Routing Engine and coordinates backup and fallback. The Path Exporter summarizes physical paths and capacity for TE and BwE (failures change what it exports). Raven integrates BGP and IS-IS so central TE and conventional routing coexist. Summary slide: new abstraction (bandwidth functions) → more precise TE input · source control → division within a class + network protection · all allocation can be expressed as intent and enforced globally.
6.6 Did SDN simplify or complicate WAN operations? → dSDN (2024)
Data: of the 41 largest B4 outages over four years, 42% were control-only and 10% control-and-data, so 52% had a control-related root cause (the rest of the pie: 32% data-plane only, 16% other). What changed since SDN's birth: router vendors opened up. Operators now run their own software on router CPUs (Meta runs Open/R on every vendor's box).
| Design | Decision basis | How the path takes effect |
|---|---|---|
| Link-state shortest path (IS-IS) | topology + link costs (no TE) | each router picks its next hop |
| Central TE | global topology + demand | controller installs paths |
| dSDN | global TE computed at every router | ingress encodes the source route |
(MPLS + RSVP-TE is a distributed mechanism for reservation, but it doesn't solve the global TE problem either.) Not covered: WAN hardware and topology design, DC/WAN commonalities.
(b) For (i), only 6 Gb/s can cross the cut while e is drained. Which lifecycle stage finds this and what should happen? (c) S offers only 2 Gb/s and receives 2 Gb/s. Does this show the intent is met?
Show solution
(b) Check & plan finds it infeasible. Respond: identify and report the conflict, and ask for a changed contract, a different maintenance plan, or more capacity.
(c) No. Observing 2 Gb/s when only 2 is offered says nothing about the availability of 8. Assurance must compare offered vs delivered (service outcome), plus configuration and network-behavior checks.
Show solution
(b) Water-fill: equal share 4 → A capped at 3; remaining 9 split by B and C (4.5 each) → B capped at 4 → C gets 5 → 3, 4, 5; unused 0.
(c) Rates t, t, 2t with 4t = 12 → t = 3 → 3, 3, 6 (A exactly satisfied); unused 0.
(d) C 9, then B 3, A 0 → 0, 3, 9.
- Allocations for C = 3, 10, 13, 16 Gb/s (and any unused capacity).
- Describe the policy these curves express.
Show solution
- C = 3: s ≤ 2, 2s = 3 → s = 1.5 → (3, 0).
C = 10: s ∈ [2, 4]: 4 + 3(s−2) = 10 → s = 4 → (4, 6).
C = 13: s ∈ [4, 5]: (s) + 3(s−2) = 4s − 6 = 13 → s = 4.75 → (4.75, 8.25).
C = 16: at s = 5: 5 + 9 = 14; App2 capped; App1 = s → s + 9 = 16 → s = 7 > 6, so App1 caps at 6 → (6, 9), 1 Gb/s unused (all demand satisfied). - App1 gets strict priority for its first 4 Gb/s. Then App2 takes every increment until it has 6 (C = 10). Then they share 1 : 3 until App2's demand is met. App1's plateau at 4 is temporary; its cap is 6. No single fixed weight ratio can express this.
- Allocations at C = 6, 12, 16.
- Same capacities with non-work-conserving 2:1 sharing (reserve 2C/3 and C/3, then cap by demand). Unused capacity?
- With work-conserving 2:1 sharing.
- Construct a bandwidth-function policy that no single fixed weight ratio can implement, and show why.
Show solution
- C = 6: 3s = 6 → s = 2 → (4, 2). C = 12: s = 4 → (8, 4). C = 16: X capped at 8 for s ≥ 4; 8 + s = 16 → s = 8 > 6 → Y caps at 6 → (8, 6), 2 unused.
- C = 6: (4, 2). C = 12: (8, 4). C = 16: reserve 10.67 / 5.33 → (8, 5.33), 2.67 unused while Y still wants 0.67.
- C = 16: X 8, leftover goes to Y up to its demand → (8, 6), 2 unused (demand-limited). Same as the functions here.
- E.g., X(s) = min(2s, s + 2, 8), Y(s) = min(s, 8). C = 6 → s = 2 → (4, 2), a 2:1 ratio. C = 10 → s = 4 → (6, 4), a 3:2 ratio. The ratio depends on the operating point, so no fixed weight reproduces both (the HW answer's construction).
- Write the aggregate P(s): breakpoints and slopes.
- The parent is allocated 11 Gb/s. Each child's rate? Allocated 6?
- Why aggregate with functions instead of passing up one total-demand number (14)?
Show solution
- Add heights: slope 4 on [0, 2] (P(2) = 8) → slope 1 on [2, 8] (P(8) = 14) → flat at 14.
- 11: on the slope-1 segment, 6 + s = 11 → s = 5 → (6, 5). 6: on the slope-4 segment, 4s = 6 → s = 1.5 → (4.5, 1.5).
- A single number loses how the children should share at each level. The function preserves it, so the parent can be allocated among other aggregates and decomposed locally (and in a distributed way) without solving the full problem.
- With fixed routes, find the allocation. When does App1 freeze?
- An unused route B–D–C with 4 Gb/s becomes available to App1. New allocation?
- What does this show about TE vs bandwidth allocation?
Show solution
- App1 freezes when B–C fills: 3s = 2 → s = 2/3 → App1 = 2. App2 keeps growing until A–B fills: 2 + s = 8 → s = 6 → (2, 6).
- App1 can reach 2 + 4 = 6 beyond B, but A–B is still shared: 3s + s = 8 → s = 2 → App1 = 6 (its cap), App2 = 2 → (6, 2).
- Same curves, same total on A–B (8), but routes change where growth stops. TE picks routes to improve the max-min allocation; the bandwidth functions define the policy.
- At what s does the first link fill? Group rates then?
- Continue until no group can grow. Final rates and per-path split. Unused capacity?
- Now add A→D (2 Gb/s, cost 10) and D→C (10 Gb/s, cost 1), giving FG1 the path ADCB and FG2 the path ADC. Continue from (b). Final rates?
Show solution
- A→B fills when 2s = 6 → s = 3: FG1 = 6 (AB), FG2 = 3 (AC).
- FG1 spills to ACB: A→C load = (2s − 6) + s = 6 → s = 4. FG1 = 8 (6 AB + 2 ACB), FG2 = 4 (AC). A→C is full and both groups have no unsaturated path, so both freeze. C→B carries 2 of 6, so 4 Gb/s unused.
- Both grow over A→D: (2s − 8) + (s − 4) = 2 → 3s = 14 → s = 4.67. FG1 = 9.33 (6 AB + 2 ACB + 1.33 ADCB), FG2 = 4.67 (4 AC + 0.67 ADC). Check C→B: 2 + 1.33 = 3.33 ≤ 6 ✓.
- Load on every link (continuous).
- Round every fraction independently to the nearest multiple of 50%. Loads now?
- Fix it with 50% units without reducing either group.
Show solution
- AB 10; ACB 8.33 → AC gets 8.33 + FG2 1.67 = 10; CB 10 (8.33 + 1.67 from ADCB); AD = 1.67 + 3.33 = 5; DC 5. Every link is full.
- FG1 → (½, ½, 0): AB 10, ACB 10. FG2 → (½, ½): AC 2.5, ADC 2.5. AC = 10 + 2.5 = 12.5 > 10 ✗.
- Greedy adjustment (the slide's result): FG1 = 10 AB + 10 ACB; FG2 = 100% ADC (5). AC 10, CB 10, AD 5, DC 5 ✓.
- How much data (MB) does each team send in the interval?
- What could the network deliver under the stated policy? How much is wasted?
- Propose a mechanism change with its benefit and cost.
Show solution
- A: min(4, 10) × 0.5 s = 2 Gb = 250 MB. B: capped by its budget, 10 × 0.5 = 5 Gb = 625 MB.
- Policy: A 4, B 16 (gets A's unused 6) → (4 + 16) × 0.5 = 10 Gb = 1,250 MB. Sent 875 MB, so 375 MB wasted (3 Gb).
- Event-driven updates: a team reports as soon as its demand drops below its budget (or the parent lends unused budget immediately). Benefit: capacity redistributes within ms. Cost: more frequent reports and allocation computation, which can make the hierarchy's control plane a bottleneck.
Show solution
Correct: A, B, D, F, G
- A ✔ — Usage ↑, budgets ↓.
- B ✔ — If cwnd/RTT < limit, CC binds; otherwise BwE's limit binds.
- C ✘ — Orion is per domain; domains act like ASes and exchange BGP (Raven).
- D ✔ — This avoids making the NIB a bottleneck that knows every reaction.
- E ✘ — It keeps operator-defined control and global TE. SDN = programmability, not centralization.
- F ✔ — Source routing, like Meta's.
- G ✔ — 42% control-only + 10% control-and-data.
Show solution
7 · Microsoft: SWAN, TeaVaR, OneWAN
Lectures 16–17 (taught by the TA). Microsoft's DNA: failure handling, and historically solving the optimization problem exactly with an LP solver (Meta and Google use heuristics).
| Meta | Microsoft | ||
|---|---|---|---|
| inter-DC WAN | EBB | B4 | SWAN |
| Internet-facing WAN | CBB | B2 | CORE |
7.1 SWAN: centralized TE for high utilization
- Collect: hosts tell their service's broker (a per-service server that gathers demand and later hands out rate limits) how much they want to send; brokers pass totals to the controller. Network agents on the switches report topology and link state.
- Compute: an optimal, fair allocation, class by class. Interactive traffic (user-facing, latency-sensitive) is allocated first; background traffic (bulk copies, backups) gets what remains. Within a class SWAN wants max-min fairness and high throughput. It gets there approximately by solving a series of LPs: each one maximizes total throughput while not letting any flow fall below the level it reached in the previous round, so the smallest flows are raised first, like water-filling. Output: a rate for each tunnel between each pair of DCs.
- Realize: brokers rate-limit hosts; network agents configure only the edge (ingress) switches. Core routers have statically configured label-switched paths, so SWAN just picks tunnels and weights at the edge (e.g., tunnel 1: 50%, tunnel 2: 30%, tunnel 3: 20%). Each tunnel entry is a rule, and the rule table is small. Recomputed about every 5 min.
Congestion-free updates with scratch capacity
Switches don't update simultaneously, so mid-update a link can carry some flows' old rates and others' new rates. Lecture example (links 100 Gb/s): initial U(F1 80, F2 20) / L(20, 80) → target swap. If F2 moves first, U = 80 + 80 = 160. If F1 moves first, L overloads. Splitting into chunks without spare room still overloads.
Why scratch capacity makes this possible: if every stage leaves a fraction s of each link free, a step may move traffic as long as the temporary overlap fits in that free slice. Moving a little of the traffic per step keeps the overlap small, so a plan always exists. Smaller s means a smaller overlap allowed per step, so more steps; the bound is ⌈1/s⌉ − 1.
For every link e and every step i → i+1:
Σ_f max( x_f,e(i) , x_f,e(i+1) ) ≤ c_e ← worst case: any mix of old/new
Flow conservation each stage: Σ_e x_f,e(i) = d_f
Objective: maximize headroom (slack); if infeasible with k stages, try k+1
Whiteboard version of the lecture LP (a = F1, b = F2; u = upper, l = lower link):
variables per stage i: a_u^i, a_l^i, b_u^i, b_l^i
each flow fully carried: a_u^i + a_l^i = 80, b_u^i + b_l^i = 80
upper link, step i→i+1: max(a_u^i, a_u^{i+1}) + max(b_u^i, b_u^{i+1}) + h ≤ 100
(same for the lower link) · stage 0 and stage 3 are fixed · maximize h, h ≥ 0
With scratch capacity s (fraction kept free on every link): at most ⌈1/s⌉ − 1 steps
(s = 10% → ≤ 9 · s = 20% → ≤ 4 · bigger s = fewer steps but less usable capacity)
Changing the tunnel set with limited rule space
If the new allocation uses different tunnels, you must install new rules before removing old ones. With infinite rule space: add all new rules, shift traffic congestion-free, delete old ones. In reality the table is small, so keep spare rule entries (scratch rule capacity). Lecture: from {1,2} to {3,4} with one spare slot: add 3 → compute an optimal allocation restricted to {2,3} → congestion-free shift → remove 1 → add 4 → shift to {3,4} (that allocation was already computed at the start) → remove 2. Getting to the target takes a series of LPs (allocation LPs for intermediate tunnel sets plus congestion-free plan LPs).
7.2 TeaVaR: utilization with an availability guarantee
EBB, B4, and SWAN recover reactively: fast local reroute, then the controller re-optimizes seconds to minutes later. Until then, allocations made for “all links up” can't be met, so there is no availability guarantee.
The slide's numbers, worked out. P(fail): top L1 = 10⁻³, middle L2 = 10⁻¹ (flaky), bottom L3 = 10⁻³, independent.
| Event | Probability | Consequence |
|---|---|---|
| no link fails | (0.999)²(0.9) ≈ 89.8% | 30 Gb/s available |
| exactly one fails | ≈ 10.2% (almost all of it is the middle link) | 20 Gb/s left |
| two or more fail | ≈ 2·10⁻³·10⁻¹ = 0.02% | ≤ 10 Gb/s left |
| top or bottom fails | 1 − 0.999² ≈ 0.2% | (matters if you use only those two) |
- A 1-failure-tolerant allocation (20 Gb/s spread so any two survivors carry it) is met whenever at most one link is down: 1 − 0.02% = 99.98%. So 20 Gb/s can be guaranteed at β = 99.98%, while the 2-failure guarantee only allows 10.
- Sending 10 + 10 on only the two reliable links (ignoring the flaky middle) is met whenever both are up: ≈ 99.8%, not 99.98%.
Independence: P(scenario q) = Π_links P(link state in q) (2^n scenarios for n links)
Loss of a flow in q: 1 − (demand still deliverable on surviving tunnels)/(demand)
(no rerouting inside the scenario)
L(x, q) = MAX over flows of that loss ← worst-off flow
Loss distribution for allocation x: values L(x,q) with probabilities P(q)
V(x) = VaR_β = β-percentile of that distribution (smallest v with P(L ≤ v) ≥ β)
TeaVaR: x*, V* = argmin_x V(x) s.t. link capacities
Guarantee: scale every allocation by (1 − V*) → satisfiable β of the time
② Loss in a scenario. Fix an allocation x (how much each flow sends on each tunnel). In a scenario, traffic on failed tunnels is simply lost (no rerouting yet). A flow's loss = the fraction of its demand that didn't get through. The scenario's loss L(x, q) is the worst flow's loss, because the promise must hold for every flow.
③ Loss distribution. Listing every scenario's loss with its probability gives the distribution of “how bad things are” under allocation x.
④ VaRβ (value at risk). Sort scenarios from least to most loss and add up their probabilities until you reach β (e.g. 99.98%). The loss where you stop is V(x): “with probability at least β, loss is no worse than V”.
⑤ Optimize and promise. TeaVaR searches for the allocation with the smallest V. If the best is V* = 0.1, every flow is promised 90% (1 − V*) of its allocation, and that promise holds in all scenarios except the rarest (1 − β) of the time.
Tiny example (problem 7.5, even split over 3 links, β = 0.95): P(loss = 0) = 0.92169, P(loss ≤ ⅓) = 0.99832. The first value to reach 0.95 is ⅓, so V = ⅓ and the guarantee is 30 × (1 − ⅓) = 20 Gb/s, 95% of the time.
Lecture loss example (scenario q4: L1 down, L2 and L3 up): F1 sends (2, 3, 5) and F2 sends (4, 3, 3) on (L1, L2, L3), demand 10 each. F1 loses 2/10 = 0.2, F2 loses 4/10 = 0.4, so L(x, q4) = 0.4 (the max over flows). Probability primer: dependent events use P(A∩B) = P(A)·P(B|A); independent ones use P(A∩C) = P(A)·P(C). The p-th percentile is the value below which p% of samples fall.
7.3 OneWAN: merge the split WANs
Challenges: ① routing-table scale (~10⁵ DC routes vs ~10⁶ Internet routes) ② fast failure repair ③ scaling the TE optimization ④ estimating Internet demand (not under your control) ⑤ migrating live traffic seamlessly.
- Max-flow = the most traffic that can be pushed from A to the destination through a given entry router, limited by the smallest capacities along the way.
- Router roles: aggregation routers keep the full IP tables (BGP with Internet and DC prefixes) and choose the egress next hop. Backbone routers keep no prefixes and just forward on MPLS labels the controller programs (TE paths and rates, as in SWAN). The agg→backbone hop is handled locally by steering, not inside the central LP, which keeps the LP smaller.
- Label stack along the path (slide): ingress edge → (BGP) → ingress aggregation router pushes [egress-site label, BGP next-hop node SID] (traffic steering) → ingress backbone router swaps the outer label for a TE path label (traffic engineering across the backbone) → egress backbone router pops it, leaving only the BGP next-hop SID (segment routing) → egress aggregation router pops that and forwards on IP → egress edge (BGP). Only the aggregation routers ever look at IP prefixes.
- Vocabulary: a trunk = all traffic from one source backbone router to one destination site in one priority class (the unit the optimizer allocates). Shared risk = links that can fail together because they share something physical, e.g. two “different” links running through the same fiber conduit. Committed share = capacity promised to a priority class in advance. Scavenger = the lowest priority, which only uses capacity nobody else wants.
- Solver chain: candidate paths (low-delay paths with fewer shared risks, plus max-flow paths) → reserve each priority's committed share → priority 0 (best-effort and higher): max-min fair rate per trunk → minimum cost while keeping fair rates; priority 1 (scavenger): max-min fair with the remaining capacity → balance link utilization (min MLU) → add risk-diverse paths (avoid shared risks) and re-optimize.
- Tractability: trunk = (source backbone router, destination site, class); compute paths only for pairs with demand · prune trunks < 500 Mb/s (only 2.5% of traffic) → 5× fewer constraint rows, 7× fewer variables · faster LP solvers (CLP, GLOP: about 5× faster than SWAN's original) with dual simplex and cost perturbation.
- Write the condition a transition from stage i to i+1 must satisfy on each link.
- Can it be done in one step? Show the worst case.
- Construct a 3-stage plan (two intermediate states) and verify every transition.
- What does SWAN's bound say about the number of steps with 20% scratch? What's the trade-off in choosing the scratch?
Show solution
- For each link e: Σf max(xf,e(i), xf,e(i+1)) ≤ ce (any mix of old and new rates may coexist). Each flow's total is conserved at every stage.
- U: max(70, 10) + max(10, 70) = 140 > 100 ✗ (same on L).
- Stage 1: F1 (50, 30), F2 (30, 50). Stage 2: F1 (30, 50), F2 (50, 30). Stage 3 = target.
0→1: U max(70,50) + max(10,30) = 100 ✓; L max(10,30) + max(70,50) = 100 ✓.
1→2: U 50 + 50 = 100 ✓; L 50 + 50 ✓. 2→3: U max(30,10) + max(50,70) = 100 ✓; L max(50,70) + max(30,10) = 100 ✓. - ≤ ⌈1/s⌉ − 1 = ⌈5⌉ − 1 = 4 steps (an upper bound; here 3). More scratch means fewer steps and faster convergence, but less capacity for real traffic (SWAN used about 10%).
- Worst-case load on U for each transition.
- A colleague proposes going straight from stage 0 to U (40, 40), L (40, 40). Valid?
- Why is the scratch capacity still 20 after each completed stage?
Show solution
- 0→1: max(64,44) + max(16,36) = 64 + 36 = 100 ✓. 1→2: 44 + 56 = 100 ✓. 2→3: 24 + 64 = 88 ✓. (L is symmetric.)
- U: max(64,40) + max(16,40) = 64 + 40 = 104 > 100 ✗. F1 hasn't left U before F2 might arrive.
- Each flow's total (80) is conserved and both completed states use 80 per link. The invariant is kept at stage boundaries; only transient mixes may reach 100%.
- With 1 spare entry, list the steps. How many intermediate allocation LPs and how many congestion-free shift plans are needed?
- The table holds 5 entries (2 spare). Steps and counts?
- Why not overwrite T1 with T4 directly?
Show solution
- Add T4 → allocate over {T2, T3, T4} (LP) → congestion-free shift → remove T1. Add T5 → allocate over {T3, T4, T5} (LP) → shift → remove T2. Add T6 → shift to {T4, T5, T6} (allocation already known from the start) → remove T3. 2 extra allocation LPs, 3 shift plans (each shift plan is itself an LP).
- Add T4, T5 → allocate over {T3, T4, T5} → shift → remove T1, T2 → add T6 → shift to the final set → remove T3: 1 extra allocation LP, 2 shift plans.
- Traffic currently using T1 would be disrupted (dropped or rerouted unpredictably), possibly causing congestion. Keep spare rule entries the same way you keep spare link capacity.
(b) The lecture's slide. Three 10 Gb/s links, independent failure probabilities: top 10⁻³, middle 10⁻¹, bottom 10⁻³.
- P(no failure), P(exactly one failure), P(two or more failures)?
- Allocation X: 20 Gb/s spread so that any two surviving links carry it. What fraction of the time is 20 Gb/s delivered?
- Allocation Y: 10 + 10 on top and bottom only. What fraction of the time is 20 Gb/s delivered?
- Which one meets “20 Gb/s, β = 99.98%”?
Show solution
(b) i. None: 0.999²·0.9 ≈ 0.8982. Exactly one ≈ 0.1·0.999² + 2·0.001·0.999·0.9 ≈ 0.1016 (almost all from the flaky middle). Two or more ≈ 2·0.001·0.1 ≈ 0.0002 = 0.02%.
ii. X fails only if two or more links are down: delivered ≈ 99.98% of the time.
iii. Y needs both top and bottom up: 0.999² ≈ 99.8% (fails 0.2% of the time).
iv. X. Note: in lecture the TA said Y gives 99.98%; the probabilities on the slide give 99.8%. Trust your own computation.
- Probability of each of the 8 scenarios.
- Allocation E: split demand equally over the 3 links. Allocation T: split equally over L1 and L2 only. Loss distribution of each.
- VaR (the β-percentile loss) of each for β = 0.90, 0.95, 0.99.
- Max demand each allocation can carry (capacity), and the bandwidth it can guarantee β of the time (demand × (1 − VaR)) for each β. Which is better?
Show solution
- Up probabilities 0.99, 0.98, 0.95.
(Sum = 1. E.g., L3 only: 0.99·0.98·0.05.)down none L1 L2 L3 L1L2 L1L3 L2L3 all P .92169 .00931 .01881 .04851 .00019 .00049 .00099 .00001 - E: loss 0 w.p. .92169; ⅓ w.p. .07663 (one down); ⅔ w.p. .00167; 1 w.p. .00001.
T: loss 0 when L1 and L2 are up: .99·.98 = .9702; ½ w.p. .01·.98 + .99·.02 = .0296; 1 w.p. .0002 (L3 is irrelevant). - CDFs: E reaches .92169 at 0 and .99832 at ⅓. T reaches .9702 at 0 and .9998 at ½.
β = .90: E 0, T 0. β = .95: E ⅓, T 0. β = .99: E ⅓, T ½. - Capacity: E carries up to 30 (10 per link); T up to 20.
β = .90: E 30·1 = 30; T 20 → E. β = .95: E 30·⅔ = 20; T 20·1 = 20 → tie. β = .99: E 20; T 20·½ = 10 → E. The best allocation depends on β, which is why TeaVaR optimizes the tail loss rather than using a fixed rule.
- L(x, q) for: no failure; L1 down; L3 down; L2 and L3 down.
- Suppose these four are the only scenarios, with probabilities 0.90, 0.05, 0.04, 0.01. VaR at β = 0.95 and β = 0.99?
- What rates can be guaranteed 95% of the time?
Show solution
- None: 0. L1 down: F1 2/10 = 0.2, F2 4/10 = 0.4 → 0.4. L3 down: F1 0.5, F2 0.3 → 0.5. L2+L3 down: F1 0.8, F2 0.6 → 0.8. (Max over flows: the worst-off flow.)
- CDF: 0 → .90, 0.4 → .95, 0.5 → .99, 0.8 → 1. β = .95 → V = 0.4. β = .99 → V = 0.5.
- Scale by (1 − 0.4): 6 Gb/s for each flow, available 95% of the time.
- Apply OneWAN's three steering steps. What weights result? How would 1,100 flows be distributed?
- Why do aggregation routers hold the full IP tables while backbone routers don't? What do the outer label and the inner SID identify?
Show solution
- ① Filter by latency → drop D. ② Max flow: via B min(40, 30) = 30; via C min(25, 40) = 25; total 55. ③ Weights 6/11 ≈ 0.545 to B, 5/11 ≈ 0.455 to C → 600 / 500 flows. Backbone TE then allocates across the WAN tunnels.
- Internet routes number ~10⁶ (vs ~10⁵ DC routes). Only aggregation routers run BGP and pick the egress next hop; backbone routers just forward on MPLS labels that the controller programs (SWAN-style), which saves memory. Outer label = destination site / TE tunnel; inner SID = the BGP next hop (egress aggregation router).
Show solution
Correct: A, C, D, F, G
- A ✔ — Only tunnel selection and weights at the edge.
- B ✘ — Interactive (high priority) first.
- C ✔ — The 160 Gb/s transient example.
- D ✔ — Multiply per-link up/down probabilities.
- E ✘ — It's the opposite: it sizes for rare events and wastes capacity.
- F ✔ — Fragmented capacity: inter-DC traffic grew to dominate.
- G ✔ — And 5× fewer constraint rows.
8 · Network verification
Lecture 18 (the last Unit 2 lecture; it's on the quiz). The question: can we guarantee that configurations are error-free? Not intent (that is human-readable), but the thousands of configurations generated from reconciling hundreds of intents. Updates, versioning, and TeaVaR plan for failures, but nothing so far catches a human or config error (a 4 typed instead of a 5 in a prefix).
8.1 The running example
8.2 The verification map
Model components: configuration (route rules, filters) · packet class (the headers in scope, as symbolic packets: one variable stands for every packet in the class, e.g. “any TCP packet to D on port 443, from any source address and port”, and the solver reasons about all of them at once instead of testing them one by one) · environment (which links are up or failed) → possible forwarding steps → compose → feasible paths and prefixes. A digital twin (a simulated copy of the network that you feed test packets) only checks the cases you thought to try; with billions of possible packets × failure combinations it can't cover them all. Symbolic search covers the whole modeled space in one query.
In the table: ∃ = “there exists”, ∀ = “for every”, ¬ = “not” (full symbol table in §8.3). A prefix of a path is its beginning part, e.g. S, B, S is a prefix that already repeats S.
| Requirement | Meaning | Constrains |
|---|---|---|
| Reachability | some path arrives (∃) | delivered paths |
| Isolation | no path arrives for forbidden traffic (∀ ¬) | delivered paths |
| Waypointing | every delivered path visits F (∀ paths). It does not require delivery; add reachability if packets must also arrive. | delivered paths |
| Loop freedom | no feasible prefix repeats a router (a loop witness can end before delivery) | all forwarding prefixes |
| Failure tolerance | the property holds across all allowed failure conditions (e.g., ≤ 1 link down) | scope |
8.3 Encoding in first-order logic
| Symbol | Read it as | Symbol | Read it as |
|---|---|---|---|
| ∧ | and | ∀x | for every x |
| ∨ | or | ∃x | there exists an x |
| ¬ | not | A ⟹ B | if A then B (true whenever A is false) |
| ⟺ | exactly when (same truth value) | ∧i, ∨i | “and” / “or” over all i |
Letters used below: h = a packet header (symbolic: stands for every packet in a class at once); e = the environment, i.e. which links are up; x = the routing and forwarding choices; u, v = routers; S, D = source and destination.
Packet class H_p = { h : h.dstIP ∈ D_IP ∧ h.proto = TCP ∧ h.dport = p } (any src IP / src port)
ACL (ordered) hit_i(h) = match_i(h) ∧ ¬( match_1(h) ∨ … ∨ match_{i−1}(h) ) ← first match wins
permit(h) = ∨_i ( hit_i(h) ∧ action_i = allow )
One hop N(u,v,h,e) = sel(u,v,h,e) ∧ up(u,v,e) ∧ permit_{u→v}(h)
(route selected ∧ link up ∧ ACL permits — ALL three)
Path Path(v0…vm,h,e) = ∧_{i
The same lines in plain words
Packet class: “all TCP packets to D's addresses on port p, from any source” — one symbol h covers all of them.
hiti: rule i matches the packet and no earlier rule did, so rule i is the one that decides. permit: the deciding rule says allow.
N(u, v): the packet can really move from u to v: routing picks v as next hop, the link is up, and the filter lets it through. All three are needed.
Path: every consecutive hop along a router sequence works. R(S, D): some such path goes from S to D.
Backward layers: R₀ = routers already at D; R₁ adds routers that can reach a router in R₀ in one working hop; and so on. S can reach D if S ever joins a layer. In a small network, as many layers as the longest path suffice.
≤ 1 failure as “every pair has one up”: if two links were both down, the clause (upa ∨ upb) for that pair would be false. Requiring every pair's clause to be true is the same as “at most one link is down”, using only and/or/not (pure SAT).
Query: “is there a failure case we allow, consistent with how the network behaves, in which the requirement fails?”
📈 How to read this figureThe reachability layers for a web packet with S–F failed. 0 steps: only D. ≤ 1 step: F joins, because F→D is selected, up, and permitted. B does not join: B→D is selected and up, but B's ACL denies port 443. ≤ 2 steps: S's only working next hop would be B, which is not in the previous layer, so S never joins. Web from S is unreachable: a counterexample.
Scenarios in scope with ≤ 1 failure on 4 links: none, S–F, F–D, S–B, B–D (5 cases, one symbolic query).
Before the repair, web is dropped for S–F down and for F–D down, so the query is SAT with counterexample “S–F down, web packet”.
After the repair (B permits web), it is delivered in all 5, so UNSAT.
8.4 SAT vs SMT; Minesweeper
SAT (Boolean satisfiability): given true/false variables and a formula over them, find values that make the formula true, or prove none exist. Here every variable is Boolean (link states, next hops, forwarding, reachability). It is NP-complete (no known algorithm is fast on every input), but modern solvers are fast on most practical instances. SMT (satisfiability modulo theories) adds richer domains:
bit-vectors (addresses), integers (route metrics), linear arithmetic (capacity: x₁ + x₂ ≤ 5, latency bounds). Use SMT to capture capacity, availability, or latency requirements.
Minesweeper (SIGCOMM 2017) is a compiler for router configurations: parse configs and topology → encode routing and forwarding as SMT constraints → search for violations.
It encodes the three kinds of routing policy: export (which routes a router advertises to each neighbour), import (which advertised routes it accepts) and selection (which accepted route it prefers). For example c ↔ a ∧ up ∧ accept: S has a usable route from B exactly when B advertised it, the S–B link is up, and S's import policy accepts it. It also encodes route preferences and interactions between protocols.
It checks stable routing states: states where routing has settled, so no router would change its choice given what its neighbours advertise and its policies. E.g. after S–F fails, the only stable state has S selecting the route via B, and the solver then checks the requirement in that state.
An ACL can also be implemented as “don't advertise”, so the routing configuration is analyzed too, not just the filters.
The caveats A SAT result is solid evidence (a concrete counterexample). UNSAT is only as good as the model: missing ACLs, an external controller that reacts to failures, or humans “fixing” things live are all outside it.
Richer models cost more computation (NP-hard). The research is about expressive-but-efficient encodings and network-specific algorithms.
Unit 2 summary (last slide): private WANs control their traffic (choose routes, divide capacity among tenants, rate-limit at sources for predictability) but still need CC for RTT-scale reactions.
Centralized control gives an easier interface and globally optimal decisions, but it must coexist with distributed control and is a logical single point of failure. Modeling failure to hedge against it is a critical operation.
✍ iPadProblem 8.1 — Scenario table for the running example calcRouting: S uses S–F–D when S–F and F–D are both up; otherwise it settles on S–B–D. F's ACL: deny TCP/23, permit everything else. B's ACL (first match): TCP/443 → deny; TCP/22 → permit; default → deny.
Requirements: web (443) delivered under any ≤ 1 link failure; SSH (22) goes through F in normal operation; telnet (23) never delivered.
- For each scenario (none, S–F, F–D, S–B, B–D down), is web / SSH / telnet delivered, and via which node?
- Which requirements are violated, and in which scenarios?
- Repair B's ACL minimally and state the verification result after the repair.
Show solution
down path web SSH telnet
none S–F–D ✓ ✓ via F blocked at F
S–F S–B–D ✗ dropped at B ✓ via B blocked (default deny)
F–D S–B–D ✗ dropped at B ✓ via B blocked
S–B S–F–D ✓ ✓ via F blocked at F
B–D S–F–D ✓ ✓ via F blocked at F
(b) Only web reachability under failure fails (S–F down, F–D down). The waypoint holds in normal operation; isolation holds everywhere.
(c) Change B's first rule to TCP/443 → permit (or delete it). Web is then delivered in all 5 scenarios, so the query “≤ 1 failure ∧ model ∧ web not delivered” is UNSAT; telnet is still default-denied.
✍ iPadProblem 8.2 — Reachability layers calcSame network and buggy ACL as 8.1, for a web packet. Using N(u,v) = selected ∧ up ∧ permit and backward layers R₀ = {D}, Rk = Rk−1 ∪ {v : N(v,u) for some u ∈ Rk−1}:
- Compute R₀, R₁, R₂ with F–D down.
- With S–B down.
- With F–D down after the repair.
- Why do two layers suffice here?
Show solution
- R₀ = {D}. F→D: link down ✗. B→D: selected and up, but the ACL denies 443 ✗ → R₁ = {D}. S→B is selected but B ∉ R₁ → R₂ = {D}. S unreachable.
- R₁ = {D, F} (B→D still denies web). S→F is selected, up, and permitted → R₂ = {D, F, S}. Reachable.
- R₁ = {D, B}, R₂ = {D, B, S}. Reachable.
- The longest loop-free path (the diameter) is 2 hops, so k = 2 covers every possible path.
✍ iPadProblem 8.3 — Encoding an ordered ACL shortB's ACL in order: r1: src ∈ 66.6.0.0/16 → deny; r2: TCP/443 → permit; r3: TCP/22 → permit; r4: default → deny.
- Decide: web from 66.6.1.1; web from 10.0.0.1; telnet from 10.0.0.1; SSH from 66.6.7.7.
- Write hit₂(h) and permit(h) in first-order logic.
- An engineer swaps r1 and r2. Which decision changes, and what kind of requirement does that violate?
Show solution
- deny (r1) · permit (r2) · deny (r4) · deny (r1).
- hit₂(h) = match₂(h) ∧ ¬match₁(h) = (h.proto = TCP ∧ h.dport = 443) ∧ ¬(h.src ∈ 66.6.0.0/16).
permit(h) = (hit₂(h)) ∨ (hit₃(h)), since only r2 and r3 allow (equivalently ∨i hiti ∧ actioni = allow).
- Web from 66.6.1.1 becomes permitted: an isolation violation (the blocked source now reaches D). Order matters, which is why the encoding includes ¬(earlier matches).
✍ iPadProblem 8.4 — Writing requirements and the query shortFor the network in 8.1 (links SF, FD, SB, BD), write:
- Isolation for telnet.
- Waypointing for SSH. Does it imply SSH is delivered?
- Loop freedom.
- “At most one link down” as pure Boolean clauses. How many clauses?
- The solver query that checks “web survives every single-link failure”, and how to read SAT vs UNSAT.
Show solution
- ∀h ∈ H23, ∀e allowed: ¬R(S, D, h, e).
- ∀h ∈ H22, ∀ delivered paths π = (S … D): F ∈ π. No: it constrains delivered paths only, so dropping all SSH satisfies it vacuously. Add reachability if SSH must arrive.
- ¬∃ path prefix v₀…vm, ∃ i ≠ j : vi = vj (checked on prefixes, since a loop never delivers).
- Every pair has an up link: (upSF ∨ upFD), (upSF ∨ upSB), (upSF ∨ upBD), (upFD ∨ upSB), (upFD ∨ upBD), (upSB ∨ upBD): C(4,2) = 6 clauses.
- Allowed(e) ∧ M(C, h, e, x) ∧ h ∈ H443 ∧ ¬R(S, D, h, e). SAT → the assignment is a counterexample (which link failed, the packet, the forwarding state). UNSAT → no violation exists within the model's scope.
✍ iPadProblem 8.5 — Why symbolic search? calc(a) How many failure scenarios are in scope for ≤ 1 failure on 4 links? ≤ 2 failures? (b) For 50 links with ≤ 2 failures? All subsets? (c) Why model packets symbolically (H443) instead of enumerating headers?Show solution
(a) 1 + 4 = 5; 1 + 4 + 6 = 11. (b) 1 + 50 + 1225 = 1,276; all subsets 2⁵⁰ ≈ 10¹⁵. (c) A class like “any src IP, any src port, TCP, dport 443” covers ~2⁴⁸+ concrete headers. Simulation (a digital twin) can't enumerate them; one symbolic query covers them all.
✍ iPadProblem 8.6 — SAT, SMT, Minesweeper MCQWhich statements are correct?☐ A. If the solver returns UNSAT for (allowed failures ∧ model ∧ ¬property), the property is guaranteed in the real network under all conditions.☐ B. A SAT result yields a concrete counterexample: a failure condition, a packet, and forwarding state that violate the property.☐ C. Pure Boolean SAT can't directly express “the sum of competing traffic on a link ≤ its capacity” over integer rates; SMT can.☐ D. Minesweeper derives routing and forwarding constraints from router configurations, including import policies and route preferences, and checks stable routing states.☐ E. Waypointing alone guarantees that packets are delivered.☐ F. Loop freedom is checked on forwarding prefixes, because a looping packet may never be delivered.Show solution
Correct: B, C, D, F
- A ✘ — Only within the modeled scope. Missing behaviors (external controllers, humans, unmodeled ACLs) aren't covered.
- B ✔ — The witness explains the problem.
- C ✔ — SMT adds integers, bit-vectors, linear arithmetic.
- D ✔ — A compiler for configs; stable states after failures.
- E ✘ — It constrains only delivered paths; add reachability.
- F ✔ — A loop witness can end before delivery.
9 · Cumulative refresher: Quiz 1 material (Lectures 1–8)
Compressed from your Quiz 1 and exam-1 reference. Expect at most one or two questions here, probably wrapped around PCC/BBR ideas.
Topic The one thing to remember
End-to-end argument Correctness (e.g., a file arriving intact) can only be completely verified at the endpoints. Link-level checks only improve performance. Fate-sharing: keep connection state at the endpoints so the network survives router failures.
NUM max Σ U(x_s) s.t. Ax ≤ c. Source rule U′(x) = path price. log utility → proportional fairness; α→∞ → max-min; α = 2 → Reno-like (min potential delay); linear → max throughput (starves long flows).
Reno / AIMD +1 per RTT, halve on loss. x ∝ 1/(RTT·√p) → RTT unfairness. Needs ≈ 1 BDP of buffer to stay at full utilization. CUBIC grows on wall-clock time (RTT-fair).
Fluid models dW/dt = [inc·(1−p) − dec(W)·p] / R: read the increase term (AI if constant, MI if ∝W) and the decrease term (MD if ∝W, AD if constant).
Copa d_q = RTT_standing − RTT_min; λ_target = 1/(δ·d_q); λ_current = cwnd/RTT_standing. Current > target → decrease. ±v/δ per RTT; about 1/δ packets queued; competitive mode.
Vegas Q = (W/RTT_min − W/RTT)·RTT_min (packets queued). Q < α → +1; Q > β → −1; otherwise hold (α=1, β=3 typical). Starves beside Reno.
Bufferbloat queue delay = bytes queued × 8 / link rate. A huge FIFO plus loss-based CC gives seconds of delay. Fix with AQM (CoDel) or delay-aware CC.
BBR BtlBw = windowed max delivery rate (10 rounds); RTprop = windowed min RTT (10 s). BDP = BtlBw·RTprop; cwnd ≈ 2·BDP; must pace. PROBE_BW gains 1.25/0.75/1×6. PROBE_RTT drains inflight to refresh the min RTT. v1 ignores loss (unfair); v2 adds loss/ECN; v3 refines.
ECN / DCTCP Marks give a signal before buffer-overflow loss, with no retransmission. Standard ECN response = react as if one loss (once per RTT), not proportionally. DCTCP: cwnd ← (1 − α/2)cwnd.
CoDel Sojourn time per packet. Bad queue = min sojourn > target (5 ms) for a whole interval (100 ms). Drop gaps then shrink as 100/√count. Persistent delay matters, not the average or the max.
INT Switches stamp per-hop info (queue length, tx bytes, timestamp, capacity). This reveals which hop is congested, which an ECN bit can't. Header overhead grows with hops, so it is used in datacenters.
📈 How to read this chart (BBR's model of the path)x-axis: how much data the sender has in flight. Blue: the delivery rate the receiver sees. Orange: the RTT. Left of the BDP line, more in-flight data means more delivered (the pipe isn't full) and the RTT stays at its minimum (no queue). At the BDP (bandwidth × min RTT) the pipe is exactly full: maximum delivery rate and minimum RTT, the optimal point BBR aims for. Right of it, extra data only builds a queue: delivery stays flat and the RTT climbs, until the buffer overflows at “loss”. Loss-based algorithms (Reno, CUBIC) operate out near the loss line; BBR tries to stay at the knee.
9.1 Bridges: Part 1 ideas that Part 2 reuses
The professor said Quiz 2 may use “ideas that depend on information we covered before quiz one”. These are the links most likely to be tested. The § numbers point into your Exam 1 reference (networks-exam1/notes/EXAM_REFERENCE.md), the full source for Lectures 1–8.
Part 2 topic Part 1 idea it builds on Exam 1 ref.
TE vs congestion control (§3) The two knobs: change rates (CC, endpoints) or routes (TE, control plane). Controlling both is rare, except in hyperscaler WANs. §3.1, §4.6
Min-MLU, MCF (§3, §5) Routing matrix A and link loads Ax; NUM's Ax ≤ c becomes TE's Σ x_kp ≤ U·c_e. §3.2, §3.5
B4 waterfill, bandwidth functions (§6) Max-min fairness by water-filling; weighted utilities (w·log x); fairness is a property of the utility. Parking lot: max-min (½, ½, ½) vs proportional (⅓, ⅔, ⅔). §3.3, §3.4
PCC utilities (§1) Utility functions, concavity (one hill, so climbing works), Copa's utility ln x − δ ln d. §3.4–3.5, §6.1
PCC vs Copa / BBR (§1) Model-based vs model-less; Copa targets 1/δ queued packets (delay magnitude); BBR estimates BtlBw and RTprop. §10.1, §6, §10.3–10.8
PCC rate-based vs windows (§1.4 aside) Windows vs rates; pacing hybrid: cap inflight at cwnd, pace at 2·cwnd/RTT. §5.3
QUIC ossification (§2) Internet ossification then vs now: one company now owns server, network and client, so it can deploy (BBR, QUIC). §7.2
QUIC reliability (§2) End-to-end argument: reliability belongs at the endpoints; definition of reliability (all delivered, in order). §2.5, §2.1
SDN pros/cons, dSDN (§4, §6.6) SDN's real benefits (cheap hardware, global optimization) vs cost (network-wide blast radius); “single point of failure” = a logically centralized wrong decision, not a dead machine. §2.1
dSDN fate-sharing (§6.6) Clark's fate-sharing: state is lost only if the entity that needs it is lost. dSDN applies it to control: control depends only on the routers and links it manages. §2.3
Data plane vs control plane timescales (§4, §5) Data plane: per packet, nanoseconds. Control plane: seconds to minutes. Hence local fast reroute + slow central TE. §2.1
BwE, entitlements, source control (§5, §6.5) Deployment authority: the feasible mechanism depends on who controls the bottleneck and the sender. Private WANs control both, which is why host rate limits work there and not on the open Internet (cf. why ECN and source quench failed). §10.2, §9.3, §2.6
TeaVaR, SWAN headroom (§7) The “finite / delayed / distributed” framing: operators keep failure headroom and can't plan to use 100%. §3.7
How to use this (about 15 min, Day 3): Lecture 19 said Part 1 appears only inside the PCC question, so focus on the PCC, rate-vs-window and NUM rows. read your Exam 1 reference §1 (formula sheet) and §11–13 (comparison tables), then this table, then do problems 9.9–9.10. If any row feels unfamiliar, open the § it points to.
✍ iPadProblem 9.1 — NUM: fairness on two links calcTwo links, 10 Mb/s each. Flow 0 crosses both; flow 1 uses only link 1; flow 2 only link 2. Find the allocation under (a) max throughput (linear utility), (b) proportional fairness (log utility), (c) max-min fairness.Show solution
(a) x₀ = 0, x₁ = x₂ = 10 (total 20; the long flow starves).
(b) Maximize log x₀ + 2·log(10 − x₀): 1/x₀ = 2/(10 − x₀) → x₀ = 10/3 ≈ 3.33, x₁ = x₂ = 6.67.
(c) Equal share on each bottleneck → 5, 5, 5.
✍ iPadProblem 9.2 — Copa decision calcCopa, δ = 0.5, cwnd = 20 packets, RTT_min = 40 ms, RTT_standing = 50 ms. Compute d_q, the target and current rates (packets/s), and the next adjustment and its size per RTT (v = 1).Show solution
① Queueing delay = standing RTT − minimum RTT: dq = 50 − 40 = 10 ms. ② Copa's target rate is the rate at which this flow would keep 1/δ packets queued: λtarget = 1/(δ·dq) = 1/(0.5·0.010 s) = 200 pkt/s. ③ Current rate = cwnd / standing RTT = 20/0.050 s = 400 pkt/s. ④ Current > target means it is queueing more than it wants → decrease. Each ACK changes cwnd by v/(δ·cwnd), and there are ≈ cwnd ACKs per RTT, so ≈ v/δ = 1/0.5 = 2 packets per RTT.
✍ iPadProblem 9.3 — Vegas decision calcVegas, W = 24 packets, BaseRTT = 40 ms, current RTT = 50 ms, α = 1, β = 3. Compute Q = (W/BaseRTT − W/RTT)·BaseRTT and the action.Show solution
Expected rate (if nothing were queued) = W/BaseRTT = 24/0.040 s = 600 pkt/s. Actual rate = W/RTT = 24/0.050 s = 480 pkt/s. The difference (120 pkt/s) is data sitting in queues instead of moving; multiplying by BaseRTT turns it into a packet count: Q = 120 × 0.04 = 4.8 packets of this flow queued. Vegas wants between α = 1 and β = 3; 4.8 > β → too much queued → decrease cwnd by 1 (it would increase if Q < α and hold if in between).
✍ iPadProblem 9.4 — Bufferbloat calcA 50 Mb/s bottleneck with a FIFO holding 2 MB of waiting data; base RTT 30 ms. (a) Queueing delay for a packet behind 2 MB? (b) Resulting RTT? (c) Max waiting data (kB) to keep queueing ≤ 10 ms?Show solution
(a) A packet must wait until everything ahead of it is transmitted. Convert bytes to bits first: 2 MB × 8 = 16 Mb. At 50 Mb/s that takes 16/50 = 0.32 s = 320 ms. (b) RTT = base RTT + queueing delay = 30 + 320 = 350 ms, more than 10× the base: that is bufferbloat. (c) Reverse it: the link drains 50 Mb/s × 0.010 s = 0.5 Mb in 10 ms, and 0.5 Mb ÷ 8 = 62.5 kB. Any queue larger than that adds more than 10 ms.
✍ iPadProblem 9.5 — BBR estimates calcDelivery-rate samples 80, 95, 90 Mb/s; RTT samples 30, 25, 40 ms. (a) BtlBw, RTprop, BDP (kB)? (b) Why does BBR periodically cut inflight in ProbeRTT? (c) Why must BBR pace?Show solution
(a) Max → 95 Mb/s; min → 25 ms; BDP = 95×10⁶ × 0.025 = 2.375 Mb = ≈ 297 kB. (b) To drain the queue so it can measure (refresh) the true min RTT, since max BW and min RTT can't be observed at the same time. (c) Without pacing, bursts build queues and delivery samples underestimate or distort the bottleneck rate.
✍ iPadProblem 9.6 — CoDel MCQCoDel with target 5 ms and interval 100 ms. Experiment 1: sojourn time stays at 6 ms for 300 ms. Experiment 2: sojourn alternates 3 ms (20 ms) and 30 ms (5 ms). Which are correct?☐ A. Experiment 1 meets the persistent-delay condition after about 100 ms, even though its maximum is lower than experiment 2's.☐ B. Experiment 2 enters dropping as soon as a 30 ms sojourn is observed.☐ C. If experiment 1 persists, successive drop gaps shrink as 100/√count ms (100, 70.7, 57.7, 50 …).☐ D. CoDel's target must be re-tuned whenever the link rate changes because it is measured in bytes.Show solution
Correct: A, C
- A ✔ — The minimum sojourn stays above target for a whole interval.
- B ✘ — Within every interval the min is 3 ms < 5, so it's good queueing (a burst).
- C ✔ — Control law.
- D ✘ — Sojourn time is in time units, independent of link rate.
✍ iPadProblem 9.7 — Reading fluid models calcA sender updates once per RTT R; it sees a loss indication with probability p. What algorithm does each describe?
(i) dW/dt = [3(1−p) − p·W/2]/R. (ii) dW/dt = [(1−p)·W/4 − p·W/2]/R. (iii) For (i), the equilibrium window.Show solution
(i) AIMD: +3 packets per RTT without loss, halve (−W/2) on loss. (ii) MIMD: ×1.25 per RTT without loss, ×0.5 on loss. (iii) Set dW/dt = 0: 3(1−p) = pW/2 → W* = 6(1−p)/p.
✍ iPadProblem 9.8 — ECN, INT, end-to-end MCQWhich are correct?☐ A. ECN marks let the sender respond to congestion before buffer overflow causes loss, without retransmitting the marked packets.☐ B. With Reno's standard ECN response, if 20% of a window's packets are marked the window shrinks by exactly 20%.☐ C. INT records can show which hop had the largest queue; a single ECN mark can't.☐ D. By the end-to-end argument, reliable link-level retransmission makes an endpoint file checksum unnecessary.☐ E. BBRv1 reduces its rate in response to ECN marks.Show solution
Correct: A, C
- A ✔ — Signal before loss.
- B ✘ — It reacts like one loss: halve, once per RTT.
- C ✔ — Per-hop telemetry.
- D ✘ — Only the endpoints can verify the complete transfer; link checks just help performance.
- E ✘ — v1 ignores loss and ECN; v2 adds them.
✍ iPadProblem 9.9 — Bridges between Part 1 and Part 2 MCQWhich statements are correct?☐ A. dSDN's fate-sharing applies Clark's principle to control: control should depend only on the routers and links it manages, so it fails only when they do.☐ B. Host rate limits (BwE) work in Google's WAN for the same reason ECN never deployed on the open Internet.☐ C. Min-MLU traffic engineering and NUM congestion control turn the same knob: both adjust source sending rates.☐ D. QUIC's fast rollout fits the Part 1 “de-ossification” story: one company controlling servers, clients and much of the traffic can change transport behavior quickly.☐ E. In B4's waterfill, if every flow group has the same bandwidth function B(s) = s and no cap, the result is max-min fair.☐ F. SDN's single-point-of-failure risk is mainly the controller machine crashing, which replication solves.Show solution
Correct: A, D, E
- A ✔ — Clark: state is lost only when the entity that needs it is lost. dSDN: control runs on the routers, in-band, so no separate control network or server can fail independently.
- B ✘ — Opposite reasons. BwE works because one authority controls both the senders and the network. ECN (and ICMP source quench) failed because authority on the open Internet is fragmented and networks don't trust each other.
- C ✘ — Different knobs: CC changes rates with routes fixed; TE changes routes with demand fixed (Exam 1 ref §3.1).
- D ✔ — Exam 1 ref §7.2: deployability went up because one company can own the server, much of the network and the client. QUIC also runs in user space, so updating the app updates the transport.
- E ✔ — Equal slopes mean equal priority, so raising the common fair share s is exactly water-filling: max-min fairness.
- F ✘ — Controllers are replicated. The risk is a logically centralized wrong decision (a bug or bad config) applied network-wide: the blast radius.
✍ iPadProblem 9.10 — Parking lot: max-min, proportional, and bandwidth functions calcTwo 10 Gb/s links in series. A long flow L crosses both links; S1 uses only link 1; S2 uses only link 2. Everyone has unlimited demand.
- Max-min fair rates (water-filling)?
- Proportionally fair rates (maximize log L + log S1 + log S2)?
- Run B4-style waterfill with bandwidth functions B(s) = s for all three groups.
- Repeat (c) with S1's function changed to B(s) = 2s. What do you notice?
Show solution
- Raise all equally; both links fill together at 5: L = S1 = S2 = 5.
- By symmetry S1 = S2 = 10 − L. Maximize log L + 2·log(10 − L): 1/L = 2/(10 − L), so L = 10/3. L = 3.33, S1 = S2 = 6.67. The long flow pays two link prices, so it gets less.
- Equal functions = max-min. Link 1: s + s = 10 → s = 5, and link 2 likewise. (5, 5, 5), same as (a).
- Link 1: L + S1 = s + 2s = 10 → s = 10/3. L = 10/3 and S1 = 20/3 freeze (link 1 is full). S2 keeps growing on link 2 until L + S2 = 10 → S2 = 20/3.
Result (3.33, 6.67, 6.67). The bandwidth function reproduced the proportionally fair outcome: by choosing slopes, the operator picks the fairness notion. Fairness is a property of the utility (Exam 1 ref §3.4).
10 · Mock Quiz 2 (do it on Day 3, timed)
Rules 60 minutes (the real quiz is long, so rehearse under pressure), only your two printed cheatsheets (as on the real quiz), calculator OK. It's the last section of the iPad PDF. Score MCQs exactly like the real quiz: +1 per correct mark, −1 per wrong mark, floor 0 per question.
Then open the solutions below and write an error log: for each miss, was it a concept gap (re-read that section, redo its problems) or a careless slip (units, misread)?
The questions are deliberately a little harder than Quiz 1, since the professor said Quiz 2 would be.
✍ iPadProblem M.1 — Performance-oriented congestion control (12 pts) MCQcalc(a) Which statements are correct?☐ A. Allegro's default utility counts throughput only while the loss rate stays below about 5%.☐ B. Vivace penalizes the magnitude of the RTT, as Copa does with queueing delay.☐ C. In Vivace, a larger magnitude of the estimated utility gradient produces a larger rate change, subject to a bound.☐ D. When Allegro's two trial pairs disagree, it moves in the direction of the pair with the larger utility difference.☐ E. Under random non-congestive loss, PCC can keep increasing its rate because higher rates still yield higher utility, without identifying the cause of the loss.(b) A Vivace sender at 200 Mb/s tests 190 and 210 Mb/s and measures U(190) = 150, U(210) = 146. With θ = 25, compute g, Δr, and the new rate.Show solution
Correct: A, C, E
- A ✔ — Sigmoid(L − 0.05).
- B ✘ — It penalizes the gradient dRTT/dt.
- C ✔ — Δr = θg, bounded.
- D ✘ — It stays at r and widens ε.
- E ✔ — No cause identification; just utility comparison.
(b) g = (146 − 150)/(210 − 190) = −0.2; Δr = 25·(−0.2) = −5 → 195 Mb/s.
✍ iPadProblem M.2 — QUIC scheduling and semantics (12 pts) calcMCQ(a) All buffered at t = 0: A (2 chunks), B (1 chunk), C (2 chunks); one chunk per packet; RTT 60 ms (30 each way); ACKs immediate; no loss; cwnd starts at 1 and grows by 1 per RTT.
Give each object's display time under C-first, and under round robin in the order A, B, C.
(b) Which statements are correct?☐ A. With HTTP/2 over one TCP connection, a lost packet of one object can delay delivery of other objects whose bytes already arrived.☐ B. QUIC 0-RTT can be used on the first-ever connection to a server.☐ C. A QUIC retransmission reuses the original packet number so the receiver can match it to the lost packet.☐ D. All QUIC streams in a connection share one congestion controller.Show solution
(a) C-first: t0 C1; t60 C2, A1; t120 A2, B1 → C 90, A 150, B 150 ms. RR (A, B, C): t0 A1; t60 B1, C1; t120 A2, C2 → B 90, A 150, C 150 ms.
Correct: A, D
- A ✔ — TCP-level head-of-line blocking.
- B ✘ — It needs remembered resumption state.
- C ✘ — A new packet number; stream offsets identify the bytes.
- D ✔ — CC is per connection.
✍ iPadProblem M.3 — Traffic engineering with classes (12 pts) calcThree disjoint paths: P1 (10 Gb/s, 5 ms), P2 (10 Gb/s, 8 ms), P3 (20 Gb/s, 30 ms). Demands: interactive 6 Gb/s (requires path latency ≤ 10 ms) and bulk 18 Gb/s.
- The controller aggregates both classes and minimizes MLU, and each path carries the classes in proportion. Loads, MLU, and interactive traffic on P3?
- Find a policy-compliant allocation with the same MLU. What does the network need for it?
- Interactive grows to 22 Gb/s, bulk drops to 10. Is the aggregate feasible? Is the policy feasible? What should the operator do?
Show solution
- 24/40 = MLU 0.6: P1 6, P2 6, P3 12. Interactive is 25% of each path → 3 Gb/s on P3 (violates the policy).
- P1 + P2 carry 12: all 6 interactive + 6 bulk; P3 12 bulk → MLU 0.6. It needs traffic classification, per-class demand estimates, and per-class forwarding rules/weights.
- Aggregate 32 ≤ 40: feasible (MLU 0.8). Policy: interactive may only use P1 + P2 = 20 < 22, so it is infeasible. Admit/rate-limit interactive to 20 (P1, P2 full) and put bulk on P3 (0.5), or renegotiate the policy. TE can't create low-latency capacity.
✍ iPadProblem M.4 — Mechanisms (10 pts) MCQWhich statements are correct?☐ A. An MPLS label is 20 bits, and the S bit marks the bottom of the label stack.☐ B. CSPF prunes links that can't meet a trunk's bandwidth or color constraints before running shortest path.☐ C. With Meta's version bit, the source may start tagging packets v1 as soon as it has sent the update messages to the new path's routers.☐ D. sFlow lets switches keep exact per-flow byte counts at line rate.☐ E. Under the hose model, a site's total egress is bounded, but how it splits across destinations may change.☐ F. A Binding SID lets an intermediate router supply the rest of a label stack, working around a stack-depth limit.Show solution
Correct: A, B, E, F
- A ✔ — label 20 | Exp 3 | S 1 | TTL 8.
- B ✔ — Prune → shortest path → install.
- C ✘ — It must wait for acknowledgments that every v1 rule is installed.
- D ✘ — It samples 1-in-N packets; switches keep no per-flow state.
- E ✔ — That is the point of the hose.
- F ✔ — Continuation at the BSID node.
✍ iPadProblem M.5 — HPRR (12 pts) calcParallel directed links L and R, 10 Gb/s each, with fixed background 2 Gb/s on each. Unsplittable LSPs: A = 6 and C = 3 on L, B = 4 on R.
HPRR considers A, then B, then C, repeating passes until nothing changes. A move is accepted only if the max utilization on the new route after the move is lower than the max utilization on the LSP's current route before it.
- Run HPRR. Final placement and MLU.
- Is it optimal among unsplittable placements? Justify.
- What MLU would arbitrary splitting achieve?
Show solution
- Start: L = 2 + 6 + 3 = 11 (1.1), R = 6 (0.6).
Pass 1: A → R: after R = 12 → 1.2, not < 1.1 ✗. B → L: after L = 15 → 1.5, not < 0.6 ✗. C → R: after R = 9 → 0.9 < 1.1 ✓ → L = 8 (0.8), R = 9 (0.9).
Pass 2: A → R: after 15 ✗. B → L: after 12 → 1.2, not < 0.9 ✗. C → L: after 11 → 1.1, not < 0.9 ✗. Stop: L {A}, R {B, C}, MLU 0.9.
- Enumerate the subsets on L: {A} → 0.9; {B, C} → L 9, R 8 → 0.9; every other subset ≥ 1.1. So 0.9 is optimal; HPRR got lucky here (contrast 5.3).
- Total 13 + 4 = 17 over 20 → 0.85.
✍ iPadProblem M.6 — Bandwidth functions and intent (14 pts) calcMCQ(a) Two groups share one bottleneck: A(s) = min(4s, 8), B(s) = min(s, 10). Allocations at C = 6, 14, 20 Gb/s.
(b) A and B are the children of an aggregate that is allocated 9 Gb/s. Children's rates?
(c) Which statements are correct?☐ A. If service S offers 2 Gb/s and receives 2 Gb/s, an intent of “≥ 8 Gb/s for S” is confirmed.☐ B. Orion's reconciliation repairs drift such as rules missing after a component restart.☐ C. TE gives BwE paths and split weights; BwE enforces budgets at hosts and reports prioritized demand to TE.☐ D. A non-work-conserving 2:1 policy can leave capacity unused while one group still has unmet demand.Show solution
(a) C = 6: 5s = 6 → s = 1.2 → (4.8, 1.2). C = 14: A caps at s = 2 (total 10); 8 + s = 14 → s = 6 → (8, 6). C = 20: B caps at 10 → (8, 10), 2 unused.
(b) Aggregate slope 5 until s = 2 (10 Gb/s): 5s = 9 → s = 1.8 → (7.2, 1.8).
Correct: B, C, D
- A ✘ — Offered = delivered = 2 says nothing about 8 Gb/s availability.
- B ✔ — Desired vs observed state, at every layer.
- C ✔ — The TE ↔ BwE loop.
- D ✔ — E.g., (8, 5.33) with 2.67 unused while Y wanted 6.
✍ iPadProblem M.7 — SWAN and TeaVaR (14 pts) calc(a) Links U and L, 50 Gb/s each. F1: (U 30, L 10) → (U 10, L 30). F2: (U 10, L 30) → (U 30, L 10). Can the update happen in one step? Check a plan through the intermediate state F1 (20, 20), F2 (20, 20). What's SWAN's step bound with this 20% scratch?
(b) F1 sends (4, 4, 2) and F2 sends (1, 3, 6) on links (L1, L2, L3); demands 10 each. Compute L(x, q) for “L1 down” and “L3 down”.
(c) The only scenarios are none (0.90), L1 down (0.06), L3 down (0.04). VaR at β = 0.95 and at 0.99, and the rate per flow guaranteed in each case.Show solution
(a) One step: U = max(30,10) + max(10,30) = 60 > 50 ✗. 0→1: U max(30,20) + max(10,20) = 50 ✓, L max(10,20) + max(30,20) = 50 ✓. 1→2: U max(20,10) + max(20,30) = 50 ✓, L 50 ✓. Valid 2-stage plan. Bound ⌈1/0.2⌉ − 1 = 4.
(b) L1 down: F1 4/10 = 0.4, F2 1/10 = 0.1 → 0.4. L3 down: F1 0.2, F2 0.6 → 0.6.
(c) CDF: 0 → 0.90, 0.4 → 0.96, 0.6 → 1.00. β = 0.95 → V = 0.4 → guarantee 10·0.6 = 6 Gb/s per flow. β = 0.99 → V = 0.6 → 4 Gb/s per flow.
✍ iPadProblem M.8 — Verification (14 pts) calcMCQS routes via A when S–A and A–D are up, otherwise via B. Requirement: DNS (UDP/53) from S reaches D under any single link failure.
A's ACL: permit all. B's ACL (first match): r1 UDP → deny; r2 UDP/53 → permit; r3 default → permit.
- Write the verification query. Is it SAT or UNSAT? Give a witness if SAT.
- Fix the configuration and re-evaluate.
- How many failure scenarios are in scope, and how many pairwise clauses encode “≤ 1 failure”?
(d) To also require “DNS + other traffic on B–D ≤ 10 Gb/s”, which solver class do you need?Show solution
(a) Allowed(e) [≤ 1 failure] ∧ M(config, h, e) ∧ h ∈ HUDP/53 ∧ ¬R(S, D, h, e). SAT: witness “S–A down (or A–D down), DNS packet, S→B selected, B's r1 denies”. r1 shadows r2.
(b) Swap r1 and r2 (or delete r1 if UDP needn't be blocked). Re-check: DNS is delivered in all 5 scenarios → UNSAT (holds within the model).
(c) 5 scenarios (none + 4 single failures); C(4,2) = 6 clauses.
(d) SMT (integer or linear arithmetic over rates); pure SAT is Boolean only.
11 · One-page formula and fact sheet (for printing, use the fuller EXAM2_CHEATSHEET.pdf instead)
── PCC (L9) ─────────────────────────────────────────────────────────────────────────────
Allegro u = T·Sigmoid(L−0.05) − x·L, T = x(1−L) trials r(1±ε), ≥1 RTT each, wait 1 RTT
pairs agree → move; disagree → stay, ε↑ STARTING(×2) → DECISION → ADJUSTING
Vivace u = x^t − b·x·dRTT/dt − c·x·L g ≈ (U₊−U₋)/(r₊−r₋) Δr = θ·g (θ grows, Δr bounded)
fluid dRTT/dt ≈ (x − C)/C (slope, not magnitude)
PCC-β U = g − β·q (β = Mb/s traded per ms) tie when β = Δg/Δq
BBR route change: min-RTT filter 10 s keeps old RTT → cwnd = 2·BW·RTT_old too small → rate = cwnd/RTT_new
→ BW filter (10 rounds) drops → spiral until min-RTT expires
── QUIC (L10) ─────────────────────────────────────────────────────────────────────────────
response time (fresh): TCP+TLS1.3 = 3 RTT · QUIC = 2 RTT · QUIC 0-RTT = 1 RTT (needs state + server OK)
stream ID+offset = byte identity (same on resend) · packet number = transmission (new on resend)
loss: packet threshold (3 higher acked) · time threshold (9/8 RTT) · PTO = probe, doesn't declare loss
per-connection: CC, flow-control credit, crypto · per-stream: order/delivery · migration: CID + PATH_CHALLENGE
scheduler tables: t | ACKs | cwnd | sent → arrive = t + one-way delay
── TE (L11, L13) ──────────────────────────────────────────────────────────────────────────
MLU = max_e load_e/c_e parallel disjoint paths: x_p = D·c_p/Σc, MLU* = D/Σc
min ρ s.t. Σ_p x_kp = d_k ; Σ_{k,p∋e} x_kp ≤ ρ c_e ; x ≥ 0
mean latency = Σ x_p·lat_p / D TE can't beat the cut: D > cut ⇒ admission / CC
staged move with headroom h: move ≤ h per step, alternate, confirm each
── MPLS / SDN (L12) ───────────────────────────────────────────────────────────────────────
MPLS shim 32 b = label 20 | Exp/TC 3 | S 1 | TTL 8 · push / swap / pop · labels local per router
CSPF: prune (bw, colors) → shortest path → install; sequential trunks are order-dependent
survive f of k parallel links: reserve D/(k−f) per link (total D·k/(k−f))
flow table: match · action (fwd/drop/modify/to-controller) · priority · counters
── Meta (L12–14, HW Q5) ───────────────────────────────────────────────────────────────────
CBB (external) / EBB (internal) · 4 planes, own controllers · sFlow 1-in-N sampling → DC×DC×class matrix
estimate = samples × N × avg size × 8 / interval · Open/R: Spark, LinkMonitor, KvStore (eventual), Decision, FIB
classes ICP > Gold (shortest RTT + burst margin) > Silver > Bronze (K-shortest + min MLU)
strict priority + buffer carving · entitlements + host rate limits
HPRR: one LSP at a time; accept iff maxutil(new route, after) < maxutil(current route, before)
w_e = exp[α(u′_e/u* − 1)], route cost = Σ w_e (penalizes hops); stuck states need swaps
label stack depth 3 → Binding SID continuation · version bit: install v1 everywhere, all ACK, then flip src
hose: E_i, I_j (2n numbers) vs pipe n(n−1) · max i→j ≤ min(E_i, I_j)
── Google (L14–16, HW Q4) ─────────────────────────────────────────────────────────────────
intent (what) > policy (preference) > configuration (exact state) · lifecycle: interpret, check+plan, fulfill, assure, respond
Orion per domain (BGP between) · NIB pub-sub · reconcile desired↓ observed↑ · request→resolve→realize→report
B(s): slope = weight, flat = cap · pick s with Σ B_i(s) = C · freeze at bottleneck/cap · aggregate: add heights
B4: cheapest path first, spill on fill, freeze; quantize splits (K units); fix overload greedily
BwE: host (HTB) → job → cluster → global; usage ↑ budgets ↓ · waste from stale budgets = Δrate × interval
dSDN: 52% of 41 largest outages control-related; TE on every router, in-band, ingress source-routes
── Microsoft (L16–17) ─────────────────────────────────────────────────────────────────────
SWAN: interactive then background (iterative LP ≈ water-fill); edge-only config; static core labels
congestion-free: Σ_f max(x_f(i), x_f(i+1)) ≤ c_e · scratch s ⇒ ≤ ⌈1/s⌉−1 steps · spare rule entries for tunnel changes
TeaVaR: P(q) = Π P(link state); flow loss = unmet/demand; L(x,q) = max over flows; V = β-percentile;
min V(x); guarantee = allocation × (1−V*) β of the time · k-failure: n links of c → (n−k)·c
OneWAN: agg routers (full BGP, choose egress) / backbone (MPLS) · steer: latency filter → max-flow weights
prune trunks < 500 Mb/s (2.5% traffic → 5× rows, 7× vars) · CLP/GLOP 5×
── Verification (L18) ─────────────────────────────────────────────────────────────────────
N(u,v,h,e) = sel ∧ up ∧ permit · hit_i = match_i ∧ ¬(earlier) · R_k backward from D, k ≤ diameter
query Allowed ∧ M ∧ ¬P → SAT = counterexample; UNSAT = holds in model only
≤1 of n links down: C(n,2) pairwise clauses (up_a ∨ up_b) · scenarios Σ_{i≤k} C(n,i)
SAT (Boolean) vs SMT (+integers, bit-vectors) · Minesweeper: config compiler, stable routing states
── Units ───────────────────────────────────────────────────────────────────────────────────
1 B = 8 b · 1 MB = 10⁶ B · Gb/s × s = Gb → ÷8 = GB · delay = bits/rate · BDP = rate × RTT
Built from the course slides, transcripts, HW2 and its model answers, and your Quiz 1. Good luck. You've got this.