Gentoo × Raspberry Pi(brcmfmac)で Wi-Fi 接続に失敗したときの原因切り分けと解決メモ

本記事は、Gentoo + Raspberry Pi 5(brcmfmac) 環境で 5GHz Wi-Fi(OpenWrt AP)への接続に失敗した事象を、ログの読み解き → 原因候補の整理 → 最短の切り分け → 恒久対策の順でまとめたトラブルシュート記録です。 同様の環境・構成でハマった方の参考になれば幸いです。

TL;DR(最初に結論)

  • 症状は ASSOC-REJECT status_code=16 の連発。dmesg には brcmf_set_channel … reason -52 が多発。
  • 規制ドメイン(regdom)が global=JP でも phy=99(UNSET)のまま、かつ WPA3/SAE のビルド/設定相性が絡んで アソシエーション前段で失敗していた。
  • 改善に効いたもの:
    • AP の国コードを JP 固定、チャンネル 36–48(非DFS)(今回は 48)で固定。
    • クライアントは一時的に WPA2-PSK(AES)に限定(key_mgmt から SAE を外す、pairwise/group/proto を CCMP/RSN 固定)。
    • sae_pwe 未対応による設定パースエラーを除去。
    • 起動後に udev or systemd で iw reg set JP を強制(phy が 99 から動かない個体の保険)。
  • つながっている別サーバは、接続後に AP の Country IE(802.11d)で JP に寄っていた(=接続できれば後追いで JP になる)。今回の問題個体は 接続前に落ちるため、phy が 99 のままという見え方だった。

構成概要

  • クライアント:Gentoo Linux on Raspberry Pi 5
    • カーネル:brcmfmac(Broadcom FullMAC ドライバ)
    • ネットワーク:systemd-networkd + wpa_supplicant
    • MTU:1450(k3s/flannel 想定)
  • アクセスポイント:OpenWrt
    • SSID:OpenWrt5Ghz
    • 暗号:WPA2/WPA3 ミックス(PSK + SAE, CCMP)
    • チャンネル:48(5.240GHz, 非DFS)
    • Country:JP(固定) ← 対応後
    • Wifiアクセスポイント側の暗号化: mixed WPA2/WPA3 PSK, SAE (CCMP)
  • 目的:5GHz 接続の安定化(WPA3 も将来的に使いたい)

症状とログ

DHCPv6の設定ができていなかった

networkctl status wlan0 をした際に次のエラーがでた

networkd[1575743]: wlan0: link_check_ready(): dynamic addressing protocols are enabled but none of them finished yet.
10月 29 00:08:32 k3s-prd-server systemd-networkd[1575743]: wlan0:
DHCPv6 CLIENT: Failed to set identifier: そのようなファイルやディレクトリはありません
10月 29 00:08:32 k3s-prd-server systemd-networkd[1575743]:
wlan0: Failed to configure DHCPv6 client: そのようなファイルやディレクトリはありません
10月 29 00:08:32 k3s-prd-server systemd-networkd[1575743]: wlan0: Failed

DHCPv6 まわりで “DUID を作れない(ENOENT)→ 失敗 → インターフェースが failed に落ちる → DHCPv4 も巻き添えで STOP link is not activated は出ていますが、Acquiring DHCPv4 lease. まで進んでいるので、根っこは DUID 関連の「ファイルが無い」問題

下記を実行

# DHCPv6 の世界では、この machine-id は DUID(DHCP Unique Identifier)生成の材料 になる
systemd-machine-id-setup

# DUID の格納ディレクトリを用意(所有者・権限も)DUID ファイルを永続化するディレクトリ。 systemd-networkd は DUID を初回生成時にここへ保存
# 省略した場合の挙動: systemd-networkd は起動時に /var/lib/systemd/network/ を自動生成するらしい
install -d -o systemd-network -g systemd-network -m 0755 /var/lib/systemd/network

# 念のため netif のランタイムパスも再作成(通常は自動)
# networkd の 一時的な状態ファイル(リンク情報やリースキャッシュ)を格納するランタイムディレクトリ
install -d -o systemd-network -g systemd-network -m 0755 /run/systemd/netif

