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。两个结构体通过指针互指联系在一起。

猜你喜欢

转载自blog.csdn.net/qq_28351465/article/details/83344025
今日推荐