1. 程式人生 > >ioctl配置IP地址 Linux核心實現分析

ioctl配置IP地址 Linux核心實現分析

1 執行flow

本文以Linux kernel3.10版本描述

上圖是《Understanding LINUX NETWORK INTERNALS》一書中對socket的ioctl呼叫的整體flow,本文只對其中SIOCSIFADDR這一個command進行flow的梳理。

首先是socket的建立,這在上圖中沒有標識出來,大致flow如下圖所示,這部分原始碼在 net/socket.c中

socket的create對ioctl的作用主要有兩點:

1、如何在執行ioctl時,呼叫到sock_ioctl

在建立inode時,將socket_file_ops賦給inode→i_fop。這樣在執行ioctl時,通過執行在inode的函式指標,最終呼叫的就是sock_ioctl

函式。

如不理解上一句話,可參考如下解釋:

    socket_file_ops 是socket 檔案中 file_operations結構體的實現的物件(全域性變數)。在每次create socket時,均將該全域性變數的指標賦給inode→i_fop.

    每次執行ioctl時,是執行的inode→i_fop->(*unlocked_ioctl),而socket_file_ops→unlocked_ioctl 賦值是sock_ioctl函式的指標

    所以每次在對socket執行ioctl時,最終執行的是sock_ioctl

    該賦值在socket_alloc_file函式中實現,呼叫鏈是sock_map_fd →sock_alloc_file

2、如何根據SIOCSIFADDR,最終呼叫至inet_ioctl

在socket create時,會執行pf->create函式,該函式會將inet_ioctl函式指標賦值給sock->ops→ioctl

詳細說明:

    pf通過socket create時的family,找到對應pf,執行其中的create函式。

    family為AF_INET時,呼叫的create為 net/af_inet.c中的inet_create函式.

    在pf→create函式中,通過type找到對應ioctl函式,賦值給sock->ops

    type為SOCK_DGRAM時,對應ioctl為inet_ioctl

根據以上兩點大致可以理解在《Understanding LINUX NETWORK INTERNALS》一書中的socket 執行ioctl的flow

一開始,執行到sock_ioctl,該函式中根據cmd,執行sock→ops→ioctl

在上面2點可知,執行sock→ops→ioctl即執行inet_ioctl

inet_ioctl根據cmd,執行devinet_ioctl

所以最終執行的是devinet_ioctl函式

devinet_ioctl的實現在net/devinet.c中

devinet_ioctl函式的執行flow大致如下圖所示:

 

 根據ifr.ifr_name的名稱,找到對應的in_device結構體,並找到對應的ifa結構體

將ifa重置ifaddr為設定ip,最後在重新新增至in_device結構體中。

SIOCGIFADDR 的flow便是將在找到ifa結構體後,將ifa中的addr set回sin_addr返回

2 資料結構

上部分主要寫了ioctl的執行flow和做了哪些事,可以看出,其中in_device與

in_device如下:

kernel network中比較重要的兩個結構體net_device和in_device,net_device主要用於核心自身(驅動以及上層協議等)對網路裝置的操作;

而in_device用於儲存使用者態對此裝置的配置,比如ip地址的配置等,儲存在in_device。兩個結構體通過指標互指聯絡在一起。