OpenWrt 25.12 的 DHCP client 在處理 client id 的行為和 24.10 有所不同,在 release announcement 底下看到一些人因此有連線問題。
與此相關的主要 pull request 是這個:base-files,netifd,odhcp6c: generate/use a global DUID for DHCP
拆 code 瞭解一下,看遇到的話怎麼應對比較合適。
dhcp_default_duid#
新加的 /etc/uci-defaults/14_network-generate-duid 這個 script 會確保設定 network.globals.dhcp_default_duid 裡存有 UUID-Based DHCPv6 Unique Identifier (DUID-UUID)。
有人回報,說他遇到的問題手動砍掉 dhcp_default_duid 能夠解決。雖然從長期維護的角度這不可行,因為 UCI defaults 每次更新後都會重跑,每次更完都要再去砍太累不講,還要考慮遠端更新之後連線起不來砍不到的情況,不過從 debug 的角度來說是新資訊,所以後面也會一併看。
DHCPv4#
底層實做靠 BusyBox 的 udhcpc。
接著看在 UCI 或 LuCI 裡沒有設定 clientid 的狀況。
24.10 的行為#
根據 24.10 dhcp.sh 的寫法,會對 udhcpc 下 -C 參數,也就是 --clientid-none。DHCP request 中不會帶 client id。
25.12 的行為#
根據 25.12 dhcp.sh 的寫法,會以 dhcp_default_duid 生成 client id,再以 -x 0x3d:<clientid> 參數傳進 udhcpc。
25.12 砍掉 dhcp_default_duid 的行為#
這樣的話就不會下 client id 的相關參數,這時候 udhcpc 的預設行為是參考這裡,使用 MAC address 生成 client id。
udhcpc 生成 client id 的預設行為可以看 code 裡面怎麼處理 clientid_mac_ptr。
簡而言之,如果 MAC address 是 00:BE:EF:C0:FF:EE,生成的 client id 就會是 0100BEEFC0FFEE。
- 第 1 個 byte 是 hardware type,
01代表 Ethernet (10Mb),在udhcpc裡是寫死的 - 剩下是 MAC address
也就是說,下面兩個會用同樣的 client id:
- MAC address 是
00:BE:EF:C0:FF:EE,不下 client id 的相關參數 - 下
-x 0x3d:0100BEEFC0FFEE參數
用正規方式重現 24.10 的行為?#
似乎沒有比較簡單的方法。
- 先確認過去拿到的 lease 有 release
- 檢查
norelease設定
- 檢查
- 可以在 interface 把
clientid設成01<macaddr>試試 - 如果還是不行只能自己 build firmware 抽換
dhcp.sh
DHCPv6#
底層實做靠 OpenWrt 的 odhcp6c。
接著看在 UCI 或 LuCI 裡沒有設定 clientid 的狀況。
24.10 的行為#
根據 24.10 dhcpv6.sh 的寫法,就不會下 client id 的相關參數,這時候 odhcp6c 的預設行為是參考 DUID-LL,使用 MAC address 生成 client id。
odhcp6c 生成 client id 的預設行為可以看 code 裡面 // Create client DUID 的部份。
簡而言之,如果 MAC address 是 00:BE:EF:C0:FF:EE,生成的 client id 就會是 0003000100BEEFC0FFEE。
- 第 1-2 個 byte 是 DUID type,
0003代表 DUID Based on Link-Layer Address (DUID-LL),在odhcp6c裡是寫死的 - 第 3-4 個 byte 是 hardware type,
0001代表 Ethernet (10Mb),也是寫死的 - 剩下是 MAC address
也就是說,下面兩個會用同樣的 client id:
- MAC address 是
00:BE:EF:C0:FF:EE,不下 client id 的相關參數 - 下
-c 0003000100BEEFC0FFEE參數
25.12 的行為#
根據 25.12 dhcpv6.sh 的寫法,會把 dhcp_default_duid 直接塞進 odhcp6c 的 -c <clientid> 參數當 client id 來用。
25.12 砍掉 dhcp_default_duid 的行為#
回歸 24.10 的行為。
用正規方式重現 24.10 的行為#
在需要的 interface 把 clientid 設成 00030001<macaddr> 即可。
和 DHCPv4 不同,norelease 在 DHCPv6 是預設開啟的,要格外注意。
參考資料#
- Hardware Types - Address Resolution Protocol (ARP) Parameters
- BOOTP Vendor Extensions and DHCP Options - Dynamic Host Configuration Protocol (DHCP) and Bootstrap Protocol (BOOTP) Parameters
- Option Codes - Dynamic Host Configuration Protocol for IPv6 (DHCPv6)
- Comment 32 - OpenWrt 25.12.0 - Stable Release
- Problem with DHCP client and forced ClientID in v25.12
- netifd dhcp: send DHCP client ID by default
- High packet loss after upgrade to OpenWRT 25.12.0 (due to dhcp clientid changes?)