Replaces #840, which was closed: it was stale before it was opened, and not only because the state moved on.
The proposal presented A, B and C as the option space and concluded pod-to-pod was blocked. Policy routing was available the whole time — it moved pod egress in #842 and pod-to-pod in #855. The file did not record a constraint, it recorded a blind spot and gave it the authority of a checked-in document.
What this is
Three of four classes are separated, so the file describes the built design rather than proposing one. The PROPOSAL- name goes with it.
Contents: which link each class uses and by what mechanism; the rule order and why 980/981 match source and destination; where table 47 and table 48 each come from; how the bird mesh renders itself from the Kubernetes API without repeating an address; and why the node's own CIDR is originated rather than read back from the kernel — the strange next-hop rejection that made IPv4 fail silently while IPv6 worked.
Failure behaviour is written down because it is what made this safe to roll one node at a time: an empty table 48 falls through to main and pod traffic returns to VLAN 40 — unseparated, not broken.
Management
The remaining class, with its per-service levers and the two approaches the owner rejected — carrying the caveat that the same reasoning which produced that list also called pod-to-pod impossible. It is a record of decisions, not an analysis to trust.
bootstrap.sh
Its reference follows the rename. The comment's point was always that the QEMU and Hetzner sites use two segments rather than the homelab's split, so it says that now instead of pointing at a "target" that has since been built.
Replaces #840, which was closed: it was stale before it was opened, and not only because the state moved on.
The proposal presented A, B and C as the option space and concluded pod-to-pod was blocked. Policy routing was available the whole time — it moved pod egress in #842 and pod-to-pod in #855. The file did not record a constraint, it recorded a blind spot and gave it the authority of a checked-in document.
## What this is
Three of four classes are separated, so the file describes the built design rather than proposing one. The `PROPOSAL-` name goes with it.
Contents: which link each class uses and by what mechanism; the rule order and why 980/981 match source **and** destination; where table 47 and table 48 each come from; how the bird mesh renders itself from the Kubernetes API without repeating an address; and why the node's own CIDR is originated rather than read back from the kernel — the `strange next-hop` rejection that made IPv4 fail silently while IPv6 worked.
Failure behaviour is written down because it is what made this safe to roll one node at a time: an empty table 48 falls through to main and pod traffic returns to VLAN 40 — unseparated, not broken.
## Management
The remaining class, with its per-service levers and the two approaches the owner rejected — carrying the caveat that the same reasoning which produced that list also called pod-to-pod impossible. It is a record of decisions, not an analysis to trust.
## bootstrap.sh
Its reference follows the rename. The comment's point was always that the QEMU and Hetzner sites use two segments rather than the homelab's split, so it says that now instead of pointing at a "target" that has since been built.
Refs #576
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replaces the proposal, which was wrong before it was written down. It presented A, B and C as the option space and concluded pod-to-pod was blocked; policy routing was available the whole time and is what moved pod egress and then pod-to-pod. The file recorded a blind spot and gave it the authority of a checked-in document.
Three of four classes are separated now, so this describes the built design rather than proposing one, and the PROPOSAL- name goes with it: which link each class uses, the rule order and why 980/981 match source and destination, where each table comes from, how the bird mesh renders itself from the API without repeating an address, and why the node's own CIDR is originated rather than read back from the kernel.
Management is the remaining class. Its levers are listed, along with the two approaches the owner rejected — with the caveat that the same reasoning which produced that list also called pod-to-pod impossible, so it is a record of decisions and not an analysis to trust.
Failure behaviour is stated because it is what makes the design safe to roll one node at a time: an empty table 48 falls through to main and pod traffic returns to VLAN 40, unseparated rather than broken.
bootstrap.sh's reference follows the rename; its point was always that the QEMU/Hetzner sites use two segments, not the homelab's split.
Refs #576
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🤖Automated review — model claude-haiku-4-5-20251001 (complexity: trivial), commit f0701370db29d3398aaa00882ceb95ed5496260f.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
This PR replaces a stale proposal document with accurate documentation of the traffic-class separation that has already been built and implemented. The new NETWORK-traffic-classes.md comprehensively describes the design, routing configuration, and rationale for the separation of four traffic classes across VLANs and routing tables. The PR properly removes the old proposal and updates the bootstrap.sh comment to reference the new documentation.
🟢 Nits
Minor — bird.conf comment duplication: The rationale for originating rather than reading back the pod CIDR appears in both kubernetes/infrastructure/bird/bird.conf (lines 12-15) and kubernetes/NETWORK-traffic-classes.md (lines 78-82). This is understandable for self-contained documentation in each location, but the two should be kept in sync if either is updated.
Tests
No tests are needed for documentation changes. The file is a reference document, not executable code.
Recommendation
Looks reasonable — no blocking issues; the documentation accurately describes the implemented system and properly replaces stale material.
🤖 **Automated review** — model `claude-haiku-4-5-20251001` (complexity: trivial), commit `f0701370db29d3398aaa00882ceb95ed5496260f`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
This PR replaces a stale proposal document with accurate documentation of the traffic-class separation that has already been built and implemented. The new `NETWORK-traffic-classes.md` comprehensively describes the design, routing configuration, and rationale for the separation of four traffic classes across VLANs and routing tables. The PR properly removes the old proposal and updates the bootstrap.sh comment to reference the new documentation.
## 🟢 Nits
**Minor — bird.conf comment duplication**: The rationale for originating rather than reading back the pod CIDR appears in both `kubernetes/infrastructure/bird/bird.conf` (lines 12-15) and `kubernetes/NETWORK-traffic-classes.md` (lines 78-82). This is understandable for self-contained documentation in each location, but the two should be kept in sync if either is updated.
## Tests
No tests are needed for documentation changes. The file is a reference document, not executable code.
## Recommendation
Looks reasonable — no blocking issues; the documentation accurately describes the implemented system and properly replaces stale material.
<!-- pr-review:sha=f0701370db29d3398aaa00882ceb95ed5496260f -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Replaces #840, which was closed: it was stale before it was opened, and not only because the state moved on.
The proposal presented A, B and C as the option space and concluded pod-to-pod was blocked. Policy routing was available the whole time — it moved pod egress in #842 and pod-to-pod in #855. The file did not record a constraint, it recorded a blind spot and gave it the authority of a checked-in document.
What this is
Three of four classes are separated, so the file describes the built design rather than proposing one. The
PROPOSAL-name goes with it.Contents: which link each class uses and by what mechanism; the rule order and why 980/981 match source and destination; where table 47 and table 48 each come from; how the bird mesh renders itself from the Kubernetes API without repeating an address; and why the node's own CIDR is originated rather than read back from the kernel — the
strange next-hoprejection that made IPv4 fail silently while IPv6 worked.Failure behaviour is written down because it is what made this safe to roll one node at a time: an empty table 48 falls through to main and pod traffic returns to VLAN 40 — unseparated, not broken.
Management
The remaining class, with its per-service levers and the two approaches the owner rejected — carrying the caveat that the same reasoning which produced that list also called pod-to-pod impossible. It is a record of decisions, not an analysis to trust.
bootstrap.sh
Its reference follows the rename. The comment's point was always that the QEMU and Hetzner sites use two segments rather than the homelab's split, so it says that now instead of pointing at a "target" that has since been built.
Refs #576
🤖 Generated with Claude Code
🤖 Automated review — model
claude-haiku-4-5-20251001(complexity: trivial), commitf0701370db29d3398aaa00882ceb95ed5496260f.Summary
This PR replaces a stale proposal document with accurate documentation of the traffic-class separation that has already been built and implemented. The new
NETWORK-traffic-classes.mdcomprehensively describes the design, routing configuration, and rationale for the separation of four traffic classes across VLANs and routing tables. The PR properly removes the old proposal and updates the bootstrap.sh comment to reference the new documentation.🟢 Nits
Minor — bird.conf comment duplication: The rationale for originating rather than reading back the pod CIDR appears in both
kubernetes/infrastructure/bird/bird.conf(lines 12-15) andkubernetes/NETWORK-traffic-classes.md(lines 78-82). This is understandable for self-contained documentation in each location, but the two should be kept in sync if either is updated.Tests
No tests are needed for documentation changes. The file is a reference document, not executable code.
Recommendation
Looks reasonable — no blocking issues; the documentation accurately describes the implemented system and properly replaces stale material.