diff --git a/hosts/xlab-gateway/default.nix b/hosts/xlab-gateway/default.nix index bf366bf..eb279af 100644 --- a/hosts/xlab-gateway/default.nix +++ b/hosts/xlab-gateway/default.nix @@ -56,5 +56,32 @@ autodetect = true; }; + # CAPWAP over the 1420-MTU wg-to-wgnet tunnel: the lab Cisco APs (e.g. 3802 + # b08b.cfa8.4fa8) send ~1469B DON'T-FRAGMENT DTLS packets to the C9800 WLC at + # 10.0.10.10 during join, and ignore both PMTUD and DHCP interface-mtu, so the + # CAPWAP/DTLS handshake blackholes on the tunnel and the AP never joins. Clear + # the DF bit on UDP->WLC at ingress so those packets fragment through the tunnel + # (the WLC reassembles). Confirmed: AP joins with this in place. See memory + # cisco-wlc-discovery. + systemd.services.capwap-df-clear = { + description = "Clear DF on lab AP CAPWAP->WLC (10.0.10.10) so DTLS fits the 1420 wg tunnel"; + after = [ "network.target" "systemd-networkd.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = pkgs.writeShellScript "capwap-df-clear-up" '' + set -e + for i in $(seq 1 30); do ${pkgs.iproute2}/bin/ip link show bond.lan254 >/dev/null 2>&1 && break; sleep 1; done + ${pkgs.iproute2}/bin/tc qdisc del dev bond.lan254 handle ffff: ingress 2>/dev/null || true + ${pkgs.iproute2}/bin/tc qdisc add dev bond.lan254 handle ffff: ingress + ${pkgs.iproute2}/bin/tc filter add dev bond.lan254 parent ffff: protocol ip prio 1 u32 \ + match ip protocol 17 0xff match ip dst 10.0.10.10/32 \ + action pedit ex munge ip df set 0 pipe action csum ip + ''; + ExecStop = "-${pkgs.iproute2}/bin/tc qdisc del dev bond.lan254 handle ffff: ingress"; + }; + }; + system.stateVersion = "25.11"; }