Linux协议栈代码阅读笔记(二)网络接口的配置
(基于linux-2.6.11)

(一)用户态通过C库函数ioctl进行网络接口的配置

例如,知名的ifconfig程序,就是通过C库函数sys_ioctl实现网络接口的配置的。
具体方法大致如下,即建立一个socket,得到一个fd,然后在此fd上执行ioctl即可完成各种操作(例如,查询/配置mac、ip、mtu,启动/停止网络接口)。
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ioctl(fd, SIOCGIFFLAGS, (caddr_t)&ifr);

(二)上述C库函数如何与内核交互
C库代码准备好相应的工作后(例如,设置系统调用号啦、参数构造啦、栈啦、寄存器设置啦),通过系统调用指令,进入内核态。从内核返回后,C库函数再做相应的善后工作,然后将结果返回给用户程序。

这部分代码,不同架构的处理器,有不同的实现。

(三)内核态如何处理用户的网络通讯请求
上一步,C库发起了系统调用,根据系统调用号,进入系统调用表的相应表目。ioctl对应的是54号系统调用,即sys_ioctl函数。
此函数的代码如下(源码文件:fs\Ioctl.c),最终通过vfs_ioctl完成操作。
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
 struct file * filp;
 int error = -EBADF;
 int fput_needed;

filp = fget_light(fd, &fput_needed);
 if (!filp)
  goto out;

error = security_file_ioctl(filp, cmd, arg);
 if (error)
  goto out_fput;

error = vfs_ioctl(filp, fd, cmd, arg);
 out_fput:
 fput_light(filp, fput_needed);
 out:
 return error;
}

(四)vfs_ioctl内部的执行路径
由于我们的fd对应的是一个socket,并且我们的操作是配置网络接口。因此,进入vfs_ioctl后的函数执行路径如下:
do_ioctl
filp->f_op->ioctl(即socket_file_ops.unlocked_ioctl,也就是sock_ioctl)
sock->ops->ioctl(即inet_dgram_ops.ioctl,也就是inet_ioctl)
接下来的工作,就看具体的操作了。

如果是ip层的设置,基本上都是围绕网络接口对应的in_device结构变量进行操作。IP地址啦、多播信息啦,就在这里了。

如果是L2层的设置,基本上都是围绕网络接口对应的net_device结构变量进行操作。接口名称、mtu什么的,就在这里了。

(每一个网络接口对应一个net_device结构变量,__dev_get_by_name函数能够根据接口名称查找到对应的net_device结构。net_device实际上是in_device结构的一个成员,__in_dev_get_rtnl返回某个net_device结构所属的in_device的地址)

大体来说,L2层的设置,通常就是设置/获取net_device结构变量中相关成员的值。例如,获取接口mtu,就是获取dev->mtu的值。

当然,有些操作需要调用网络接口的驱动程序中的相关函数,net_device结构中有这些函数的地址,直接调用即可。

另外,有些操作完成后,还需要通知那些注册了关心此事件的内核模块。

例如,mac地址变化后,会通过如下形式通知其他内核模块。

notifier_call_chain(&netdev_chain,  NETDEV_CHANGEADDR, dev);

至于IP层的设置,在下还没有理解其代码,这里就不描述了。

下面列出部分操作对应的函数。

1)设置/查询ip、广播地址等操作,执行sock->ops->ioctl函数(即inet_dgram_ops.ioctl,也就是inet_ioctl)
例如:

设置ip地址涉及的执行路径(从inet_ioctl内部开始):

devinet_ioctl

inet_set_ifa

inet_insert_ifa

2)设置/查询接口名称、mac地址、mtu等,执行dev_ioctl函数。

例如:

设置mtu涉及到的执行路径(从dev_ioctl内部开始):
dev_ifsioc
dev_set_mtu
dev->change_mtu(以Intel(R)的e1000网卡为例,dev->change_mtu对应的函数是网卡驱动中的e1000_change_mtu。源码:drivers\net\e1000\E1000_main.c)
raw_notifier_call_chain(&netdev_chain,    NETDEV_CHANGEMTU, dev);  //通知内核中关心mtu变化事件的模块