systemctl restart systemd-networkd

/etc/systemd/networkd.conf に下記を追加

[Network]
DHCPv6DUIDType=link-layer-time

確認コマンド

ping6 -c3 fddf:b915:8720::1          # ゲートウェイ

また確認にはiwコマンド( net-wireless/iw )も用いた

iw dev
iw wlan0 link
iw wlan0 scan | less
iw phy0 info

wpa_supplicant ジャーナル(失敗側)

wlan0: Trying to associate with SSID 'OpenWrt5Ghz'
wlan0: PMKSA-CACHE-ADDED 20:05:b6:ff:bb:0f 0
wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:00:00:00:00:00 status_code=16
wlan0: CTRL-EVENT-SSID-TEMP-DISABLED ... reason=CONN_FAILED
  • status_code=16 は「送信者/受信者のアドレスが不正」等の一般化された **Assoc 失敗(Timeout/拒否)**で出がち。
  • PMKSA 追加直後に失敗しているため、暗号/ネゴ/チャネルの問題が濃厚。

カーネルメッセージ(dmesg)

brcmfmac: brcmf_set_channel: set chanspec 0xd02e fail, reason -52
  • チャネル切り替えに失敗(-52)を連発。regdom/チャネル幅/DFS 判定などで不一致時に出やすい。

規制ドメインの状態

iw reg get
global: country JP: ...
phy#0: country 99: DFS-UNSET
  • global=JP に対して phy=99(UNSET)。ドライバ側(phy)に国コードが反映されていない。

別サーバ(成功側)の特徴的ログ

CTRL-EVENT-REGDOM-CHANGE init=COUNTRY_IE type=COUNTRY alpha2=JP
  • 接続後に AP の Country IE により regdom が JP に遷移。 → 接続に成功すれば後追いで JP になるため、phy=99 自体は“接続できる個体では”致命ではない。

原因候補の洗い出し

  1. regdom(国コード)不一致・未反映
  • global=JP でも phy が 99 のままだと、利用可能チャネル/帯域が制限される。
  • アソシエーション前にチャネル切替で失敗 → status_code=16。
  1. WPA3/SAE(PMF/H2E)周りのビルド/設定相性
  • sae_pwe が unknown として 設定ファイルのパースエラー → そもそも起動できない/ネゴに失敗。
  • AP が WPA2/WPA3 ミックスの場合、クライアント側の SAE 実装が弱いと前段でコケやすい。
  1. brcmfmac + linux-firmware + カーネルの組み合わせ差
  • つながる個体とつながらない個体で FW/Kernel/Driver 世代差があると、初期チャネル制御や HE/VHT まわりで差が出る。

最短の切り分けフロー(実際に効いた順)

  1. AP を JP 固定・**非DFS チャンネル(36–48)**に固定
  • OpenWrt(例:5GHz が radio1 の場合):
uci set wireless.radio1.country='JP'
uci set wireless.radio1.channel='48'   # 36/40/44/48 のどれでもOK
uci commit wireless
wifi reload
  • Country=JP と Channel=48(非DFS)で再起動。
  • AP 側 Country 00(world)だと不整合が出やすいので必ず JP 固定。
  1. クライアントを WPA2-PSK(AES)固定に下げて握れるか確認 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf(一時設定):
ctrl_interface=/var/run/wpa_supplicant
update_config=0
country=JP

network={
    ssid="OpenWrt5Ghz"
    psk="********"
    key_mgmt=WPA-PSK WPA-PSK-SHA256    # ← SAE を一旦外す
    ieee80211w=1                       # PMF optional
    pairwise=CCMP
    group=CCMP
    proto=RSN
    priority=20
}

反映:

wpa_cli -i wlan0 flush
systemctl restart wpa_supplicant@wlan0
journalctl -u wpa_supplicant@wlan0 -n 100 --no-pager

