Q:使用者空間調用ioctl操作網卡裝置行為時,調用鍊是什麼樣的?不同的socket類型是否也不一樣?
先來看一下系統調用ioctl的調用鍊是什麼樣的,請看下表
函數名稱 | 檔案名 | 做了什麼 |
---|---|---|
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) | fs/ioctl.c | ioctl函數入口 |
do_vfs_ioctl | fs/ioctl.c | 真正入口,這個函數裡邊會區分哪些是針對真正的檔案進行操作的,哪些是針對虛拟檔案進行操作的,顯然socket這類的ioctl就屬于虛拟檔案 |
vfs_ioctl | fs/ioctl.c | 這個函數會根據檔案描述符的指針找到檔案操作指針f_op對應的指針接口函數unlocked_ioctl,那麼這個unlocked_ioctl的函數指針在哪裡注冊的呢?net/socket.c裡邊調用系統調用socket建立sock檔案描述符的時候通過sock_map_fd函數再調用函數sock_alloc_file,這個函數裡邊會将socket_file_ops注入到socket檔案描述符裡邊,有的人會好奇網卡驅動裡邊也有關于unlocked_ioctl函數指針的注冊,那網卡驅動的ioctl是怎麼被調用的呢?網卡驅動的ioctl是先open一個/dev/netdeviceName,然後再調用ioctl傳遞裝置的檔案描述符。 |
sock_ioctl | net/socket.c | 函數入口則判斷輸入的cmd指令是否屬于[SIOCDEVPRIVATE, SIOCDEVPRIVATE+15]這個區間,如果屬于則調用dev_ioctl函數去操作裝置驅動相關功能接口進行設定,如果不在這個區間則針對各個cmd進行處理,如果這個函數的cmd都沒對應的處理動作,則調用sock_do_ioctl進行處理 |
sock_do_ioctl | net/socket.c | 這個函數根據sock->ops調用各自的ioctl指針,這裡就是轉到各family子產品去處理了,比如netlink子產品就去調用net/netlink/af_netlink.c下的sock_no_ioctl,pf_packet則調用net/packet/af_packet.c下的packet_ioctl,如果各子產品的ioctl函數處理之後傳回ENOIOCTLCMD錯誤即找不到指令,則仍然調用dev_ioctl去處理 |
dev_ioctl | net/core/dev_ioctl.c | 這個函數主要針對真實網卡驅動進行設定,比如設定多點傳播接收以及混雜模式等。 |
有了上面的分析,我們可以回答第二個問題,如果是針對網卡進行的操作,無論通過哪種family類型的socket,就是可以的,但是針對指定family特有的CMD則需要區分。
參考文章: IOCTL in Linux (I/O Control) – Linux Device Driver Tutorial Part 8