linux论坛搭建(网页版linux系统链接网络源码)
源码目录
linux-1.2.13
|
|---net
|
|---protocols.c
|---socket.c
|---unix
||
||---proc.c
||---sock.c
||---unix.h
|---inet
|
|---af_inet.c
|---arp.h,arp.c
|---...
|---udp.c,utils.c
其中unix子文件夹中三个文件是有关UNIX域代码,UNIX域是模拟网络传输方式在本机范围内用于进程间数据传输的一种机制。
系统调用通过INT$0x80进入内核执行函数,该函数根据AX寄存器中的系统调用号,进一步调用内核网络栈相应的实现函数。
网络分层
从这个图中,可以看到,到传输层时,横生枝节,代码不再针对任何数据包都通用。从下到上,收到的数据包由哪个传输层协议处理,根据从数据包传输层header中解析的数据确定。从上到下,数据包的发送使用什么传输层协议,由socket初始化时确定。
1、vfs层
2、socket是用于负责对上给用户提供接口,并且和文件系统关联。
3、sock,负责向下对接内核网络协议栈
4、tcp层和ip层,linux 1.2.13相关方法都在tcp_prot中。在高版本linux中,sock负责tcp层,ip层另由struct inet_connection_sock和icsk_af_ops负责。分层之后,诸如拥塞控制和滑动窗口的字段和方法就只体现在struct sock和tcp_prot中,代码实现与tcp规范设计是一致的
5、ip层负责路由等逻辑,并执行nf_hook,也就是netfilter。netfilter是工作于内核空间当中的一系列网络(TCP/IP)协议栈的钩子(hook),为内核模块在网络协议栈中的不同位置注册回调函数(callback)。也就是说,在数据包经过网络协议栈的不同位置时做相应的由iptables配置好的处理逻辑。
6、link层,先寻找下一跳(ip==>mac),有了MAC地址,就可以调用dev_queue_xmit发送二层网络包了,它会调用__dev_xmit_skb会将请求放入块设备的队列。同时还会处理一些vlan的逻辑
7、设备层:网卡是发送和接收网络包的基本设备。在系统启动过程中,网卡通过内核中的网卡驱动程序注册到系统中。而在网络收发过程中,内核通过中断跟网卡进行交互。网络包的发送会触发一个软中断NET_TX_SOFTIRQ来处理队列中的数据。这个软中断的处理函数是net_tx_action。在软中断处理函数中,会将网络包从队列上拿下来,调用网络设备的传输函数ixgb_xmit_frame,将网络包发的设备的队列上去。
网卡中断处理程序为网络帧分配的,内核数据结构sk_buff缓冲区;是一个维护网络帧结构的双向链表,链表中的每一个元素都是一个网络帧(Packet)。虽然TCP/IP协议栈分了好几层,但上下不同层之间的传递,实际上只需要操作这个数据结构中的指针,而无需进行数据复制。
网络与文件操作
VFS为文件系统抽象了一套API,实现了该系列API就可以把对应的资源当作文件使用,当调用socket函数的时候,我们拿到的不是socket本身,而是一个文件描述符fd。
从linux5.9看网络层的设计整个网络层的实际中,主要分为socket层、af_inet层和具体协议层(TCP、UDP等)。当使用网络编程的时候,首先会创建一个socket结构体(socket层),socket结构体是最上层的抽象,然后通过协议簇类型创建一个对应的sock结构体,sock是协议簇抽象(af_inet层),同一个协议簇下又分为不同的协议类型,比如TCP、UDP(具体协议层),然后根据socket的类型(流式、数据包)找到对应的操作函数集并赋值到socket和sock结构体中,后续的操作就调用对应的函数就行,调用某个网络函数的时候,会从socket层到af_inet层,af_inet做了一些封装,必要的时候调用底层协议(TCP、UDP)对应的函数。而不同的协议只需要实现自己的逻辑就能加入到网络协议中。
file_operations结构定义了普通文件操作函数集。系统中每个文件对应一个file结构,file结构中有一个file_operations变量,当使用write,read函数对某个文件描述符进行读写操作时,系统首先根据文件描述符索引到其对应的file结构,然后调用其成员变量file_operations中对应函数完成请求。
//参见socket.c
static struct file_operations socket_file_ops={
sock_lseek,//?′êμ??
sock_read,
sock_write,
sock_readdir,//?′êμ??
sock_select,
sock_ioctl,
NULL,/*mmap*/
NULL,/*no special open code...*/
sock_close,
NULL,/*no fsync*/
sock_fasync
};
以上socket_file_ops变量中声明的函数即是网络协议对应的普通文件操作函数集合。从而使得read,write,ioctl等这些常见普通文件操作函数也可以被使用在网络接口的处理上。kernel维护一个struct file list,通过fd==>struct file==>file->ops==>socket_file_ops,便可以以文件接口的方式进行网络操作。同时,每个file结构都需要有一个inode结构对应。用于存储struct file的元信息
struct inode{
...
union{
...
struct ext_inode_info ext_i;
struct nfs_inode_info nfs_i;
struct socket socket_i;
}u
}
也就是说,对linux系统,一切皆文件,由struct file描述,通过file->ops指向具体操作,由file->inode存储一些元信息。对于ext文件系统,是载入内存的超级块、磁盘块等数据。对于网络通信,则是待发送和接收的数据块、网络设备等信息。从这个角度看,struct socket和struct ext_inode_info等是类似的。
免责声明:本文由用户上传,如有侵权请联系删除!