[转]linux内核网络分层结构
Preface
Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计。
Linux内核采用分层结构处理网络数据包。分层结构与网络协议的结构匹配,既能简化数据包处理流程,又便于扩展和维护。
内核网络结构
在Linux内核中,对网络部分按照网络协议层、网络设备层、设备驱动功能层和网络媒介层的分层体系设计。
网络驱动功能层主要通过网络驱动程序实现。
在Linux内核,所有的网络设备都被抽象为一个接口处理,该接口提供了所有的网络操作。
net_device结构表示网络设备在内核中的情况,也就是网络设备接口。网络设备接口既包括软件虚拟的网络设备接口,如环路设备,也包括了网络硬件设备,如以太网卡。
Linux内核有一个dev_base的全局指针,指向一个设备链表,包括了系统内的所有网络设备。该设备链表每个节点是一个网络设备。
在net_device结构中提供了许多供系统访问和协议层调用的设备方法,包括初始化、打开关闭设备、数据包发送和接收等。
与网络有关的数据结构
内核对网络数据包的处理都是基于sk_buff结构的,该结构是内核网络部分最重要的数据结构。
网络协议栈中各层协议都可以通过对该结构的操作实现本层协议数据的添加或者删除。使用sk_buff结构避免了网络协议栈各层来回复制数据导致的效率低下。

sk_buff结构可以分为两个部分,一部分是存储数据包缓存,在图中表示为PackertData,另一部分是由一组用于内核管理的指针组成。
sk_buff管理的指针最主要的是下面4个:
head指向数据缓冲(PackertData)的内核首地址;
data指向当前数据包的首地址;
tail指向当前数据包的尾地址;
end 指向数据缓冲的内核尾地址。
数据包的大小在内核网络协议栈的处理过程中会发生改变,因此data和tail指针也会不断变化,而head和tail指针是不会发生改变的。
对于一个TCP数据包为例,sk_buff还提供了几个指针直接指向各层协议头。mac指针指向数据的mac头;nh指针指向网络协议头,一般是IP协议头;h指向传输层协议头,在本例中是TCP协议头。
对各层设置指针的是方便了协议栈对数据包的处理。
net_device结构
Linux内核中网络设备最重要的数据结构就是net_device结构了,它是网络驱动程序最重要的部分。
net_device结构保存在include/linux/netdevices.h头文件,理解该结构对理解网络设备驱动有很大帮助。
内核中所有网络设备的信息和操作都在net_device设备中,无论是注册网络设备,还是设置网络设备参数,都用到该结构。
下面是主要数据成员。
设备名称
总线参数
协议参数
链接层变量
接口标志
数据包接收流程
在Linux内核中,一个网络数据包从网卡接收到用户空间需要经过链路层、传输层和socket的处理,最终到达用户空间。

以DM9000网卡为例,当网卡收到数据包以后,调用中断处理函数 dm9000_interrupt(),该函数检查中断处理类型,如果是接收数据包中断,则调用 dm9000_rx()函数接收数据包到内核空间。
dm9000_rx()函数收到数据包完成后,内核会继续调用 netif_rx()函数,函数的作用是把网卡接收到数据提交给协议栈处理。
协议栈使用 net_rx_action()函数处理接收数据包队列,该函数处理数据包后如果是 IP数据包则提交给ip_recv()函数处理。ip_recv()函数主要是检查一个数据包IP头的合法性,检查通过后交给 ip_local_deliver()和 ip_local_deliver_finish()函数处理,之所以分开处理是因为内核中有防火墙相关的代码需要动态加载到此处。
IP头处理完毕后,以UDP数据包为例将交由 udp_recv()函数处理,与 ip_recv()函数类亿,该函数检查 UDP头的合法性,然后交给 udp_queue_recv()函数处理,最后提交给 sock_queue_recv()函数处理。
数据包进入 socket部分的第一个函数是 skb_recv_datagram(),该函数从内核的 socket队列取出数据包,交给 socket部分的 udp_recvmsg()函数,该函数负责处理UDP的数据,sock_recvmsg()处理提交给 sock_read()函数。
sock_read()函数读取接收到的数据缓冲,把数据返回给 sys_read()系统调用。sys_read()函数调用最终把数据复制到用户空间,供用户使得。
数据包发送流程
以UDP数据包发送流程为例,在DM9000网卡上如何发送一个数据包。

