设为首页 | 加入收藏

欢迎访问幸运彩票app手机下载-幸运彩票app安卓版下载-幸运彩票下载安装

幸运彩票33372 >> 幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序

本文作者: M. Jones, 原文地址:https://www.ibm.com/developerworks/cn/linux/l-linux-networking-stack/

协议简介

虽然关于网络的正式介绍一般都参阅了 OSI(Open Systems Interconnection)模型,可是本文对 Linux 中根本网络栈的介绍分为四层的 Internet 模型(如图 1 所示)。

图 1. 网络栈的 Internet 模型

这个栈的最底部是链路层。链路层是指供给对物理层拜访的设备驱动程序,这可所以各种介质,例如串口链路或以太网设备。链路层上面是网络层,它担任将报文定向到方针方位。再上一层称为传输层,担任端到端的通讯(例如,在一台主机内部)。虽然网络层担任办理主机之间的通讯,可是传输层需求担任办理主机内部各端之间的通讯。终究一层是应用层,它一般是一个语义层,能够了解要传输的数据。例如,超文本传输协议(HTTP)就担任传输服务器和客户机之间对 Web 内容的恳求与呼应。

实践来说,网络栈的各个层次有一些更为人所熟知的姓名。在链路层上,能够找到以太网,这是最常用的一种高速介质。更早的链路层协议包含一些串口协议,例如 SLIP(Serial Line Internet Protocol)、CSLIP(Compressed SLIP)和PPP(Point-to-Point Protocol)。最常见的网络层协议是 IP(Internet Protocol),可是网络层中还存在一些满意其他需求幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序的协议,例如 ICMP(Internet Control Message Protocol)和ARP( Address Resolution Protocol)。在传输层上是 TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)。终究,应用层中包含许多我们都十分了解的协议,包含规范的 Web 协议 HTTP 和电子邮件协议 SMTP(Simple Mail Transfer Protocol)。

中心网络架构

现在持续了解 Linux 网络栈的架构以及怎么完成这种 Internet 模型。图 2 供给了 Linux 网络栈的高档视图。最上面是用户空间层,或称为应用层,其间界说了网络栈的用户。底部是物理设备,供给了对网络的衔接才能(串口或比如以太网之类的高速网络)。中心是内核空间,即网络子体系,也是本文介绍的要点。流经网络栈内部的是 socket 缓冲区(sk_buffs),它担任在源和汇点之间传递报文数据。您很快就将看到 sk_buff 的结构。

图 2. Linux 高档网络栈架构

首要,让我们来快速阅读一下 Linux 网络子体系的中心元素,后续章节中会更具体进行介绍。顶部(请参阅图 2)是体系调用接口。它简略地为用户空间的应用程序供给了一种拜访内核网络子体系的办法。坐落其下面的是一个协议无关层,它供给了一种通用办法来运用底层传输层协议。然后是实践协议,在 Linux 中包含内嵌的协议 TCP、UDP,当然还有 IP。然后是别的一个协议无关层,供给了与各个设备驱动程序通讯的通用接口,最下面是设备驱动程序自身。

体系调用接口

体系调用接口能够从两个视点进行描绘。用户建议网络调用时,经过体系调用接口进入内核的进程应该是多路的。终究调用 ./net/socket.c 中的 sys_socketcall 完毕该进程,然后进一步将调用分路发送到指定方针。体系调用接口的另一种描绘是运用一般文件操作作为网络 I/O。例如,典型的读写操作能够在网络 socket 上履行(socket 运用一个文件描绘符表明,与一个一幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序般文件相同)。因而,虽然有许多操作是网络专用的(运用 socket 调用创立一个 socket,运用 connect 调用衔接一个收信方,等等),可是也有一些规范的文件操作能够应用于网络目标,就像操作一般文件相同。终究,体系调用接口供给了在用户空间应用程序和内核之间搬运操控的办法。

协议无关接口

