ifrename 命令與 net.ifrenames 內核啓動參數

很多網卡驅動在加載時會對虛擬網絡接口的名稱進行重命名。下面是我的系統上 dmesg 中的部分輸出,可以看到最開始虛擬網絡接口的名稱爲 eth0,最後一行的信息中可以看到接口名稱被改爲了 enp2s0。

[    4.218735] r8169 0000:02:00.0 eth0: RTL8168h/8111h, 80:e8:2c:17:f0:77, XID 54100880, IRQ 126
[    4.218736] r8169 0000:02:00.0 eth0: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[    4.219142] xhci_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x110 quirks 0x0000000000009810
[    4.219146] xhci_hcd 0000:00:14.0: cache line size of 64 is not supported
[    4.219322] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 4.19
[    4.219324] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.219325] usb usb1: Product: xHCI Host Controller
[    4.219326] usb usb1: Manufacturer: Linux 4.19.0-9-amd64 xhci-hcd
[    4.219327] usb usb1: SerialNumber: 0000:00:14.0
[    4.219435] hub 1-0:1.0: USB hub found
[    4.219456] hub 1-0:1.0: 12 ports detected
[    4.220818] r8169 0000:02:00.0 enp2s0: renamed from eth0

一般來說上述行爲並沒有啥影響,但在特定的業務場景下可能需要禁止這種行爲。要禁止這種行爲,可以通過設定 linux 內核啓動參數 net.ifrenames 來實現。

設定 net.ifrenames=0 ,表示不對 netdev 重命名,這樣網絡接口名稱將會保持 eth0、eth1 這種模式的名字。

如何動態修改 netdev name

一些系統中,有根據網口的不同功能重命名 netdev 的需求。這可以通過調用 ifrename 命令來完成。這個命令在我的系統中並沒有安裝,我首先執行如下命令,搜索需要安裝的程序名。

[longyu@debian-10:22:10:50] ~ $ sudo apt-cache search ifrename
ifrename - Rename network interfaces based on various static criteria

從上面的輸出中,我確定需要安裝的程序名就是 ifrename。執行如下命令安裝 ifrename 命令。

[longyu@debian-10:22:11:07] ~ $ sudo apt-get install ifrename
正在讀取軟件包列表... 完成
正在分析軟件包的依賴關係樹       
正在讀取狀態信息... 完成       
下列【新】軟件包將被安裝:
  ifrename
升級了 0 個軟件包,新安裝了 1 個軟件包,要卸載 0 個軟件包,有 67 個軟件包未被升級。
需要下載 53.9 kB 的歸檔。
解壓縮後會消耗 128 kB 的額外空間。
獲取:1 https://mirrors.tuna.tsinghua.edu.cn/debian buster/main amd64 ifrename amd64 30~pre9-13 [53.9 kB]
已下載 53.9 kB,耗時 4秒 (13.2 kB/s)
正在選中未選擇的軟件包 ifrename。
(正在讀取數據庫 ... 系統當前共安裝有 354686 個文件和目錄。)
準備解壓 .../ifrename_30~pre9-13_amd64.deb  ...
正在解壓 ifrename (30~pre9-13) ...
正在設置 ifrename (30~pre9-13) ...
invoke-rc.d: policy-rc.d denied execution of start.
正在處理用於 systemd (241-7~deb10u4) 的觸發器 ...
正在處理用於 man-db (2.8.5-2) 的觸發器 ...

安裝成功後,man ifrename 查看如何使用這個命令。下面是 man ifrename 的部分輸出。

      ifrename [-c configfile] [-p] [-d] [-u] [-v] [-V] [-D] [-C]
       ifrename [-c configfile] [-i interface] [-n newname]

注意 ifrename 必須在接口被 up 之前執行,不能對一個 up 的接口執行 ifrename 操作,可以將這樣的行爲理解爲,在 up 的時候 ifrename 被引用。這表明 down 掉接口就可以修改名字了。

一個具體的示例如下:

[longyu@debian-10:22:41:28] arm64 $ sudo /sbin/ifconfig enp2s0 down
[longyu@debian-10:22:41:32] arm64 $ sudo ifrename -i enp2s0 -n eth0
eth0
[longyu@debian-10:22:41:45] arm64 $ /sbin/ifconfig eth0
eth0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 80:e8:2c:17:f0:77  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在上面的示例中,我首先使用 ifconfig down 掉接口,然後執行 ifrename 將網絡接口名稱從 enp2s0 修改爲 eth0,這之後 ifconfig eth0 查看接口信息確認修改成功。

這時候查看 dmesg 的輸出信息,發現有下面的輸出:

[ 4288.006591] r8169 0000:02:00.0 eth0: renamed from enp2s0

使用 strace 命令查看系統調用過程,發現核心的過程在於下面兩個系統調用:

socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
ioctl(3, SIOCSIFNAME, {ifr_name="eth0", ifr_newname="enp2s0"}) = 0

上面的兩個系統調用首先執行 socket 打開一個網絡設備,然後通過 ioctl 命令來修改網絡設備的配置。

內核裏面的流程如下所示:

sock_ioctl -> sock_do_ioctl -> dev_ioctl -> dev_ifsioc -> dev_change_name

最終是通過調用 dev_change_name 函數來完成虛擬網卡接口重命名的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章