Linux网卡驱动(3)-网卡驱动深层分析
来源:互联网 发布:淮南大数据公司 编辑:程序博客网 时间:2024/04/30 13:09
之前我们介绍了网卡是怎么把一个数据包发送到网络上的,但是这只是Linux网络系统中的一个非常小的部分。对于内核怎么把用户数据传递给网卡,以及内核怎么把网卡收到的数据传递给用户是一个庞大的知识。
学过计算机网络的都知道,当用户需要发送数据的时候,需要根据路由表找到数据包下一站该发送到哪个路由器,这个路由器叫做这个网卡的邻居。如果邻居的MAC地址不知道,还需要通过ARP协议获取的路由去的MAC地址,这个过程交给邻居子系统来完成。
分析过程还是依据第一节课中的5层模型来分析:
1、系统调用接口
2、协议无关层
3、网络协议栈
4、设备无关层
5、硬件驱动
当用户调用write系统调用时,内核是用哪个函数来响应的呢?在第一节课中我们知道soket有一个操作函数集,socket_file_ops:
/* *Socket files have a set of 'special' operations as well as the generic file ones. These don't appear *in the operation structures but are done directly via the socketcall() multiplexor. */static const struct file_operations socket_file_ops = {.owner =THIS_MODULE,.llseek =no_llseek,.aio_read =sock_aio_read,.aio_write =sock_aio_write,.poll =sock_poll,.unlocked_ioctl = sock_ioctl,#ifdef CONFIG_COMPAT.compat_ioctl = compat_sock_ioctl,#endif.mmap =sock_mmap,.open =sock_no_open,/* special open code to disallow open via /proc */.release =sock_close,.fasync =sock_fasync,.sendpage =sock_sendpage,.splice_write = generic_splice_sendpage,.splice_read =sock_splice_read,};调用write函数时会调用到aio_write这个函数,这个函数又是由socket_aio_write实现的,我们寻本朔源可以知道调用过程是sock_aio_write->do_sock_write->__sock_sendmsg->sock->ops->sendmsg。到这里这些函数的处理过程都是属于系统调用接口和协议无关层的。接下来就会使用具体的方式函数来实现各种协议包的发送。
假如说我们需要发送一个UDP的包,这个包是用哪个函数发送出去的呢?
其实是用udp_sendmsg来实现的,这个函数就是协议栈的入口了。我们分析这段代码的实现过程:
这段代码最重要的2个操作就是
1、获取路由表的信息,通过路由找到下一站发送的IP地址,使用的是ip_route_output_flow
2、接下来就是把数据发送出去了,使用的是udp_push_pending_frames,在这个函数里面他又调用ip_push_pending_frames把这个数据包转换成ip包后发送出去。
3、在ip_push_pending_frames发送数据包的过程中,经过层层调用后最终使用ip_finish_output2来发送数据,这里面会判断是否有邻居子系统,如果有使用neigh_hh_output这个数据包,如果没有它会构造一个邻居子系统。到这里,协议栈的方式过程就算结束了,接下来是设备无关接口。
在设备无关接口中使用的发送函数是dev_queue_xmit。最终使用对应的网卡把这个数据包发送出去。下面这幅图描述的是数据包从IP协议到设备驱动的调用关系。
网络数据的接收的过程可以参考下面这幅图:
- Linux网卡驱动(3)-网卡驱动深层分析
- Linux网卡驱动分析
- Linux网卡驱动分析
- Linux网卡驱动分析
- Linux网卡驱动分析
- Linux网卡驱动分析
- LINUX网卡驱动分析
- linux网卡驱动-3
- CS8900 Linux 网卡驱动分析
- Linux网卡驱动分析--zz
- Linux网卡l8139驱动分析
- Linux有线网卡驱动分析
- linux网卡驱动源码分析
- linux网卡驱动分析之驱动加载
- linux网卡驱动分析之驱动加载
- ARM-Linux驱动--DM9000网卡驱动分析
- Linux网卡驱动(1)-网卡驱动架构分析
- 【驱动】DM9000网卡驱动分析
- Utils帮助类(半角转为全角和去除特殊字符或将所有中文标号替换为英文标号)
- HTML5 中的新特性
- opencv之轮廓特征属性及应用
- easyui-datagrid实例
- [LeetCode] 268. Missing Number
- Linux网卡驱动(3)-网卡驱动深层分析
- Oracle12c安装记录(centos6.5,命令行)
- org.hibernate.exception.SQLGrammarException: could not execute batch
- 10 个非常有用的 SVG 动画的 JavaScript 库
- linux下静态库和动态库的创建和使用
- oracle汉字转拼音(获得全拼/拼音首字母/拼音截取等)
- Android中Context详解 ---- 你所不知道的Context
- XPATH CSS PATH CHEAT SHEET
- 负数的二进制处理