当用户空间的应用程序通过 socket函数 sento()发送一个UDP数据后,会调用内核空间的 sock_writev()函数,然后通过 sock_sendmsg()函数处理。sock_sendmsg()函数调用 inet_sendmsg()函数处理,inet_sendmsg()函数会把要发送的数据交给传输层的 udp_sendmsg()函数处理。
udp_sendmsg()函数在数据前加入UDP头,然后把数据交给 ip_build_xmit()函数处理,该函数根据 socket提供的目的 IP和端口信息构造IP头,然后调用 output_maybe_reroute()函数处理。out_maybe_reroute()函数检查数据包是否需要经过路由,最后交给 ip_output()函数写入到发送队列,写入完成后由 ip_finish_output()函数处理后续工作。
链路层的 dev_queue_xmit()函数处理发送队列,调用 DM9000网卡的发送数据包函数 dm9000_xmit()发送数据包,发送完毕后,调用 dm9000_xmit_done函数处理发送结果。
本文转自http://infohacker.blog.51cto.com/6751239/1221140
[转]linux内核网络分层结构的更多相关文章
- 【驱动】网卡驱动·linux内核网络分层结构
Preface Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计. Linux内核采用分层结构处理网络数据包.分层结构与网络协议的结构匹配,既能简化数据包处理流程 ...
- Linux 网络设备驱动开发(一) —— linux内核网络分层结构
Preface Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计. Linux内核采用分层结构处理网络数据包.分层结构与网络协议的结构匹配,既能简化数据包处理流程,又 ...
- Linux内核--网络栈实现分析(十一)--驱动程序层(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7555870 更多请查看专栏,地 ...
- Linux内核--网络栈实现分析(七)--数据包的传递过程(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地 ...
- Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7497260 更多请看专栏,地址 ...
- Linux内核--网络栈实现分析(一)--网络栈初始化
本文分析基于内核Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7488828 更多请看专栏, ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程--转
转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...
- Linux内核--网络栈实现分析(一)--网络栈初始化--转
转载地址 http://blog.csdn.net/yming0221/article/details/7488828 作者:闫明 本文分析基于内核Linux Kernel 1.2.13 以后的系列博 ...
- Linux内核网络数据包处理流程
Linux内核网络数据包处理流程 from kernel-4.9: 0. Linux内核网络数据包处理流程 - 网络硬件 网卡工作在物理层和数据链路层,主要由PHY/MAC芯片.Tx/Rx FIFO. ...
随机推荐
- (学)如何在Oracle中一次执行多条sql语句
队长同学原来的地址:https://www.cnblogs.com/teamleader/archive/2007/05/31/765943.html队长同学原来的描述: 有时我们需要一次性执行多条s ...
- [GIT] Git 工作流程(Git flow, Github flow flow, Git lab flow)
reference : http://www.ruanyifeng.com/blog/2015/12/git-workflow.html Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必 ...
- 【BZOJ】【1006】【HNOI2008】神奇的国度
弦图最小染色/MCS算法 Orz PoPoQQQ (UPD:ydc的写法好像更熟悉一些……(类似堆优化的Dij啊~ 先留个坑……明天再看一看……感觉好神奇>_<(完美消除序列之于弦图 就 ...
- UVA 10026 Shoemaker's Problem
Shoemaker's Problem Shoemaker has N jobs (orders from customers) which he must make. Shoemaker can w ...
- there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
建表语句: create table test_table( id integer not null auto_increment primary key, stamp_created tim ...
- JMS基本概念之一
The Java Message Service(JMS) API is a messaging standard that allows application components based o ...
- Objective-C:NSValue类的常见用法
特殊类型的包装类:数组.结构体(OC内部的.自定义的).指针 // // main.m // 05-NSValue // // Created by ma c on 15/8/17. // Copyr ...
- JDBC 通过PreparedStatement 对数据库进行增删改查
1 插入数据 public boolean ChaRu3(User user){ boolean flag=true; Connection conn=null; PreparedStatement ...
- C++中对Mysql的操作函数可以参考以下blog中的内容
http://www.cnblogs.com/lovebread/archive/2009/11/24/1609936.html
- jquery中filter(fn)的使用研究
jquery中filter(fn)给出的官方说明是: 筛选出与指定函数返回值匹配的元素集合 这个函数内部将对每个对象计算一次 (正如 '$.each'). 如果调用的函数返回false则这个元素被删除 ...