Ethtool工具源碼剖析
ethool是一個實用的工具,用來給系統管理者以大量的控制網絡接口的操作。可以用來控制接口參數,速度,媒體類型,雙工模式,DMA環設定,硬體校驗和,LAN喚醒操作等。本人經常用于來觀測實體鍊路層的連結狀态,用于判斷網線是否正常,不用去機房看網卡亮沒亮燈了。
ethtool的版本通過如下指令進行檢視:
# ethtool --version
ethtool version 4.5
其源碼位于何處呢?
1.1.1 源碼
編譯也很簡單:
執行./configure後,運作make指令直接進行編譯。
相比之前的ifconfig和netstat工具要複雜更多,畢竟ethtool從至此的參數上來也更加龐大。
1.1.2 資料結構體
static const struct option {
const char *opts;
int want_device;
int (*func)(struct cmd_context *);
char *help;
char *opthelp;
}
因為ethtool參數複雜龐大,是以單獨定義了結構體option。第一個是參數選項,第二個是bool值,第三個是回調函數,第四個核第五個是幫助的字元串。所有的處理函數都在option的結構體數組args[]中設定了,如:do_gdrv擷取驅動資訊 , do_gset 擷取網卡參數 ,do_sset設定網卡參數 等。
結構體cmd_context是控制結構體。
/* Context for sub-commands */
struct cmd_context {
const char *devname; /* net device name */
int fd; /* socket suitable for ethtool ioctl */
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
int argc; /* number of arguments to the sub-command */
char **argp; /* arguments to the sub-command */
};
1.1.3 程式邏輯
從ethtool.c中main主函數開始,首先分析傳入參數。如果沒有參數,則調用exit_bad_args函數來輸出。
第一個參數要麼是裝置名字要麼是合法的選項,而不是一個以’-‘開頭的。
根據輸入的參數,會将func變量設定為結構體option中的回調函數。
最後調用設定過的func函數(例如do_gset函數),參數為cmd_context結構體,其中填充了相關參數(例如裝置名,套接字句柄等)。
我們可以看到,程式主邏輯非常的清晰,主要是每個參數下其針對的處理函數才是根據需要分析的重點。
例如參數-s為例,其選項結構為:
{ "-s|--change", 1, do_sset, "Change generic options",
" [ speed %d ]\n"
" [ duplex half|full ]\n"
" [ port tp|aui|bnc|mii|fibre ]\n"
" [ mdix auto|on|off ]\n"
" [ autoneg on|off ]\n"
" [ advertise %x ]\n"
" [ phyad %d ]\n"
" [ xcvr internal|external ]\n"
" [ wol p|u|m|b|a|g|s|d... ]\n"
" [ sopass %x:%x:%x:%x:%x:%x ]\n"
" [ msglvl %d | msglvl type on|off ... ]\n" },
可以看到其調用的函數為do_sset,該函數會對參數進行詳細的解析,最後确定使用者意圖後調用send_ioctl函數。當然會根據參數的差異,調用不同的參數。
例如會調用函數:send_ioctl(ctx, &ecmd);或者send_ioctl(ctx, &edata)等(send_ioctl調用ioctl系統調用,ioctl是裝置驅動程式中對裝置的I/O通道進行管理的函數,對裝置的一些特性進行控制,例如序列槽的傳輸波特率、馬達的轉速等等)。其中edata為ethtool_value結構體,ecmd為ethtool_command,還有ethtool_wolinfo。
這些結構體都定義在include/uapi/linux/ethtool.h檔案中。
1.1.4 驅動支援
現在網卡驅動程式都有對ethtool 的支援。ethtool 架構包含核心空間和使用者空間兩部分:使用者空間的部分負責将 ethtool 指令發送到核心,然後接收指令在核心中的執行結果。
核心空間的部分根據相應的指令字,通過 MDIO/MDC 讀寫 MII 寄存器,實作對網卡的管理,并把執行結果傳回使用者空間,如下圖所示。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SNhR2NlR2N3E2MyYjNhRTNyAjMmV2NyEjZkRDM0czM28CX2EzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
ethtool擔負着使用者空間和具體網絡裝置驅動之間的互動,包括查詢、設定網卡資訊。相關聲明在include/linux/ethtool.h檔案中,核心是ethtool_ops類型的結構。