socket 层是一个协议无关接口,它供给了一组通用函数来支撑各种不同协议。socket 层不光能够支撑典型的 TCP 和 UDP 协议,并且还能够支撑 IP、裸以太网和其他传输协议,例如 SCTP(Stream Control Transmission Protocol)。

经过网络栈进行的通讯都需求对 socket 进行操作。Linux 中的 socket 结构是 struct sock,这个结构是在 linux/include/net/sock.h 中界说的。这个巨大的结构中包含了特定 socket 所需求的一切状况信息,其间包含 socket 所运用的特定协议和在 socket 上能够履行的一些操作。

网络子体系能够经过一个界说了自己功用的特别结构来了解可用协议。每个协议都保护了一个名为 proto 的结构(能够在 linux/include/net/sock.h 中找到)。这个结构界说了能够在从 socket 层到传输层中履行特定的 socket 操作(例如,怎么创立一个 socket,怎么运用 socket 树立一个衔接,怎么封闭一个 socket 等等)。

网络协议

网络协议这一节对一些可用的特定网络协议作出了界说(例如 TCP、UDP 等)。它们都是在 linux/net/ipv4/af_inet.c 文件中一个名为 inet_init 的函数中进行初始化的(因为 TCP 和 UDP 都是 inet 簇协议的一部分)。 inet_init 函数运用 proto_register 函数来注册每个内嵌协议。这个函数是在 linux/net/core/sock.c 中界说的,除了能够将这个协议添加到活动协议列表中之外,假如需求,该函数还能够挑选分配一到多个 slab 缓存。

经过 linux/net/ipv4/ 目录中 udp.c 和 raw.c 文件中的 proto 接口,您能够了解各个协议是怎么标识自己的。这些协议接口每个都依照类型和协议映射到 inetsw_array,该数组将内嵌协议与操作映射到一同。inetsw_array 结构及其联系如图 3 所示。开端,会调用 inet_init 中的 inet_register_protosw 将这个数组中的每个协议都初始化为 inetsw。函数 inet_init 也会对各个 inet幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序 模块进行初始化,例如 ARP、ICMP 和 IP 模块,以及 TCP 和 UDP 模块。

图 3. Internet 协议数组结构

Socket 协议的相互联系

回想以下在创立 socket 时,需求指定类型和协议,例如my_sock = socket( AF_INET, SOCK_STREAM, 0 )。AF_INET 表明一个 Internet 地址簇,它运用的是一个流 socket,界说为 SOCK_STREAM(如此处的 inetsw_array 所示)。

注意在 图 3 中,proto 结构界说了传输特有的办法,而 proto_ops 结构则界说了通用的 socket 办法。能够经过调用 inet_register_protosw 将其他协议参加到 inetsw 协议中。例如,SCTP 便是经过调用 linux/net/sctp/protocol.c 中的 sctp_init 参加其间的。有关 SCTP 的更多信息,请参阅 参阅资料 一节的内容。

socket 中的数据移动是运用一个所谓的 socket 缓冲区(sk_buff)的中心结构完成的。sk_buff 中包含了报文数据,以及触及协议栈中多个层次的状况数据。所发送或接纳的每个报文都是运用一个 sk_buff 表明的。sk_buff 结构是在 linux/include/linux/skbuff.h 中界说的,如图 4 所示。

图 4. Socket 缓冲区及其与其他结构的联系

如图所示,多个 sk_buff 能够针对某个给定衔接链接在一同。每个 sk_buff 都在设备结构(net_device)中标识报文发送的目的地,或许接纳报文的来源地。因为每个报文都是运用一个 sk_buff 表明的,因而报文头都能够经过一组指针(th、iph 和 mac[用于 Media Access Control 或许 MAC 头])方便地进行定位。因为 sk_buff 是 socket 数据办理的中心,因而创立了许多支撑函数来对它们进行办理。其间有些函数用于创立和毁掉 sk_buff 结构,或对它进行克隆或排队办理。