[置顶] Linux协议栈代码阅读笔记(二)网络接口的配置的更多相关文章

  1. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  2. Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  3. <<梦断代码>>阅读笔记二

    这是第二篇读书笔记,这本书我已经读了有一大半了,感觉书中所描述的人都是疯子,一群有创造力,却又耐得住寂寞的疯子. 我从书中发现几点我比较感兴趣的内容. 第一个,乐高之梦.将程序用乐高积木一样拼接起来. ...

  4. Detectron2源码阅读笔记-(二)Registry&build_*方法

    ​ Trainer解析 我们继续Detectron2代码阅读笔记-(一)中的内容. 上图画出了detectron2文件夹中的三个子文件夹(tools,config,engine)之间的关系.那么剩下的 ...

  5. Linux-3.0.8 input subsystem代码阅读笔记

    先乱序记录一下阅读Linux input subsystem代码的笔记. 在input device driver的入口代码部分,需要分配并初始化input device结构,内核提供的API是inp ...

  6. 《Java编程思想》阅读笔记二

    Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...

  7. Bleve代码阅读(二)——Index Mapping

    引言 Bleve是Golang实现的一个全文检索库,类似Lucene之于Java.在这里通过阅读其代码,来学习如何使用及定制检索功能.也是为了通过阅读代码,学习在具体环境下Golang的一些使用方式. ...

  8. Linux系统运维笔记(二),Linux文件编辑命令

    Linux系统运维笔记 Linux文件编辑命令 首先我们使用命令 vi filename 打开一个文件,这个时候进入到的是命令模式 接下来我们按i,然后键盘随便输入写内容. 然后按ESC重新进入到命令 ...

  9. Java Jdk1.8 HashMap源代码阅读笔记二

    三.源代码阅读 3.元素包括containsKey(Object key) /** * Returns <tt>true</tt> if this map contains a ...

随机推荐

  1. 【C#/WPF】Image图片的Transform变换:平移、缩放、旋转

    WPF中图像控件Image的变换属性Transform: 平移 缩放 旋转 即要想实现图片的平移.缩放.旋转,是修改它所在的Image控件的Transform变换属性. 下面在XAML中定义了Imag ...

  2. 【大数据笔记】白话详解Zookeeper的一致性

    下面内容主要摘抄于<<Hadoop实战>>,红色高亮部分是本人添加的白话注释. Zookeeper 是一种高性能.可扩展的服务. Zookeeper 的读写速度非常快,并且读的 ...

  3. sed: 1: “…”: invalid command code on Mac OS

    昨天因为项目中有很多文件的同一个变量需要批量替换成另一个,想用sed做这个.Linux 这样其实就可以了 ~# sed -i “s/string_old/string_new/g” grep -rl ...

  4. FastDFS - 文件服务器学习资料

    FastDFS搭建及java整合代码 CentOS 6.5下 FastDFS结合Nginx插件实现图片http访问 图片服务器fastDFS的搭建以及配置 nginx fastdfs 配置后 上传成功 ...

  5. 完美解决方案:wordpress后台进不去,用户名、密码输入了登陆没有反应(有更新)

    http://mingming4745.blog.163.com/blog/static/173845720119159425890/?suggestedreading ——————————————— ...

  6. PHP并发IO编程之路

    并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO.协程.PHP程序员因为有强大的LAMP框架,对这类底层方面的知识知之甚少, ...

  7. 创建ajax对象并兼容多个浏览器方法简单记录

    这篇文章主要介绍了如何创建ajax对象并兼容多个浏览器,需要的朋友可以参考下<script> function createAjax(){ var request=false; //win ...

  8. LoadRunner性能测试基础知识问答

    Q1:什么是负载测试?什么是性能测试? A1:负载测试是通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足性能指标的情况下,系统所能承受的最大负载量的测试,例如,访问一个页面的响应时间规定不超 ...

  9. Qt中的串口编程之一

    QtSerialPort 简介 功能介绍 SerialPort SerialPortInfo 源代码 编译和安装 配置编译环境 Perl只是在Qt5的时候才需要Qt4的情况下可以不配置 使用如下推荐步 ...

  10. Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering

    Defferrard, Michaël, Xavier Bresson, and Pierre Vandergheynst. "Convolutional neural networks o ...