Two-layer structure: Sources (raw notes) + Wiki (compile output) Four domains: Dev (40), Venture (3), Homelab (23), Reference (0) Includes CLAUDE.md spec, index pages at all levels, compile log Co-Authored-By: Lovebug <lovebug@herbylab.dev>
106 lines
5.8 KiB
Markdown
106 lines
5.8 KiB
Markdown
---
|
|
created: '2026-05-08'
|
|
path: Sources/Homelab
|
|
project: homelab-vlan-renumber
|
|
status: completed
|
|
tags:
|
|
- proxmox
|
|
- automation
|
|
type: session-notes
|
|
updated: '2026-05-08'
|
|
---
|
|
|
|
# Homelab VLAN Renumber — Switch Chip to Bridge Alignment
|
|
|
|
## Outcome
|
|
|
|
Renumbered OpenWrt's hardware switch chip VLANs to match the bridge VLAN filtering layer. Lab and private VLANs now use the same VID end-to-end (11 and 21) from the wire through the chip, sub-interface, and bridge. Unblocked Phase 1.3 — Knot LXC successfully reaches `10.0.11.1` over a tagged trunk from PVE.
|
|
|
|
## The Problem
|
|
|
|
OpenWrt was running two layers of VLAN configuration with different VID numbering:
|
|
|
|
- **Switch chip (swconfig):** VID 1, 2, 3 (lab), 4 (private)
|
|
- **Bridge VLAN filtering:** VID 11, 21, 31, 61, 71
|
|
|
|
Bridge VLAN filtering rules quietly translated between them via `:u*` (untagged + PVID) on the sub-interface ports. NAS frames came up tagged VID 3 from the chip, hit `eth1.3` configured as `:u*` on bridge VID 11 — bridge applied PVID 11 to ingressing untagged frames. PVE same pattern: VID 4 → `eth1.4:u*` → bridge PVID 21.
|
|
|
|
The translation worked, but it meant configuring PVE to send `tag=11` for "VLAN 11 lab" actually required sending `tag=3` (the chip's wire VID), which is the kind of hidden mismatch that loses an hour of debugging six months later.
|
|
|
|
## The Architecture Change
|
|
|
|
**Switch chip — added entries with bridge-matching VIDs:**
|
|
|
|
```
|
|
VLAN 11: ports='3 4t 6t' (NAS untagged on 3, PVE tagged on 4, CPU tagged on 6)
|
|
VLAN 21: ports='4 6t' (PVE untagged on 4, CPU tagged on 6)
|
|
```
|
|
|
|
**Linux — created explicit 8021q sub-interfaces:**
|
|
|
|
```
|
|
config device
|
|
option type '8021q'
|
|
option ifname 'eth1'
|
|
option vid '11'
|
|
option name 'eth1.11'
|
|
|
|
config device
|
|
option type '8021q'
|
|
option ifname 'eth1'
|
|
option vid '21'
|
|
option name 'eth1.21'
|
|
```
|
|
|
|
These were **created explicitly** rather than relying on the legacy implicit `eth1.<N>` auto-creation. The previous `eth1.3` and `eth1.4` ports never had explicit device entries — Linux auto-spawned them when referenced in the bridge ports list. The explicit form is the modern OpenWrt-recommended pattern and makes the config self-documenting.
|
|
|
|
**Bridge — `homebridge` ports updated:**
|
|
|
|
```
|
|
ports='eth1.3' → ports='eth1.21' 'eth1.11'
|
|
```
|
|
|
|
(`eth1.3` retained for ports 1/2 still on legacy VID 3 — see Open Items.)
|
|
|
|
**Bridge VLAN filtering — sub-interfaces wired to matching VIDs:**
|
|
|
|
```
|
|
VID 11: 'eth1.11' tagged member, 'eth1.3:u*' (NAS legacy translation, retained)
|
|
VID 21: 'eth1.21:u*' (PVE untagged + PVID)
|
|
```
|
|
|
|
## How the Migration Stayed Live
|
|
|
|
Parallel-build pattern. Built the new VID 21 plumbing alongside the existing VID 4 path before tearing anything down. PVE management kept flowing on the legacy path until the new path was verified, then `eth1.4` was removed in one cutover. Same approach for VID 11. PVE never dropped, NAS never dropped.
|
|
|
|
## Hybrid Trunk on PVE Port
|
|
|
|
Port 4 ended as a hybrid trunk: VID 21 untagged (PVE management default) + VID 11 tagged (LXC traffic). This required the LXC's `tag=11` parameter to match the wire VID for the first time — previously this would have needed `tag=3` due to the translation layer.
|
|
|
|
## Key Learnings
|
|
|
|
- **swconfig VIDs are real wire VIDs.** Earlier in the session I (Claude) misframed them as "internal slots" — they're actual 802.1Q tags on frames between the switch silicon and the CPU. The number you see in `swconfig` is the number on the wire.
|
|
- **Tagged port ≠ port adds tag.** Tagged means "expect frames to already carry an 802.1Q tag and preserve it." The sending device adds the tag. PVID on an untagged port is what tags ingressing untagged frames.
|
|
- **VLANs only do anything when something downstream enforces them.** A VID on a frame is just a number unless a switch or bridge filters on it. The original setup "worked" because the bridge wasn't VLAN-aware yet — turning on `bridge-vlan-aware yes` is what surfaced the latent chip/bridge mismatch.
|
|
- **Two VID namespaces stacked on top of each other is a footgun.** The translation pattern works but creates cognitive overhead every time you debug. Aligning the layers eliminates a class of "which number do I use here?" questions forever.
|
|
- **Explicit `8021q` device entries beat implicit sub-interface auto-spawn.** Self-documenting, idiomatic for current OpenWrt, easier to grep for in the config. The implicit form is legacy and hides the dependency on bridge `ports` list references.
|
|
- **`uci add_list` is non-destructive on bridge ports.** Adding a sub-interface to a bridge port list during a parallel build doesn't disrupt existing members. Both paths run side-by-side until the old one is removed.
|
|
- **Parallel-build > rename for live infrastructure.** Renaming `eth1.4` → `eth1.21` in place would have required atomically updating the device, bridge, and switch_vlan in one reload. Building `eth1.21` alongside, verifying, then removing `eth1.4` is recoverable at every step.
|
|
|
|
## Open Items
|
|
|
|
- [ ] Switch chip still has VID 3 with ports 1 and 2 as members (link down on 1, link up on 2). Need to identify what's on port 2 before retiring VID 3 entirely.
|
|
- [ ] Cosmetic: `eth1.21` listed as redundant tagged member on bridge VID 11 (harmless, future cleanup).
|
|
- [ ] Cosmetic: switch_vlan descriptions still say `lab-new` / `private-new`. Should rename to `lab` / `private` once VID 3 is fully retired.
|
|
- [ ] Document new wiring on Knot LXC — Phase 1.3 resume notes can now move from "blocked" to "infrastructure ready."
|
|
|
|
## Final State
|
|
|
|
| Layer | VID 11 (lab) | VID 21 (private) |
|
|
|---|---|---|
|
|
| Switch chip | `3 4t 6t` | `4 6t` |
|
|
| Sub-interface | `eth1.11` (explicit 8021q) | `eth1.21` (explicit 8021q) |
|
|
| Bridge port | `eth1.11` tagged, `eth1.3:u*` legacy | `eth1.21:u*` |
|
|
| End-to-end VID | 11 (NAS untagged on chip, all else 11) | 21 (PVE untagged on chip, all else 21) |
|
|
|
|
NAS reachable, PVE management reachable, Knot LXC pinging gateway. Phase 1.3 unblocked. |