针对给定的 socket,Socket 缓冲区能够链接在一同,这样能够包含许多信息,包含到协议头的链接、时刻戳(报文是何时发送或接纳的),以及与这个报文相关的设备。

设备无关接口

协议层下面是别的一个无关接口层,它将协议与具有许多各种不同功用的硬件设备衔接在一同。这一层供给了幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序一组通用函数供底层网络设备驱动程序运用,让它们能够对高层协议栈进行操作。

首要,设备驱动程序可能会经过调用 register_netdevice 或 unregister_netdevice 在内核中进行注册或刊出。调用者首要填写 net_device 结构,然后传递这个结构进行注册。内核调用它的 init 函数(假如界说了这种函数),然后履行一组健全性查看,并创立一个 sysfs 条目,然后将新设备添加到设备列表中(内核中的活动设备链表)。在 linux/include/linux/netdevice.h 中能够找到这个 net_device 结构。这些函数都是在 linux/net/core/dev.c 中完成的。

要从协议层向设备中发送 sk_buff,就需求运用 dev_queue_xmit 函数。这个函数能够对 sk_buff 进行排队,从而由底层设备驱动程序进行终究传输(运用 sk_buff 中引证的 net_device 或 sk_buff->dev 所界说的网络设备)。dev 结构中包含了一个名为 hard_start_xmit 的办法,其间保存有建议 sk_buff 传输所运用的驱动程序函数。

报文的接纳一般是运用 netif_rx 履行的。当底层设备驱动程序接纳一个报文(包含在所分配的 sk_buff 中)时,就会经过调用 netif_rx 将 sk_buff 上传至网络层。然后,这个函数经过 netif_rx_schedule 将 sk_buff 在上层协议行列中进行排队,供今后进行处理。能够在 linux/net/core/dev.c 中找到 dev_queue_xmit 和 netif_rx 函数。

最近,内核中引入了一种新的应用程序编程接口(NAPI),该接口答应驱动程序与设备无关层(dev)进行交互。有些驱动程序运用的是 NAPI,可是大多数驱动程序仍然在运用旧式的帧接纳接口(份额大约是 6 比 1)。NAPI 在高负载的情况下能够发生更好的功能,它避免了为每个传入的帧都发生中止。

设备驱动程序

网络栈底部是担任办理物理网络设备的设备驱动程序。例如,包串口运用的 SLIP 驱动程序以及以太网设备运用的以太网驱动程序都是这一层的设备。

在进行初始化时,设备驱动程序会分配一个 net_device 结构,然后运用有必要的程序对其进行初始化。这些程序中有一个是 dev->hard_start_xmit,它界说了上层应该怎么对 sk_buff 排队进行传输。这个程序的参数为 sk_buff。这个函数的操作取决于底层硬件,可是一般 sk_buff 所描绘的报文都会被移动到硬件环或行列中。就像是设备无关层中所描绘的相同,关于 NAPI 兼容的网络驱动程序来说,帧的接纳运用了 netif_rx 和 netif_receivewake_skb 接口。NAPI 驱动程序会对底层硬件的才能进行一些约束。有关更具体的信息,请参阅 参阅资料 一节的内容。

设备驱动程序在 dev幸运彩票app手机下载-Linux 网络栈分析,从 socket 到设备驱动程序 结构中装备好自己的接口之后,调用 register_netdevice 便能够运用该装备。在 linux/drivers/net 中能够找出网络设备专用的驱动程序。

展望

Linux 源代码是学习有关大多数设备类型的设备驱动程序规划最佳办法,包含网络设备驱动程序。在这里能够找到的是各种规划的改变以及对可用内核 API 的运用,可是所学到的每一点都会十分有用,都能够作为新设备驱动程序的起点。除非您需求一种新协议,不然网络栈中的其他代码都是通用的,都会十分有用。即便现在,TCP(用于流协议)或 UDP(用于根据音讯的协议)的完成都能够作为开端新开发有用模块运用。



上一条      下一条
返回顶部