→ CTRL-EVENT-CONNECTED が出れば、犯人は SAE/PMF 相性。 (のちほど WPA3 を段階的に復活)

  1. sae_pwe のパースエラーを除去

sae_pwe が unknown と出る場合は、そのバイナリが H2E を解釈しない。 → まず 行を削除して起動可能に戻す(WPA3 本格運用時に再検討)。

WPA3 を使いたい場合のメモ

まずは WPA2 で安定していることを確認。 次に key_mgmt に SAE を戻し、AP 側は PMF optional から開始:

# 何が交渉可能か(SAE が出るか)
wpa_cli -i wlan0 get_capability key_mgmt
wpa_cli -i wlan0 get_capability pmf
wpa_cli -i wlan0 get_capability pairwise
wpa_cli -i wlan0 get_capability group

# バージョンとリンクライブラリ
wpa_supplicant -v
ldd "$(command -v wpa_supplicant)"
  • key_mgmt に SAE が出なければ、そのバイナリは WPA3/SAE 未対応。
  • pmf に required optional などが出れば PMF は機能有り。
  • wpa_supplicant -v に with OpenSSL 等が表示される(H2E/sae_pwe は暗号ライブラリ要件の影響を受ける)。 Gentoo では USE フラグだけでは SAE/H2E 可否は読み取りづらいケースあり。実機で get_capability を見るのが最短。

設定パラメータの要点

  • ieee80211w
    • PMF(Protected Management Frames)
    • 0=無効, 1=任意, 2=必須
    • WPA3/SAE は PMF 必須。ミックス運用ならまず 1(任意) を推奨。
  • sae_pwe
    • SAE の PWE 算出方式
    • 0=Hunting-and-pecking のみ, 1=H2E のみ, 2=両対応
    • 未対応バイナリでは パースエラーで起動失敗するため注意。対応状況が分かるまで 削除が安全。
  • pairwise / group / proto
    • 暗号スイートとプロトコルバージョンの指定。
    • 近代的な WPA2 固定:
pairwise=CCMP
group=CCMP
proto=RSN
  • WPA3(SAE)でも proto=RSN のままで良い(key_mgmt=SAE と ieee80211w=2 を併用)。

チェックリスト(再発防止)

  • AP(OpenWrt)
    • Country=JP、Channel=36–48(非DFS)で開始
    • 暗号:WPA2/WPA3 ミックス → 最初は PMF optional(ieee80211w=1)
    • hostapd ログ(logread | grep -i hostapd)で Assoc/SAE/PMF の拒否有無を確認
  • クライアント(Raspberry Pi 5)
    • iw reg get:global/phy とも JP が理想。ダメなら udev/systemd で iw reg set JP を強制
    • wpa_supplicant:まず WPA2 固定で接続 → 安定後に SAE を戻す
    • pairwise/group/proto は CCMP/RSN 固定(TKIP/WEP を封じる)
    • wpa_cli get_capability で SAE/PMF の可用性確認
  • ドライバ/ファーム
    • dmesg | grep -i brcmfmac に chanspec fail -52 が並ばないこと
    • linux-firmware の更新は ライセンス許可/マスク解除のうえ慎重に(他デバイスへの既知バグもあるため)

確認コマンド

# 規制ドメイン
iw reg get

# スキャン
iw dev wlan0 scan | grep -A3 'SSID: OpenWrt5Ghz'

# wpa_supplicant ログ
journalctl -u wpa_supplicant@wlan0 -n 100 --no-pager

# ドライバ/ファーム
dmesg | egrep -i 'brcmfmac|firmware|cfg80211' | tail -n 200
modinfo brcmfmac | egrep -i 'filename|version|srcversion'

# 機能可否(SAE/PMF など)
wpa_cli -i wlan0 get_capability key_mgmt
wpa_cli -i wlan0 get_capability pmf
wpa_cli -i wlan0 get_capability pairwise
wpa_cli -i wlan0 get_capability group

# バイナリ/リンク
wpa_supplicant -v
ldd "$(command -v wpa_supplicant)"

参考