From 4206605f2ee3035596f24804647e832b34aea452 Mon Sep 17 00:00:00 2001 From: gatieme Date: Sun, 4 Sep 2016 23:42:38 +0800 Subject: [PATCH 1/6] ... --- .../04-net/04-/{ => 01-net_device}/README.md | 0 .../04-net/{05 => 04-/02-receive}/README.md | 480 ++++++++++-------- study/kernel/04-net/04-/images/napi.png | Bin 0 -> 62524 bytes .../04-net/04-/images/net_rx_action.png | Bin 0 -> 40641 bytes .../04-/images/receive_kernel_route.png | Bin 0 -> 53403 bytes 5 files changed, 265 insertions(+), 215 deletions(-) rename study/kernel/04-net/04-/{ => 01-net_device}/README.md (100%) rename study/kernel/04-net/{05 => 04-/02-receive}/README.md (78%) create mode 100644 study/kernel/04-net/04-/images/napi.png create mode 100644 study/kernel/04-net/04-/images/net_rx_action.png create mode 100644 study/kernel/04-net/04-/images/receive_kernel_route.png diff --git a/study/kernel/04-net/04-/README.md b/study/kernel/04-net/04-/01-net_device/README.md similarity index 100% rename from study/kernel/04-net/04-/README.md rename to study/kernel/04-net/04-/01-net_device/README.md diff --git a/study/kernel/04-net/05/README.md b/study/kernel/04-net/04-/02-receive/README.md similarity index 78% rename from study/kernel/04-net/05/README.md rename to study/kernel/04-net/04-/02-receive/README.md index ea08c89..528d123 100644 --- a/study/kernel/04-net/05/README.md +++ b/study/kernel/04-net/04-/02-receive/README.md @@ -1,215 +1,265 @@ -进程虚拟地址空间 -======= - -| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | -| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| -| 2016-06-14 | [Linux-4.7](http://lxr.free-electrons.com/source/?v=4.7) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux内存管理](http://blog.csdn.net/gatieme/article/category/6225543) | - - -#2 接受分组 -------- - - -分组到达内核的时间是不可预测的. 所有现代的设备驱动程序都使用中断来通知内核(或系统)有分组到达. 网络驱动程序对特定于设备的中断设置了一个处理例程, 因此每当该中断被引发时(即分组到达), 内核都调用该处理程序, 将数据从网卡传输到物理内存, 或通知内核在一定时间后进行处理. - -几乎所有的网卡都支持DMA模式, 能够自行将数据传输到物理内存. 但这些数据仍然需要解释和处理,这在稍后进行. - -##2.1 传统方法 -------- - -当前, 内核为分组的接收提供了两个框架. 其中一个很早以前就集成到内核中了, 因而称为传统方法. 但与超高速网络适配器协作时, 该API会出现问题,因而网络子系统的开发者已经设计了一种新的API(通常称为NAPI 1). 我们首先从传统方法开始, 因为它比较易于理解. 另外, 使用旧API的适配器较多, 而使用新API的较少. 这没有问题, 因为其物理传输速度没那么高, 不需要新方法. NAPI在稍后讨论 - -图12-10给出了在一个分组到达网络适配器之后,该分组穿过内核到达网络层函数的路径 - - -因为分组是在中断上下文中接收到的, 所以处理例程只能执行一些基本的任务,避免系统(或当前CPU)的其他任务延迟太长时间. - -在中断上下文中, 数据由3个短函数2处理, 执行了下列任务. - -![接收到的分组穿过内核的路径]() - - -1. net_interrupt是由设备驱动程序设置的中断处理程序. 它将确定该中断是否真的是由接收到的分组引发的(也存在其他的可能性, 例如, 报告错误或确认某些适配器执行的传输任务). 如果确实如此,则控制将转移到`net_rx`. - -2. `net_rx`函数也是特定于网卡的, 首先创建一个新的套接字缓冲区. 分组的内容接下来从网卡传输到缓冲区(也就是进入了物理内存), 然后使用内核源代码中针对各种传输类型的库函数来分析首部数据. 这项分析将确定分组数据所使用的网络层协议,例如IP协议. - -3. 与上述两个方法不同, `netif_rx`函数不是特定于网络驱动程序的,该函数位于`net/core/dev.c`. 调用该函数,标志着控制由特定于网卡的代码转移到了网络层的通用接口部分. - -该函数的作用在于, 将接收到的分组放置到一个特定于CPU的等待队列上, 并退出中断上下文, 使得CPU可以执行其他任务. - -内核在全局定义的softnet_data数组中管理进出分组的等待队列, 数组项类型为softnet_data. 为提高多处理器系统的性能, 对每个CPU都会创建等待队列, 支持分组的并行处理. - -不心使用显式的锁机制来保护等待队列免受并发访问, 因为每个CPU都只修改自身的队列, 不会干扰其他CPU的工作. 下文将忽略多处理器相关内容, 只考虑单"softnet_data等待队列", 避免过度复杂化. - - -定义[`include/linux/netdevice.h?v=4.7, line 2719`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2719) - - -```cpp -// http://lxr.free-electrons.com/source/include/linux/netdevice.h#L2719 -/* - * Incoming packets are placed on per-CPU queues - */ -struct softnet_data { - struct list_head poll_list; - struct sk_buff_head process_queue; - - /* stats */ - unsigned int processed; - unsigned int time_squeeze; - unsigned int received_rps; -#ifdef CONFIG_RPS - struct softnet_data *rps_ipi_list; -#endif -#ifdef CONFIG_NET_FLOW_LIMIT - struct sd_flow_limit __rcu *flow_limit; -#endif - struct Qdisc *output_queue; - struct Qdisc **output_queue_tailp; - struct sk_buff *completion_queue; - -#ifdef CONFIG_RPS - /* input_queue_head should be written by cpu owning this struct, - * and only read by other cpus. Worth using a cache line. - */ - unsigned int input_queue_head ____cacheline_aligned_in_smp; - - /* Elements below can be accessed between CPUs for RPS/RFS */ - struct call_single_data csd ____cacheline_aligned_in_smp; - struct softnet_data *rps_ipi_next; - unsigned int cpu; - unsigned int input_queue_tail; -#endif - unsigned int dropped; - struct sk_buff_head input_pkt_queue; - struct napi_struct backlog; - -}; -``` - -目前只对该数据结构的一个成员`input_pkt_queue`感兴趣: - - -```cpp -// http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2753 -struct softnet_data { - struct sk_buff_head input_pkt_queue; -} -``` - -* `input_pkt_queue`使用上文提到的`sk_buff_head`表头, 对所有进入的分组建立一个链表. - -* [`netif_rx`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3830)在结束工作之前将软中断`NET_RX_SOFTIRQ`标记为即将执行, 然后退出中断上下文. - -* [`net_rx_action`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L5177)用作该软中断的处理程序. 其代码流程图在图12-11给出. 请记住, 这里描述的是一个简化的版本. 完整版包含了对高速网络适配器引入的新方法, 将在下文介绍. - - -![图12-11 net_rx_action 的代码流程图]() - - -在一些准备任务之后,工作转移到[`process_backlog`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4809), 该函数在循环中执行下列步骤. 为简化描述, 假定循环一直进行, 直至所有的待决分组都处理完成,不会被其他情况中断. - -1. [`__skb_dequeue`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L1741)从等待队列移除一个套接字缓冲区, 该缓冲区管理着一个接收到的分组. - -2. 由[`netif_receive_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4290)函数分析分组类型, 以便根据分组类型将分组传递给网络层的接收函数(即传递到网络系统的更高一层). 为此, 该函数遍历所有可能负责当前分组类型的所有网络层函数, 一一调用[`deliver_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L1807). - -接下来[`deliver_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L1807)函数使用一个特定于分组类型的处理程序[`func`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2131), 承担对分组的更高层(例如互联网络层)的处理. - -[`netif_receive_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4290)也处理诸如桥接之类的专门特性, 但讨论这些边角情况是不必要的, 至少在平均水准的系统中, 此类特性都属于边缘情况. - -所有用于从底层的网络访问层接收数据的网络层函数都注册在一个散列表中, 通过全局数组[`ptype_base`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L153)实现. - -新的协议通过[`dev_add_pack`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L397)增加. 各个数组项的类型为[`struct packet_type`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2128), 定义如下: - -```cpp -// http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2128 -struct packet_type { - __be16 type; /* This is really htons(ether_type). */ - struct net_device *dev; /* NULL is wildcarded here */ - int (*func) (struct sk_buff *, - struct net_device *, - struct packet_type *, - struct net_device *); - bool (*id_match)(struct packet_type *ptype, - struct sock *sk); - void *af_packet_priv; - struct list_head list; -}; -``` - -| 字段 | 描述 | -|:---:|:----:| -| type | 指定了协议的标识符,处理程序会使用该标识符 | -| dev | 将一个协议处理程序绑定到特定的网卡(NULL 指针表示该处理程序对系统中所有网络设备都有效) | -| func | 是该结构的主要成员。它是一个指向网络层函数的指针,如果分组的类型适当,将其传递给该函数. 其中一个处理程序就是 ip_rcv ,用于基于IPv4的协议,在下文讨论 | - -`netif_receive_skb`对给定的套接字缓冲区查找适当的处理程序, 并调用其`func`函数, 将处理分组的职责委托给网络层, 这是网络实现中更高的一层. - - - -##2.2 对高速接口的支持 -------- - -如果设备不支持过高的传输率, 那么此前讨论的旧式方法可以很好地将分组从网络设备传输到内核的更高层. 每次一个以太网帧到达时, 都使用一个IRQ来通知内核. - -这里暗含着"快"和"慢"的概念. 对低速设备来说, 在下一个分组到达之前, IRQ的处理通常已经结束. 由于下一个分组也通过IRQ通知, 如果前一个分组的IRQ尚未处理完成, 则会导致问题, 高速设备通常就是这样. 现代以太网卡的运作高达`10000 Mbit/s`, 如果使用旧式方法来驱动此类设备, 将造成所谓的"中断风暴". 如果在分组等待处理时接收到新的IRQ, 内核不会收到新的信息 : 在分组进入处理过程之前, 内核是可以接收IRQ的, 在分组的处理结束后, 内核也可以接收IRQ, 这些不过是"旧闻"而已. 为解决该问题, NAPI使用了IRQ和轮询的组合. - -假定某个网络适配器此前没有分组到达, 但从现在开始, 分组将以高频率频繁到达. 这就是NAPI设备的情况, 如下所述. - -1. 第一个分组将导致网络适配器发出IRQ. 为防止进一步的分组导致发出更多的IRQ, 驱动程序会关闭该适配器的Rx IRQ. 并将该适配器放置到一个轮询表上. - -2. 只要适配器上还有分组需要处理, 内核就一直对轮询表上的设备进行轮询. - -3. 重新启用Rx中断. - - -如果在新的分组到达时, 旧的分组仍然处于处理过程中, 工作不会因额外的中断而减速. 虽然对设备驱动程序(和一般意义上的内核代码)来说轮询通常是一个很差的方法, 但在这里该方法没有什么不利之处:在没有分组还需要处理时,将停止轮询,设备将回复到通常的IRQ驱动的运行方式. 在没有中断支持的情况下, 轮询空的接收队列将不必要地浪费时间, 但NAPI并非如此. - -NAPI的另一个优点是可以高效地丢弃分组. 如果内核确信因为有很多其他工作需要处理, 而导致无法处理任何新的分组,那么网络适配器可以直接丢弃分组,无须复制到内核. - -只有设备满足如下两个条件时,才能实现NAPI方法。 - -1. 设备必须能够保留多个接收的分组,例如保存到DMA环形缓冲区中. 下文将该缓冲区称为Rx缓冲区. - -2. 该设备必须能够禁用用于分组接收的IRQ. 而且, 发送分组或其他可能通过IRQ进行的操作, 都仍然必须是启用的。 - -如果系统中有多个设备, 会怎么样呢? 这是通过循环轮询各个设备来解决的. 图12-12概述了这种情况. - -![图12-12 NAPI机制和循环轮询表概览]() - - -回想前文提到的, 如果一个分组到达一个空的Rx缓冲区, 则将相应的设备置于轮询表中. 由于链表本身的性质, 轮询表可以包含多个设备. - -内核以循环方式处理链表上的所有设备 : 内核依次轮询各个设备, 如果已经花费了一定的时间来处理某个设备, 则选择下一个设备进行处理. 此外, 某个设备都带有一个相对权重, 表示与轮询表中其他设备相比, 该设备的相对重要性. 较快的设备权重较大,较慢的设备权重较小. 由于权重指定了在一个轮询的循环中处理多少分组, 这确保了内核将更多地注意速度较快的设备. - -现在我们已经弄清楚了NAPI的基本原理, 接下来将讨论其实现细节. 与旧的API相比, 关键性的变化在于, 支持NAPI的设备必须提供一个 poll函数. 该方法是特定于设备的, 在用`netif_napi_add`注册网卡时指定. 调用该函数注册, 表明设备可以且必须用新方法处理. - -```CPP - -static inline void netif_napi_add(struct net_device *dev, -struct napi_struct *napi, -int (*poll)(struct napi_struct *, int), -int weight); -``` - -| 参数 | 描述 | -|:----:|:----:| -| dev | 指向所述设备的`net_device`实例 | -| poll | 指定了在IRQ禁用时用来轮询设备的函数 | -| weight | 指定了设备接口的相对权重。实际上可以对 weight 指定任意整数值。通常10/100 Mbit网卡的驱动程序 -指定为16,而1 000/10 000 Mbit网卡的驱动程序指定为64。无论如何,权重都不能超过该设备可以在 -Rx缓冲区中存储的分组的数目。 -netif_napi_add 还需要另一个参数,是一个指向 struct napi_struct 实例的指针。该结构用于 -管理轮询表上的设备。其定义如下: - -struct napi_struct { -struct list_head poll_list; -}; -unsigned long state; -int weight; -int (*poll)(struct napi_struct *, int); -轮询表通过一个标准的内核双链表实现, poll_list 用作链表元素。 weight 和 poll 的语义同上文 -所述。 state 可以是 NAPI_STATE_SCHED 或 NAPI_STATE_DISABLE ,前者表示设备将在内核的下一次循 -环时被轮询,后者表示轮询已经结束且没有更多的分组等待处理,但设备尚未从轮询表移除。 -请注意, struct napi_struct 经常嵌入到一个更大的结构中,后者包含了与网卡有关的、特定 -于驱动程序的数据。这样在内核使用 poll 函数轮询网卡时,可用 container_of 机制获得相关信息 \ No newline at end of file +进程虚拟地址空间 +======= + +| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | +| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| +| 2016-06-14 | [Linux-4.7](http://lxr.free-electrons.com/source/?v=4.7) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux内存管理](http://blog.csdn.net/gatieme/article/category/6225543) | + + +#2 接受分组 +------- + + +分组到达内核的时间是不可预测的. 所有现代的设备驱动程序都使用中断来通知内核(或系统)有分组到达. 网络驱动程序对特定于设备的中断设置了一个处理例程, 因此每当该中断被引发时(即分组到达), 内核都调用该处理程序, 将数据从网卡传输到物理内存, 或通知内核在一定时间后进行处理. + +几乎所有的网卡都支持DMA模式, 能够自行将数据传输到物理内存. 但这些数据仍然需要解释和处理,这在稍后进行. + +##2.1 传统方法 +------- + +当前, 内核为分组的接收提供了两个框架. 其中一个很早以前就集成到内核中了, 因而称为传统方法. 但与超高速网络适配器协作时, 该API会出现问题,因而网络子系统的开发者已经设计了一种新的API(通常称为NAPI 1). 我们首先从传统方法开始, 因为它比较易于理解. 另外, 使用旧API的适配器较多, 而使用新API的较少. 这没有问题, 因为其物理传输速度没那么高, 不需要新方法. NAPI在稍后讨论 + +下图出了在一个分组到达网络适配器之后,该分组穿过内核到达网络层函数的路径 + + +因为分组是在中断上下文中接收到的, 所以处理例程只能执行一些基本的任务,避免系统(或当前CPU)的其他任务延迟太长时间. + +在中断上下文中, 数据由3个短函数2处理, 执行了下列任务. + +![接收到的分组穿过内核的路径](../images/receive_kernel_route.png) + + +1. net_interrupt是由设备驱动程序设置的中断处理程序. 它将确定该中断是否真的是由接收到的分组引发的(也存在其他的可能性, 例如, 报告错误或确认某些适配器执行的传输任务). 如果确实如此,则控制将转移到`net_rx`. + +2. `net_rx`函数也是特定于网卡的, 首先创建一个新的套接字缓冲区. 分组的内容接下来从网卡传输到缓冲区(也就是进入了物理内存), 然后使用内核源代码中针对各种传输类型的库函数来分析首部数据. 这项分析将确定分组数据所使用的网络层协议,例如IP协议. + +3. 与上述两个方法不同, `netif_rx`函数不是特定于网络驱动程序的,该函数位于`net/core/dev.c`. 调用该函数,标志着控制由特定于网卡的代码转移到了网络层的通用接口部分. + +该函数的作用在于, 将接收到的分组放置到一个特定于CPU的等待队列上, 并退出中断上下文, 使得CPU可以执行其他任务. + +内核在全局定义的softnet_data数组中管理进出分组的等待队列, 数组项类型为softnet_data. 为提高多处理器系统的性能, 对每个CPU都会创建等待队列, 支持分组的并行处理. + +不心使用显式的锁机制来保护等待队列免受并发访问, 因为每个CPU都只修改自身的队列, 不会干扰其他CPU的工作. 下文将忽略多处理器相关内容, 只考虑单"softnet_data等待队列", 避免过度复杂化. + + +定义[`include/linux/netdevice.h?v=4.7, line 2719`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2719) + + +```cpp +// http://lxr.free-electrons.com/source/include/linux/netdevice.h#L2719 +/* + * Incoming packets are placed on per-CPU queues + */ +struct softnet_data { + struct list_head poll_list; + struct sk_buff_head process_queue; + + /* stats */ + unsigned int processed; + unsigned int time_squeeze; + unsigned int received_rps; +#ifdef CONFIG_RPS + struct softnet_data *rps_ipi_list; +#endif +#ifdef CONFIG_NET_FLOW_LIMIT + struct sd_flow_limit __rcu *flow_limit; +#endif + struct Qdisc *output_queue; + struct Qdisc **output_queue_tailp; + struct sk_buff *completion_queue; + +#ifdef CONFIG_RPS + /* input_queue_head should be written by cpu owning this struct, + * and only read by other cpus. Worth using a cache line. + */ + unsigned int input_queue_head ____cacheline_aligned_in_smp; + + /* Elements below can be accessed between CPUs for RPS/RFS */ + struct call_single_data csd ____cacheline_aligned_in_smp; + struct softnet_data *rps_ipi_next; + unsigned int cpu; + unsigned int input_queue_tail; +#endif + unsigned int dropped; + struct sk_buff_head input_pkt_queue; + struct napi_struct backlog; + +}; +``` + +目前只对该数据结构的一个成员`input_pkt_queue`感兴趣: + + +```cpp +// http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2753 +struct softnet_data { + struct sk_buff_head input_pkt_queue; +} +``` + +* `input_pkt_queue`使用上文提到的`sk_buff_head`表头, 对所有进入的分组建立一个链表. + +* [`netif_rx`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3830)在结束工作之前将软中断`NET_RX_SOFTIRQ`标记为即将执行, 然后退出中断上下文. + +* [`net_rx_action`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L5177)用作该软中断的处理程序. 其代码流程图在图12-11给出. 请记住, 这里描述的是一个简化的版本. 完整版包含了对高速网络适配器引入的新方法, 将在下文介绍. + + +![图12-11 net_rx_action 的代码流程图](../images/net_rx_action.png) + + +在一些准备任务之后,工作转移到[`process_backlog`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4809), 该函数在循环中执行下列步骤. 为简化描述, 假定循环一直进行, 直至所有的待决分组都处理完成,不会被其他情况中断. + +1. [`__skb_dequeue`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L1741)从等待队列移除一个套接字缓冲区, 该缓冲区管理着一个接收到的分组. + +2. 由[`netif_receive_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4290)函数分析分组类型, 以便根据分组类型将分组传递给网络层的接收函数(即传递到网络系统的更高一层). 为此, 该函数遍历所有可能负责当前分组类型的所有网络层函数, 一一调用[`deliver_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L1807). + +接下来[`deliver_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L1807)函数使用一个特定于分组类型的处理程序[`func`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2131), 承担对分组的更高层(例如互联网络层)的处理. + +[`netif_receive_skb`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L4290)也处理诸如桥接之类的专门特性, 但讨论这些边角情况是不必要的, 至少在平均水准的系统中, 此类特性都属于边缘情况. + +所有用于从底层的网络访问层接收数据的网络层函数都注册在一个散列表中, 通过全局数组[`ptype_base`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L153)实现. + +新的协议通过[`dev_add_pack`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L397)增加. 各个数组项的类型为[`struct packet_type`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2128), 定义如下: + +```cpp +// http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2128 +struct packet_type { + __be16 type; /* This is really htons(ether_type). */ + struct net_device *dev; /* NULL is wildcarded here */ + int (*func) (struct sk_buff *, + struct net_device *, + struct packet_type *, + struct net_device *); + bool (*id_match)(struct packet_type *ptype, + struct sock *sk); + void *af_packet_priv; + struct list_head list; +}; +``` + +| 字段 | 描述 | +|:---:|:----:| +| type | 指定了协议的标识符,处理程序会使用该标识符 | +| dev | 将一个协议处理程序绑定到特定的网卡(NULL 指针表示该处理程序对系统中所有网络设备都有效) | +| func | 是该结构的主要成员。它是一个指向网络层函数的指针,如果分组的类型适当,将其传递给该函数. 其中一个处理程序就是 ip_rcv ,用于基于IPv4的协议,在下文讨论 | + +`netif_receive_skb`对给定的套接字缓冲区查找适当的处理程序, 并调用其`func`函数, 将处理分组的职责委托给网络层, 这是网络实现中更高的一层. + + + +##2.2 对高速接口的支持 +------- + + + +###2.2.1 NAPI机制与轮询 +------- + + +如果设备不支持过高的传输率, 那么此前讨论的旧式方法可以很好地将分组从网络设备传输到内核的更高层. 每次一个以太网帧到达时, 都使用一个IRQ来通知内核. + +这里暗含着"快"和"慢"的概念. 对低速设备来说, 在下一个分组到达之前, IRQ的处理通常已经结束. 由于下一个分组也通过IRQ通知, 如果前一个分组的IRQ尚未处理完成, 则会导致问题, 高速设备通常就是这样. 现代以太网卡的运作高达`10000 Mbit/s`, 如果使用旧式方法来驱动此类设备, 将造成所谓的"中断风暴". 如果在分组等待处理时接收到新的IRQ, 内核不会收到新的信息 : 在分组进入处理过程之前, 内核是可以接收IRQ的, 在分组的处理结束后, 内核也可以接收IRQ, 这些不过是"旧闻"而已. 为解决该问题, NAPI使用了IRQ和轮询的组合. + +假定某个网络适配器此前没有分组到达, 但从现在开始, 分组将以高频率频繁到达. 这就是NAPI设备的情况, 如下所述. + +1. 第一个分组将导致网络适配器发出IRQ. 为防止进一步的分组导致发出更多的IRQ, 驱动程序会关闭该适配器的Rx IRQ. 并将该适配器放置到一个轮询表上. + +2. 只要适配器上还有分组需要处理, 内核就一直对轮询表上的设备进行轮询. + +3. 重新启用Rx中断. + + +如果在新的分组到达时, 旧的分组仍然处于处理过程中, 工作不会因额外的中断而减速. 虽然对设备驱动程序(和一般意义上的内核代码)来说轮询通常是一个很差的方法, 但在这里该方法没有什么不利之处:在没有分组还需要处理时,将停止轮询,设备将回复到通常的IRQ驱动的运行方式. 在没有中断支持的情况下, 轮询空的接收队列将不必要地浪费时间, 但NAPI并非如此. + +NAPI的另一个优点是可以高效地丢弃分组. 如果内核确信因为有很多其他工作需要处理, 而导致无法处理任何新的分组,那么网络适配器可以直接丢弃分组,无须复制到内核. + +只有设备满足如下两个条件时,才能实现NAPI方法。 + +1. 设备必须能够保留多个接收的分组,例如保存到DMA环形缓冲区中. 下文将该缓冲区称为Rx缓冲区. + +2. 该设备必须能够禁用用于分组接收的IRQ. 而且, 发送分组或其他可能通过IRQ进行的操作, 都仍然必须是启用的。 + +如果系统中有多个设备, 会怎么样呢? 这是通过循环轮询各个设备来解决的. 图12-12概述了这种情况. + +![图12-12 NAPI机制和循环轮询表概览](../images/napi.png) + + +回想前文提到的, 如果一个分组到达一个空的Rx缓冲区, 则将相应的设备置于轮询表中. 由于链表本身的性质, 轮询表可以包含多个设备. + +内核以循环方式处理链表上的所有设备 : 内核依次轮询各个设备, 如果已经花费了一定的时间来处理某个设备, 则选择下一个设备进行处理. 此外, 某个设备都带有一个相对权重, 表示与轮询表中其他设备相比, 该设备的相对重要性. 较快的设备权重较大,较慢的设备权重较小. 由于权重指定了在一个轮询的循环中处理多少分组, 这确保了内核将更多地注意速度较快的设备. + +###2.2.2 napi机制的实现细节 +------- + +现在我们已经弄清楚了NAPI的基本原理, 接下来将讨论其实现细节. 与旧的API相比, 关键性的变化在于, 支持NAPI的设备必须提供一个 poll函数. 该方法是特定于设备的, 在用`netif_napi_add`注册网卡时指定. 调用该函数注册, 表明设备可以且必须用新方法处理. + +```CPP +/** + * netif_napi_add - initialize a NAPI context + * @dev: network device + * @napi: NAPI context + * @poll: polling function + * @weight: default weight + * + * netif_napi_add() must be used to initialize a NAPI context prior to calling + * *any* of the other NAPI-related functions. + */ +void netif_napi_add( + struct net_device *dev, + struct napi_struct *napi, + int (*poll)(struct napi_struct *, int), + int weight); +``` + +| 参数 | 描述 | +|:----:|:----:| +| dev | 指向所述设备的`net_device`实例 | +| napi | 该结构用于管理轮询表上的设备 | +| poll | 指定了在IRQ禁用时用来轮询设备的函数 | +| weight | 指定了设备接口的相对权重。实际上可以对 weight 指定任意整数值。通常10/100 Mbit网卡的驱动程序, 指定为16,而1 000/10 000 Mbit网卡的驱动程序指定为64。无论如何,权重都不能超过该设备可以在Rx缓冲区中存储的分组的数目 | + + +`netif_napi_add`还需要另一个参数,是一个指向`struct napi_struct`实例的指针. 该结构用于管理轮询表上的设备. 其定义如下 : + +```cpp +/* + * Structure for NAPI scheduling similar to tasklet but with weighting + */ +struct napi_struct { + /* The poll_list must only be managed by the entity which + * changes the state of the NAPI_STATE_SCHED bit. This means + * whoever atomically sets that bit can add this napi_struct + * to the per-CPU poll_list, and whoever clears that bit + * can remove from the list right before clearing the bit. + */ + struct list_head poll_list; + + unsigned long state; + int weight; + unsigned int gro_count; + int (*poll)(struct napi_struct *, int); +#ifdef CONFIG_NETPOLL + spinlock_t poll_lock; + int poll_owner; +#endif + struct net_device *dev; + struct sk_buff *gro_list; + struct sk_buff *skb; + struct hrtimer timer; + struct list_head dev_list; + struct hlist_node napi_hash_node; + unsigned int napi_id; +}; +``` + +轮询表通过一个标准的内核双链表实现, `poll_list`用作链表元素. `weight`和 `poll`的语义同上文所述. `state` 以是`NAPI_STATE_SCHED`或`NAPI_STATE_DISABLE`, 前者表示设备将在内核的下一次循环时被轮询, 后者表示轮询已经结束且没有更多的分组等待处理,但设备尚未从轮询表移除. + +请注意, `struct napi_struct`经常嵌入到一个更大的结构中,后者包含了与网卡有关的、特定于驱动程序的数据. 这样在内核使用`poll`函数轮询网卡时,可用 `container_of`机制获得相关信息. + + + +##2.2.3 实现poll函数 +------- + + +`poll`函数需要两个参数 : 一个指向`napi_struct`实例的指针和一个指定了"预算"的整数, 预算表示内核允许驱动程序处理的分组数目. 我们并不打算处理真实网卡的可能的奇异之处, 因此讨论一个伪函数, 该函数用于一个需要`NAPI`的超高速适配器 : \ No newline at end of file diff --git a/study/kernel/04-net/04-/images/napi.png b/study/kernel/04-net/04-/images/napi.png new file mode 100644 index 0000000000000000000000000000000000000000..201b6a96d9e5e3f8749c3f47a6d6569e483bca4d GIT binary patch literal 62524 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 JsgN=a{$H$qGw}cb literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/04-/images/net_rx_action.png b/study/kernel/04-net/04-/images/net_rx_action.png new file mode 100644 index 0000000000000000000000000000000000000000..adece9d51fd21a604e0c96bb7019a0475b7134ac GIT binary patch literal 40641 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%0A=j0{4*H_LVwR`?&zQ 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 j1XXh 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≷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 Date: Mon, 5 Sep 2016 10:44:19 +0800 Subject: [PATCH 2/6] ... --- study/kernel/04-net/04-/02-receive/README.md | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/study/kernel/04-net/04-/02-receive/README.md b/study/kernel/04-net/04-/02-receive/README.md index 528d123..90a7e2b 100644 --- a/study/kernel/04-net/04-/02-receive/README.md +++ b/study/kernel/04-net/04-/02-receive/README.md @@ -262,4 +262,37 @@ struct napi_struct { ------- -`poll`函数需要两个参数 : 一个指向`napi_struct`实例的指针和一个指定了"预算"的整数, 预算表示内核允许驱动程序处理的分组数目. 我们并不打算处理真实网卡的可能的奇异之处, 因此讨论一个伪函数, 该函数用于一个需要`NAPI`的超高速适配器 : \ No newline at end of file +`poll`函数需要两个参数 : 一个指向`napi_struct`实例的指针和一个指定了"预算"的整数, 预算表示内核允许驱动程序处理的分组数目. + +我们并不打算处理真实网卡的可能的奇异之处, 因此讨论一个伪函数, 该函数用于一个需要`NAPI`的超高速适配器 : + + +```cpp +static int hyper_card_poll(struct napi_struct *napi, int budget) +{ + struct nic *nic = container_of(napi, struct nic, napi); + struct net_device *netdev = nic->netdev; + int work_done; + work_done = hyper_do_poll(nic, budget); + if (work_done < budget) + { + netif_rx_complete(netdev, napi); + hcard_reenable_irq(nic); + } + return work_done; +} +``` + + +在从`napi_struct`的容器获得特定于设备的信息之后, 调用一个特定于硬件的方法(这里是`hyper_do_poll`)来执行所需要的底层操作从网络适配器获取分组, 并使用像此前那样使用`netif_receive_skb`将分组传递到网络实现中更高的层. + +`hyper_do_poll`最多允许处理`budget`个分组. 该函数返回实际上处理的分组的数目. 必须区分以下两种情况. + +* 如果处理分组的数目小于预算, 那么没有更多的分组, Rx缓冲区为空, 否则, 肯定还需要处理剩余的分组(亦即,返回值不可能小于预算). 因此,netif_rx_complete将该情况通知内核,内核将从轮询表移除该设备。接下来,驱动程序必须通过特定于硬件的适当方法来重新启用IRQ. + +* 已经完全用掉了预算,但仍然有更多的分组需要处理。设备仍然留在轮询表上,不启用中断. + +###2.2.4 实现IRQ处理程序 +------- + +NAPI也需要对网络设备的IRQ处理程序做一些改动. 这里仍然不求助于任何具体的硬件, 而介绍针对虚构设备的代码: \ No newline at end of file From 284689f84894eab8be5451a156cdc7efd48cb3e3 Mon Sep 17 00:00:00 2001 From: gatieme Date: Mon, 5 Sep 2016 23:53:01 +0800 Subject: [PATCH 3/6] ... --- .../01-net_device/README.md | 0 .../02-receive/README.md | 85 ++++++++++++- .../04-net/04-网络访问层/03-send/README.md | 30 +++++ .../{04- => 04-网络访问层}/images/napi.png | Bin .../images/net_rx_action.png | Bin .../04-网络访问层/images/net_rx_action2.png | Bin 0 -> 49205 bytes .../images/receive_kernel_route.png | Bin study/kernel/04-net/05-网络层/README.md | 119 ++++++++++++++++++ 8 files changed, 232 insertions(+), 2 deletions(-) rename study/kernel/04-net/{04- => 04-网络访问层}/01-net_device/README.md (100%) rename study/kernel/04-net/{04- => 04-网络访问层}/02-receive/README.md (80%) create mode 100644 study/kernel/04-net/04-网络访问层/03-send/README.md rename study/kernel/04-net/{04- => 04-网络访问层}/images/napi.png (100%) rename study/kernel/04-net/{04- => 04-网络访问层}/images/net_rx_action.png (100%) create mode 100644 study/kernel/04-net/04-网络访问层/images/net_rx_action2.png rename study/kernel/04-net/{04- => 04-网络访问层}/images/receive_kernel_route.png (100%) create mode 100644 study/kernel/04-net/05-网络层/README.md diff --git a/study/kernel/04-net/04-/01-net_device/README.md b/study/kernel/04-net/04-网络访问层/01-net_device/README.md similarity index 100% rename from study/kernel/04-net/04-/01-net_device/README.md rename to study/kernel/04-net/04-网络访问层/01-net_device/README.md diff --git a/study/kernel/04-net/04-/02-receive/README.md b/study/kernel/04-net/04-网络访问层/02-receive/README.md similarity index 80% rename from study/kernel/04-net/04-/02-receive/README.md rename to study/kernel/04-net/04-网络访问层/02-receive/README.md index 90a7e2b..0f11a3c 100644 --- a/study/kernel/04-net/04-/02-receive/README.md +++ b/study/kernel/04-net/04-网络访问层/02-receive/README.md @@ -173,7 +173,8 @@ struct packet_type { NAPI的另一个优点是可以高效地丢弃分组. 如果内核确信因为有很多其他工作需要处理, 而导致无法处理任何新的分组,那么网络适配器可以直接丢弃分组,无须复制到内核. -只有设备满足如下两个条件时,才能实现NAPI方法。 + +只有设备满足如下两个条件时,才能实现NAPI方法. 1. 设备必须能够保留多个接收的分组,例如保存到DMA环形缓冲区中. 下文将该缓冲区称为Rx缓冲区. @@ -188,9 +189,11 @@ NAPI的另一个优点是可以高效地丢弃分组. 如果内核确信因为 内核以循环方式处理链表上的所有设备 : 内核依次轮询各个设备, 如果已经花费了一定的时间来处理某个设备, 则选择下一个设备进行处理. 此外, 某个设备都带有一个相对权重, 表示与轮询表中其他设备相比, 该设备的相对重要性. 较快的设备权重较大,较慢的设备权重较小. 由于权重指定了在一个轮询的循环中处理多少分组, 这确保了内核将更多地注意速度较快的设备. + ###2.2.2 napi机制的实现细节 ------- + 现在我们已经弄清楚了NAPI的基本原理, 接下来将讨论其实现细节. 与旧的API相比, 关键性的变化在于, 支持NAPI的设备必须提供一个 poll函数. 该方法是特定于设备的, 在用`netif_napi_add`注册网卡时指定. 调用该函数注册, 表明设备可以且必须用新方法处理. ```CPP @@ -292,7 +295,85 @@ static int hyper_card_poll(struct napi_struct *napi, int budget) * 已经完全用掉了预算,但仍然有更多的分组需要处理。设备仍然留在轮询表上,不启用中断. + ###2.2.4 实现IRQ处理程序 ------- -NAPI也需要对网络设备的IRQ处理程序做一些改动. 这里仍然不求助于任何具体的硬件, 而介绍针对虚构设备的代码: \ No newline at end of file +NAPI也需要对网络设备的IRQ处理程序做一些改动. 这里仍然不求助于任何具体的硬件, 而介绍针对虚构设备的代码: + + +```cpp +static irqreturn_t e100_intr(int irq, void *dev_id) +{ + struct net_device *netdev = dev_id; + struct nic *nic = netdev_priv(netdev); + u8 stat_ack = ioread8(&nic->csr->scb.stat_ack); + + netif_printk(nic, intr, KERN_DEBUG, nic->netdev, + "stat_ack = 0x%02X\n", stat_ack); + + if (stat_ack == stat_ack_not_ours || /* Not our interrupt */ + stat_ack == stat_ack_not_present) /* Hardware is ejected */ + return IRQ_NONE; + + /* Ack interrupt(s) */ + iowrite8(stat_ack, &nic->csr->scb.stat_ack); + + /* We hit Receive No Resource (RNR); restart RU after cleaning */ + if (stat_ack & stat_ack_rnr) + nic->ru_running = RU_SUSPENDED; + + if (likely(napi_schedule_prep(&nic->napi))) { + e100_disable_irq(nic); + __napi_schedule(&nic->napi); + } + + return IRQ_HANDLED; +} +``` + + +假定特定于接口的数据保存在`net_device->private`中, 这是大多数网卡驱动程序使用的方法. + +使用辅助函数`netdev_priv`访问该字段. + +现在需要通知内核有新的分组可用. 这需要如下二阶段的方法. + +1. `netif_rx_schedule_prep`准备将设备放置到轮询表上. 本质上, 这会安置`napi_struct->flags`中的`NAPI_STATE_SCHED`标志. + +2. 如果设置该标志成功(仅当NAPI已经处于活跃状态时, 才会失败), 驱动程序必须用特定于设备的适当方法来禁用相应的IRQ. 调用`__netif_rx_schedule`将设备的`napi_struct`添加到轮询表, 并引发软中断`NET_RX_SOFTIRQ`. 这通知内核在`net_rx_action`中开始轮询. + + +###2.2.5 处理Rx软中断 +------- + +在讨论了为支持NAPI驱动程序需要做哪些改动之后, 我们来考察一下内核需要承担的职责. + +`net_rx_action`依旧是软中断`NET_RX_SOFTIRQ`的处理程序. 在前一节给出了该函数的一个简化版本. + +随着有关NAPI的更多细节尘埃落定, 现在可以讨论该函数的所有细节了. + +![图12-13给出了其代码流程图](../images/net_rx_action.png) + + +本质上, 内核通过依次调用各个设备特定的poll方法, 处理轮询表上当前的所有设备. 设备的权重用作该设备本身的预算, 即轮询的一步中可能处理的分组数目. + +必须确保在这个软中断的处理程序中, 不会花费过多时间. 如果如下两个条件成立, 则放弃处理. + +1. 处理程序已经花费了超出一个jiffie的时间. + +2. 所处理分组的总数, 已经超过了`netdev_budget`指定的预算总值. 通常, 总值设置为300, 但可以通过`/proc/sys/net/core/netdev_budget`修改. + +这个预算不能与各个网络设备本身的预算混淆! 在每个轮询步之后, 都从全局预算中减去处理的分组数目, 如果该预算值下降到0, 则退出软中断处理程序. + +在轮询了一个设备之后, 内核会检查所处理的分组数目, 与该设备的预算是否相等. + +如果相等, 那么尚未获得该设备上所有等待的分组, 即代码流程图中`work == weight`所表示的情况. 内核接下来将该设备移动到轮询表末尾, 在链表中所有其他设备都处理过之后, 继续轮询该设备. 显然, 这实现了网络设备之间的循环调度. + +###2.2.6 在NAPI之上实现旧式API +------- + + +最后, 请注意旧的API是如何在NAPI上实现的. 内核的常规行为, 由一个与`softnet`队列关联的伪网络设备控制, `net/core/dev.c`中的`process_backlog`标准函数用作poll方法. 如果没有网络适配器将其自身添加到该队列的轮询表, 其中只包含这个伪适配器, 那么net_rx_action的行为就是通过对`process_backlog`的单一调用来处理队列中的分组, 而不管分组的来源设备. + + diff --git a/study/kernel/04-net/04-网络访问层/03-send/README.md b/study/kernel/04-net/04-网络访问层/03-send/README.md new file mode 100644 index 0000000..ef69fee --- /dev/null +++ b/study/kernel/04-net/04-网络访问层/03-send/README.md @@ -0,0 +1,30 @@ +进程虚拟地址空间 +======= + +| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | +| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| +| 2016-06-14 | [Linux-4.7](http://lxr.free-electrons.com/source/?v=4.7) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux内存管理](http://blog.csdn.net/gatieme/article/category/6225543) | + + +#3 发送分组 +------- + +在网络层中特定于协议的函数通知网络访问层处理由套接字缓冲区定义的一个分组时, 将发送完成的分组. + + +当信息从计算机发送出去时, 必须注意哪些事项? 除了特定协议需要完成的首部和校验和, 以及由高层协议实例生成的数据之外, 分组的路由是最重要的.(即使计算机只有一个网卡, 内核仍然需要区分发送到外部目标的分组和针对环回接口的分组.) + + +因为该问题只能由更高层的协议实例决定(特别是, 如果可以选择到预期目标的路由时), 所以设备驱动程序假定高层协议已经做出了决策. + + +在分组可以发送到下一个正确的计算机之前(通常不同于目标计算机,因为除非存在直接的硬件链路, 否则IP分组通常通过网关发送), 必须确定接收方网卡的硬件地址. + +这是一个复杂的过程, 将在12.8.5节详细讲述. 此时, 我们假定已经知道接收方的MAC地址. 网络访问层的所需的另一个首部, 通常由特定于协议的函数产生. + + +`net/core/dev.c`中的`dev_queue_xmit`用于将分组放置到发出分组的队列上. + +这里将忽略这个特定于设备的队列的实现, 因为它并没有揭示什么网络层的运作机制. 只要知道, 在分组放置到等待队列上一定的时间之后, 分组将发出即可. + +这是通过特定于适配器的函数`hard_start_xmit`完成的, 在每个net_device结构中都以函数指针的形式出现, 由硬件设备驱动程序实现. \ No newline at end of file diff --git a/study/kernel/04-net/04-/images/napi.png b/study/kernel/04-net/04-网络访问层/images/napi.png similarity index 100% rename from study/kernel/04-net/04-/images/napi.png rename to study/kernel/04-net/04-网络访问层/images/napi.png diff --git a/study/kernel/04-net/04-/images/net_rx_action.png b/study/kernel/04-net/04-网络访问层/images/net_rx_action.png similarity index 100% rename from study/kernel/04-net/04-/images/net_rx_action.png rename to study/kernel/04-net/04-网络访问层/images/net_rx_action.png diff --git a/study/kernel/04-net/04-网络访问层/images/net_rx_action2.png b/study/kernel/04-net/04-网络访问层/images/net_rx_action2.png new file mode 100644 index 0000000000000000000000000000000000000000..d70103e3f81e0a4b205f0fd742c83b7705239c24 GIT binary patch literal 49205 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
{p-ulaQKq|kPKWh|4{1jB}#Y$|0#zQ z->u%t9Jw);8KRqV9yEWwxx0=vsW{;YcB`4*^!RoNme!w$*u2pIoSE_SoR;x@ic#HYe(nd!MDM{tZ=} z#?w_k3&(9&oxsJ7=U^#90poGJq|3e0<$S9^+SK5ME2G4TQv(KN7=nV*TzH9L`*(S9 zc6R^E1A6T)t%x?QNMkurDz5llU9@{r^jvVcLn|HTNvOGKxx4XiPGgSQS2i+gQcx2{n6yiFCo2zqq#i`yGgdb5yvF^`C3AtK^}FPcNNau6Iz`ZL4#xEXcB^e} zgyBapW!+G18#F#6)tID)DE0clo_R=R>4(JiN}@EI@b4&I zC#G`-TXW2RjdJYA&mDFu9CnB;-8Y&krL>SIG>)8_m$}^V-Q!#69;TqJUVG|r68tA_ z3thIiz4viUJkco$dUbd%-^-lccuDl6c<}*5-zQ?00et=_TPYt@;%&iUq#6lAF`HFV z3XUCMR-q;Mrg%OT2F)0Bvk%qEzcUiTQ99y-Gq56t&-oO%8ms9@0W)Q_plzhO?BGmX zCAs%HP|h>3LaF2H!$>yfw!7bN<{Gv>h9^bS)nRp}?{$u-JO>VzwEqgOBrp3H5a%3) zaRP#@XCZFKk!f?ZI7F}7K^(N{9_^H-+v9I!PN|L<>b9Jjg=p^MDcz!mLS!aBN=AQIlJ_mVD{=XQTdr!`Wi>bDkk!p&k2IK z6=cJa;;`0GCflVyb>pPE9=`PwN?&N+nt?$^qz)D#8KqE?=Igk4)U({a5sTIMX5u<^ z1yfgA=p2}){I4gM~R`82>c0x`mIzABAdIhPHSY3yh4i{10Ov5CH423h)vV{WXeyi08t;or} zUCt=!!X}CGwS7T|5^`jF$-4_5GSr42b}1Ox?57t-iFBc>YPE}I5? zw@%4{x3_RQo$|+@65vl8%8jY54cJfEu5FKAiq6Yrmt0lP_G;}|%mv2!My%BjX;g5? zCfAqS>~V}7dJ(C_47wM+qt^vlAmebnc84*aFXwI(6v;5+pmeAq!V=b156D0AmTXLP zV@@1%x((;@u7mh+g*IUY0FfR(pidVDqqZ(*@5n+-8%TLcQ0(oTq5EYem_WIJ&b>&%tg)gn) z)1bnNVPJ!xNQ+kx+66{j*^0jcjsM4zfW?8B9WR_EwpY;E(N#<&=ZB@s&jw&S`4`5c zi++z z_&6xfq+c&w?*6!%(M26Hl;i>Hp~i@9aPwv=v*D1*fW1_PETG5l0b=gi&n`I)iF>F}g%e`b}v z*G_4?c->=3TCShL6g}SE2a5G%nEq%WwT5`_{y18`aGhVnNEId_t8Av>X+rHXQt3Zs zfhkuuGIDdBz66vVQq9lJc7f(sPy9Xej8Bgu(60Q3%RPvAbd4jD)cH_L^sEYnbpK=_ zm-+C7!YCsfXn(jHRMGfi)=q9V-L0mC1K|Z-VK`Ew$3KTi{n3QsG;E)*?fDg{KLZyq z4E%Y8CX7u8+(N+rp5G#(05jvi2clu#01fc>K%XzLkpHh!jD86LVd=jIs((MType of Service(服务类型) | 用于更复杂的协议选项,我们在这里无须关注 | +| Length(长度) | 指定了分组的总长度,即首部加数据的长度 | +| fragment ID(分片标识) | 标识了一个分片的IP分组的各个部分。分片方法将同一分片ID指定到同一原始分组的各个数据片,使之可标识为同一分组的成员。各个部分的相对位置由fragment offset(分片偏移量)字段定义。偏移量的单位是64 bit | + + +第三个标志位"保留供未来使用", 但考虑到IPv6的存在, 这是不太可能的. + + +| 字段 | 描述 | +|:-----:|:-----:| +| TTL意为"Time to Live" | 指定了从发送者到接收者的传输路径上中间站点的最大数目(或跳数) | +| Protocol | 标识了IP分组承载的高层协议(传输层)。例如,TCP和UDP协议都有对应的唯一值 | +| Checksum | 包含了一个校验和,根据首部和数据的内容计算。如果指定的校验和与接收方计算的值不一致,那么可能发生了传输错误,应该丢弃该分组 | +| src和dest | 指定了源和目标的32位IP地址 | +| options | 用于扩展IP选项 | +| data | 保存了分组数据(净荷) | + + +IP首部中所有的数值都以网络字节序存储(大端序). + +在内核源代码中, 该首部由iphdr数据结构实现, 定义在[include/uapi/linux/ip.h?v=4.7, line 85](http://lxr.free-electrons.com/source/include/uapi/linux/ip.h?v=4.7#L85) + +```cpp +struct iphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +#error "Please fix " +#endif + __u8 tos; + __be16 tot_len; + __be16 id; + __be16 frag_off; + __u8 ttl; + __u8 protocol; + __sum16 check; + __be32 saddr; + __be32 daddr; + /*The options start here. */ +}; +``` + + +`ip_rcv`函数是网络层的入口点. 分组向上穿过内核的路线如下图所示 + +![图12-15 分组穿过互联网络层的路线](../images/) + + + +发送和接收操作的程序流程并不总是分离的, 如果分组只通过当前计算机转发, 那么发送和接收操作是交织的. 这种分组不会传递到更高的协议层(或应用程序), 而是立即离开计算机, 发往新的目的地. + + + +#3 接收分组 +------- + + +在分组(以及对应的套接字缓冲区,其中的指针已经设置了适当的值)转发到ip_rcv之后, 必须检查接收到的信息, 确保它是正确的。 主要检查计算的校验和与首部中存储的校验和是否一致. + +其他的检查包括分组是否达到了IP首部的最小长度,分组的协议是否确实是IPv4(IPv6的接收例程是另一个). + +在进行了这些检查之后, 内核并不立即继续对分组的处理, 而是调用一个`netfilter`挂钩, 使得用户空间可以对分组数据进行操作. + +`netfilter`挂钩插入到内核源代码中定义好的各个位置, 使得分组能够被 +外部动态操作. 挂钩存在于网络子系统的各个位置, 每种挂钩都有一个特别的标记, 例如NF_IP_POST_ROUTING. + +在内核到达一个挂钩位置时, 将在用户空间调用对该标记支持的例程. 接下来, 在另一个内核函数中继续内核端的处理(分组可能被修改过). + +12.8.6节讨论了netfilter机制的实现。 +在下一步中,接收到的分组到达一个十字路口,此时需要判断该分组的目的地是本地系统还是远 +程计算机。根据对分组目的地的判断,需要将分组转发到更高层,或转到互联网络层的输出路径上(这 +里不打算讨论第三种选项,即通过多播将分组发送到一组计算机)。 +ip_route_input负责选择路由。这个相对复杂的决策过程在12.8.5节详细讨论。判断路由的结果 +是,选择一个函数,进行进一步的分组处理。可用的函数是ip_local_deliver和ip_forward。具体 +选择哪个函数,取决于分组是交付到本地计算机下一个更高协议层的例程,还是转发到网络中的另一 \ No newline at end of file From e2c7456c2a2f39d99be3f545a8ba15d8e600487c Mon Sep 17 00:00:00 2001 From: gatieme Date: Tue, 6 Sep 2016 11:00:22 +0800 Subject: [PATCH 4/6] ... --- .../kernel/04-net/03-socket_buffer/README.md | 129 ++++++++- study/kernel/04-net/05-网络层/README.md | 27 +- .../04-net/05-网络层/images/ip_header.png | Bin 0 -> 40378 bytes .../kernel/04-net/05-网络层/images/route.png | Bin 0 -> 84599 bytes study/kernel/04-net/1.c | 260 ------------------ study/kernel/04-net/README.md | 47 ++++ 6 files changed, 195 insertions(+), 268 deletions(-) create mode 100644 study/kernel/04-net/05-网络层/images/ip_header.png create mode 100644 study/kernel/04-net/05-网络层/images/route.png delete mode 100644 study/kernel/04-net/1.c create mode 100644 study/kernel/04-net/README.md diff --git a/study/kernel/04-net/03-socket_buffer/README.md b/study/kernel/04-net/03-socket_buffer/README.md index efc357a..7e777fb 100644 --- a/study/kernel/04-net/03-socket_buffer/README.md +++ b/study/kernel/04-net/03-socket_buffer/README.md @@ -262,17 +262,91 @@ struct sk_buff ![套接字缓冲区在各个协议层之间传递时,对缓冲区的操作](../images/trans_data.png) -在字长32位的系统上,数据类型sk_buff_data_t用来表示各种类型为简单指针的数据, 定义在[`include/linux/skbuff.h?v=4.7, line 626`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L626), 在64位 CPU上, 可使用一点小技巧来节省一些空间。sk_buff_data_t的定义改为整型变量 + + + +内核实现了一些宏用来获取缓冲区数据段的结束位置. 这些函数定义在[`include/linux/skbuff.h?v=4.7, line 1165`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L1165) + + ```cpp #ifdef NET_SKBUFF_DATA_USES_OFFSET -typedef unsigned int sk_buff_data_t; +static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) +{ + return skb->head + skb->end; +} + +static inline unsigned int skb_end_offset(const struct sk_buff *skb) +{ + return skb->end; +} #else -typedef unsigned char *sk_buff_data_t; +static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) +{ + return skb->end; +} + +static inline unsigned int skb_end_offset(const struct sk_buff *skb) +{ + return skb->end - skb->head; +} #endif ``` -套接字缓冲区需要很多指针来表示缓冲区中内容的不同部分. 由于网络子系统必须保证较低的内存占用和较高的处理速度, 因而对struct sk_buff来说,我们需要保持该结构的长度尽可能小. +内核实现了一些宏用来获取协议数据区域的结束的结束位置tail的函数. 这些函数定义在[`include/linux/skbuff.h?v=4.7, line 1849`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L1849) + +```cpp +#ifdef NET_SKBUFF_DATA_USES_OFFSET /* 64 bit */ +static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->head + skb->tail; +} + +static inline void skb_reset_tail_pointer(struct sk_buff *skb) +{ + skb->tail = skb->data - skb->head; +} + +static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) +{ + skb_reset_tail_pointer(skb); + skb->tail += offset; +} + +#else /* NET_SKBUFF_DATA_USES_OFFSET */ +static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->tail; +} + +static inline void skb_reset_tail_pointer(struct sk_buff *skb) +{ + skb->tail = skb->data; +} + +static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) +{ + skb->tail = skb->data + offset; +} + +#endif /* NET_SKBUFF_DATA_USES_OFFSET */ +``` + +在字长32位的系统上,数据类型sk_buff_data_t用来表示各种类型为简单指针的数据(`char *`), 定义在[`include/linux/skbuff.h?v=4.7, line 487`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L487), 在64位 CPU上, 可使用一点小技巧来节省一些空间. `sk_buff_data_t`的定义改为整型变量 + +```cpp +#if BITS_PER_LONG > 32 /* 64位的linux系统中long是8个字节 > 4 */ +#define NET_SKBUFF_DATA_USES_OFFSET 1 +#endif + +#ifdef NET_SKBUFF_DATA_USES_OFFSET /* 64位系统 */ +typedef unsigned int sk_buff_data_t; /* 4个字节 */ +#else /* 32位系统 */ +typedef unsigned char *sk_buff_data_t; /* 4个字节 */ +#endif +``` + +套接字缓冲区需要很多指针来表示缓冲区中内容的不同部分. 由于网络子系统必须保证较低的内存占用和较高的处理速度, 因而对`struct sk_buff`来说,我们需要保持该结构的长度尽可能小. @@ -447,3 +521,50 @@ struct sk_buff_head { 分组通常放置在等待队列中,例如分组等待处理时,或需要重新组合已经分析过的分组时. ![通过双链表管理套接字缓冲区](../images/dou_link.png) + + + +##4.3.3 skb_shared_info结构体 +------- + + +内核`skb_shared_info`结构体该类型用来管理数据包分片信息, 该结构定义在[`include/linux/skbuff.h?v=4.7, line 408`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L408) + +```cpp +/* This data is invariant across clones and lives at + * the end of the header data, ie. at skb->end. + */ +struct skb_shared_info { + unsigned char nr_frags; + __u8 tx_flags; + unsigned short gso_size; /* 尺寸 */ + /* Warning: this field is not always filled in (UFO)! */ + unsigned short gso_segs; /* 顺序 */ + unsigned short gso_type; + struct sk_buff *frag_list; + struct skb_shared_hwtstamps hwtstamps; /* 硬件时间戳 */ + u32 tskey; + __be32 ip6_frag_id; + + /* + * Warning : all fields before dataref are cleared in __alloc_skb() + */ + atomic_t dataref; /* 使用计数 */ + + /* Intermediate layers must ensure that destructor_arg + * remains valid until skb destructor */ + void * destructor_arg; + + /* must be last field, see pskb_expand_head() */ + skb_frag_t frags[MAX_SKB_FRAGS]; +}; +``` + + + 通过宏可以表示与skb的关系 + + +```cpp +/* Internal */ +#define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) +``` \ No newline at end of file diff --git a/study/kernel/04-net/05-网络层/README.md b/study/kernel/04-net/05-网络层/README.md index 8b43ea0..65abd95 100644 --- a/study/kernel/04-net/05-网络层/README.md +++ b/study/kernel/04-net/05-网络层/README.md @@ -28,10 +28,10 @@ IP在1981年正式定义(在RFC791中), 现在已经进入暮年 ------- -IP分组使用的协议首部如图12-14所示. +IP分组使用的协议首部如下图所示. -![图12-14 IP首部的结构](../images/) +![图12-14 IP首部的结构](./images/ip_header.png) | 字段 | 描述 | @@ -87,9 +87,28 @@ struct iphdr { `ip_rcv`函数是网络层的入口点. 分组向上穿过内核的路线如下图所示 -![图12-15 分组穿过互联网络层的路线](../images/) + +![图12-15 分组穿过互联网络层的路线](./images/route.png) +该函数定义在[`net/ipv4/ip_input.c?v=4.7, line 405`](http://lxr.free-electrons.com/source/net/ipv4/ip_input.c?v=4.7#L405) + + +| 函数 | 功能 | 定义 | +|:-----:|:-----:|:-----:| +| ip_rcv | 对驱动送上来的数据报文进行ip头的合法性检查, 并调用netfilter过滤器上NF_INET_PRE_ROUTING | [net/ipv4/ip_input.c?v=4.7, line 405](http://lxr.free-electrons.com/source/net/ipv4/ip_input.c?v=4.7#L405) | +| ip_local_deliver | | [net/ipv4/ip_input.c?v=4.7, line 192](http://lxr.free-electrons.com/source/net/ipv4/ip_input.c?v=4.7#L192) | + +
+ +| 函数 | 功能 | 定义 | +|:-----:|:-----:|:-----:| +| ip_queue_xmit | | [net/ipv4/ip_output.c?v=4.7, line 376](http://lxr.free-electrons.com/source/net/ipv4/ip_output.c?v=4.7#L376) | +| ip_output | | [net/ipv4/ip_output.c?v=4.7, line 346](http://lxr.free-electrons.com/source/net/ipv4/ip_output.c?v=4.7#L346) | + +```cpp + +``` 发送和接收操作的程序流程并不总是分离的, 如果分组只通过当前计算机转发, 那么发送和接收操作是交织的. 这种分组不会传递到更高的协议层(或应用程序), 而是立即离开计算机, 发往新的目的地. @@ -99,7 +118,7 @@ struct iphdr { ------- -在分组(以及对应的套接字缓冲区,其中的指针已经设置了适当的值)转发到ip_rcv之后, 必须检查接收到的信息, 确保它是正确的。 主要检查计算的校验和与首部中存储的校验和是否一致. +在分组(以及对应的套接字缓冲区, 其中的指针已经设置了适当的值)转发到ip_rcv之后, 必须检查接收到的信息, 确保它是正确的. 主要检查计算的校验和与首部中存储的校验和是否一致. 其他的检查包括分组是否达到了IP首部的最小长度,分组的协议是否确实是IPv4(IPv6的接收例程是另一个). diff --git a/study/kernel/04-net/05-网络层/images/ip_header.png b/study/kernel/04-net/05-网络层/images/ip_header.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb78416726f9a062a011f8f0b49b5d5459aa689 GIT binary patch literal 40378 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
Dr-Le&DNhy!lr%s||9`b~t>k~9 dmiq5!aZgKTrYn8Bul*n3yJBu@R&C;*@PFfp96SI3 literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/05-网络层/images/route.png b/study/kernel/04-net/05-网络层/images/route.png new file mode 100644 index 0000000000000000000000000000000000000000..d07f42b6a1306bac0e287fd1aca0898cb3b29b75 GIT binary patch literal 84599 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%0A1zd6N%Lth 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 literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/1.c b/study/kernel/04-net/1.c deleted file mode 100644 index 0128897..0000000 --- a/study/kernel/04-net/1.c +++ /dev/null @@ -1,260 +0,0 @@ -struct net_device { - char name[IFNAMSIZ]; - struct hlist_node name_hlist; - char *ifalias; - /* - * I/O specific fields - * FIXME: Merge these and struct ifmap into one - */ - unsigned long mem_end; - unsigned long mem_start; - unsigned long base_addr; - int irq; - - atomic_t carrier_changes; - - /* - * Some hardware also needs these fields (state,dev_list, - * napi_list,unreg_list,close_list) but they are not - * part of the usual set specified in Space.c. - */ - - unsigned long state; - - struct list_head dev_list; - struct list_head napi_list; - struct list_head unreg_list; - struct list_head close_list; - struct list_head ptype_all; - struct list_head ptype_specific; - - struct { - struct list_head upper; - struct list_head lower; - } adj_list; - - struct { - struct list_head upper; - struct list_head lower; - } all_adj_list; - - netdev_features_t features; - netdev_features_t hw_features; - netdev_features_t wanted_features; - netdev_features_t vlan_features; - netdev_features_t hw_enc_features; - netdev_features_t mpls_features; - netdev_features_t gso_partial_features; - - int ifindex; - int group; - - struct net_device_stats stats; - - atomic_long_t rx_dropped; - atomic_long_t tx_dropped; - atomic_long_t rx_nohandler; - -#ifdef CONFIG_WIRELESS_EXT - const struct iw_handler_def *wireless_handlers; - struct iw_public_data *wireless_data; -#endif - const struct net_device_ops *netdev_ops; - const struct ethtool_ops *ethtool_ops; -#ifdef CONFIG_NET_SWITCHDEV - const struct switchdev_ops *switchdev_ops; -#endif -#ifdef CONFIG_NET_L3_MASTER_DEV - const struct l3mdev_ops *l3mdev_ops; -#endif - - const struct header_ops *header_ops; - - unsigned int flags; - unsigned int priv_flags; - - unsigned short gflags; - unsigned short padded; - - unsigned char operstate; - unsigned char link_mode; - - unsigned char if_port; - unsigned char dma; - - unsigned int mtu; - unsigned short type; - unsigned short hard_header_len; - - unsigned short needed_headroom; - unsigned short needed_tailroom; - - /* Interface address info. */ - unsigned char perm_addr[MAX_ADDR_LEN]; - unsigned char addr_assign_type; - unsigned char addr_len; - unsigned short neigh_priv_len; - unsigned short dev_id; - unsigned short dev_port; - spinlock_t addr_list_lock; - unsigned char name_assign_type; - bool uc_promisc; - struct netdev_hw_addr_list uc; - struct netdev_hw_addr_list mc; - struct netdev_hw_addr_list dev_addrs; - -#ifdef CONFIG_SYSFS - struct kset *queues_kset; -#endif - unsigned int promiscuity; - unsigned int allmulti; - - - /* Protocol-specific pointers */ - -#if IS_ENABLED(CONFIG_VLAN_8021Q) - struct vlan_info __rcu *vlan_info; -#endif -#if IS_ENABLED(CONFIG_NET_DSA) - struct dsa_switch_tree *dsa_ptr; -#endif -#if IS_ENABLED(CONFIG_TIPC) - struct tipc_bearer __rcu *tipc_ptr; -#endif - void *atalk_ptr; - struct in_device __rcu *ip_ptr; - struct dn_dev __rcu *dn_ptr; - struct inet6_dev __rcu *ip6_ptr; - void *ax25_ptr; - struct wireless_dev *ieee80211_ptr; - struct wpan_dev *ieee802154_ptr; -#if IS_ENABLED(CONFIG_MPLS_ROUTING) - struct mpls_dev __rcu *mpls_ptr; -#endif - -/* - * Cache lines mostly used on receive path (including eth_type_trans()) - */ - unsigned long last_rx; - - /* Interface address info used in eth_type_trans() */ - unsigned char *dev_addr; - -#ifdef CONFIG_SYSFS - struct netdev_rx_queue *_rx; - - unsigned int num_rx_queues; - unsigned int real_num_rx_queues; -#endif - - unsigned long gro_flush_timeout; - rx_handler_func_t __rcu *rx_handler; - void __rcu *rx_handler_data; - -#ifdef CONFIG_NET_CLS_ACT - struct tcf_proto __rcu *ingress_cl_list; -#endif - struct netdev_queue __rcu *ingress_queue; -#ifdef CONFIG_NETFILTER_INGRESS - struct list_head nf_hooks_ingress; -#endif - - unsigned char broadcast[MAX_ADDR_LEN]; -#ifdef CONFIG_RFS_ACCEL - struct cpu_rmap *rx_cpu_rmap; -#endif - struct hlist_node index_hlist; - -/* - * Cache lines mostly used on transmit path - */ - struct netdev_queue *_tx ____cacheline_aligned_in_smp; - unsigned int num_tx_queues; - unsigned int real_num_tx_queues; - struct Qdisc *qdisc; - unsigned long tx_queue_len; - spinlock_t tx_global_lock; - int watchdog_timeo; - -#ifdef CONFIG_XPS - struct xps_dev_maps __rcu *xps_maps; -#endif -#ifdef CONFIG_NET_CLS_ACT - struct tcf_proto __rcu *egress_cl_list; -#endif -#ifdef CONFIG_NET_SWITCHDEV - u32 offload_fwd_mark; -#endif - - /* These may be needed for future network-power-down code. */ - struct timer_list watchdog_timer; - - int __percpu *pcpu_refcnt; - struct list_head todo_list; - - struct list_head link_watch_list; - - enum { NETREG_UNINITIALIZED=0, - NETREG_REGISTERED, /* completed register_netdevice */ - NETREG_UNREGISTERING, /* called unregister_netdevice */ - NETREG_UNREGISTERED, /* completed unregister todo */ - NETREG_RELEASED, /* called free_netdev */ - NETREG_DUMMY, /* dummy device for NAPI poll */ - } reg_state:8; - - bool dismantle; - - enum { - RTNL_LINK_INITIALIZED, - RTNL_LINK_INITIALIZING, - } rtnl_link_state:16; - - void (*destructor)(struct net_device *dev); - -#ifdef CONFIG_NETPOLL - struct netpoll_info __rcu *npinfo; -#endif - - possible_net_t nd_net; - - /* mid-layer private */ - union { - void *ml_priv; - struct pcpu_lstats __percpu *lstats; - struct pcpu_sw_netstats __percpu *tstats; - struct pcpu_dstats __percpu *dstats; - struct pcpu_vstats __percpu *vstats; - }; - - struct garp_port __rcu *garp_port; - struct mrp_port __rcu *mrp_port; - - struct device dev; - const struct attribute_group *sysfs_groups[4]; - const struct attribute_group *sysfs_rx_queue_group; - - const struct rtnl_link_ops *rtnl_link_ops; - - /* for setting kernel sock attribute on TCP connection setup */ -#define GSO_MAX_SIZE 65536 - unsigned int gso_max_size; -#define GSO_MAX_SEGS 65535 - u16 gso_max_segs; - -#ifdef CONFIG_DCB - const struct dcbnl_rtnl_ops *dcbnl_ops; -#endif - u8 num_tc; - struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE]; - u8 prio_tc_map[TC_BITMASK + 1]; - -#if IS_ENABLED(CONFIG_FCOE) - unsigned int fcoe_ddp_xid; -#endif -#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) - struct netprio_map __rcu *priomap; -#endif - struct phy_device *phydev; - struct lock_class_key *qdisc_tx_busylock; - bool proto_down; -}; \ No newline at end of file diff --git a/study/kernel/04-net/README.md b/study/kernel/04-net/README.md new file mode 100644 index 0000000..fb9163c --- /dev/null +++ b/study/kernel/04-net/README.md @@ -0,0 +1,47 @@ +进程虚拟地址空间 +======= + +| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | +| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| +| 2016-06-14 | [Linux-4.7](http://lxr.free-electrons.com/source/?v=4.7) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux内存管理](http://blog.csdn.net/gatieme/article/category/6225543) | + +http://blog.sina.com.cn/s/blog_4b9eab320102vme0.html + +http://blog.csdn.net/geekcome/article/details/7971463 + +http://blog.chinaunix.net/uid-29478572-id-4119158.html + +https://yq.aliyun.com/articles/5862 + +http://blog.sina.com.cn/s/blog_4b9eab320102v9qn.html + +http://blog.csdn.net/shanshanpt/article/details/19918171 + +http://blog.chinaunix.net/uid-21768364-id-2936798.html + +http://www.linuxidc.com/Linux/2012-09/70700.htm + +http://www.oschina.net/question/234345_47845 + +http://xuela-net.iteye.com/blog/1899566 + +http://blog.chinaunix.net/uid-22359610-id-1626525.html + +http://www.360doc.com/content/15/0522/07/18252487_472352496.shtml + +http://www.openstack.cn/?p=4756 + +http://weibo.com/p/1001603837806467238143 + +大家都知道TCP/IP协议栈现在是世界上最流行的网络协议栈,恐怕它的普及的最重要的原因就是其清晰的层次结构以及清晰定义的原语和接口。不仅使得上层应用开发者可以无需关心下层架构或者内部机制,从而相对透明的操作网络。这个明显的层次结构也可以在Linux内核的网络协议栈中观察到。 +主要的参考文献是:Linux网络栈剖析(中文版)/Anatomy of Linux networking stack(英文原版)by Tim Jones. +以及:Linux内核2.4.x的网络接口结构 +另外一些参考资料可以从这个页面找到:http://www.ecsl.cs.sunysb.edu/elibrary/linux/network/ (纽约州立大学石溪分校的页面) +Linux内核网络协议栈采用了如下的层次结构: + +http://www.ibm.com/developerworks/cn/linux/l-linux-networking-stack/ +http://www.ibm.com/developerworks/linux/library/l-linux-networking-stack/ + +http://gjiwwa.blu.livefilestore.com/y1p99O_6n29_58mKHdfUgbvzgKOsD5_7unXA5noegNcJ9Y2h3QMaQ-m0Rb9JGP1v_X4zI7-n7J6aqbOm1xr-HMy56E3YJZbWajO/Linux%E5%86%85%E6%A0%B82.4.x%E7%9A%84%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E7%BB%93%E6%9E%84.pdf?download + +http://www.ecsl.cs.sunysb.edu/elibrary/linux/network/ \ No newline at end of file From e5babd1fc0a9d1a5393544b31303fe9ea54c5458 Mon Sep 17 00:00:00 2001 From: gatieme Date: Tue, 6 Sep 2016 12:59:43 +0800 Subject: [PATCH 5/6] ... --- .../README.md | 0 study/kernel/04-net/02-description/README.md | 206 ++++++++++++++++++ .../images/advance_network_stack_layout.gif | Bin 0 -> 8452 bytes study/kernel/04-net/images/data_struct.gif | Bin 0 -> 11729 bytes .../04-net/images/network_stack_layout.gif | Bin 0 -> 6387 bytes .../04-net/images/sk_buff_connection.gif | Bin 0 -> 9064 bytes 6 files changed, 206 insertions(+) rename study/kernel/04-net/{01-description => 01-backgroud}/README.md (100%) create mode 100644 study/kernel/04-net/02-description/README.md create mode 100644 study/kernel/04-net/images/advance_network_stack_layout.gif create mode 100644 study/kernel/04-net/images/data_struct.gif create mode 100644 study/kernel/04-net/images/network_stack_layout.gif create mode 100644 study/kernel/04-net/images/sk_buff_connection.gif diff --git a/study/kernel/04-net/01-description/README.md b/study/kernel/04-net/01-backgroud/README.md similarity index 100% rename from study/kernel/04-net/01-description/README.md rename to study/kernel/04-net/01-backgroud/README.md diff --git a/study/kernel/04-net/02-description/README.md b/study/kernel/04-net/02-description/README.md new file mode 100644 index 0000000..75a83a4 --- /dev/null +++ b/study/kernel/04-net/02-description/README.md @@ -0,0 +1,206 @@ +进程虚拟地址空间 +======= + +| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | +| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| +| 2016-06-14 | [Linux-4.7](http://lxr.free-electrons.com/source/?v=4.7) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux内存管理](http://blog.csdn.net/gatieme/article/category/6225543) | + + +#1 Linux 网络栈剖析 +------- + +**从socket 到设备驱动程序** + +`Linux®`操作系统的最大特性之一就是它的网络栈. 它最初源于 BSD 的网络栈,具有一套非常干净的接口,组织得非常好。其接口范围从协议无关层(例如通用 socket 层接口或设备层)到各种网络协议的具体层。本文将从分层角度对 Linux 网络栈的接口进行探索,并介绍其中的一些主要结构. + + +#2 协议简介 +------- + +虽然对于网络的正式介绍一般都参考了 OSI(Open Systems Interconnection)模型, 但是本文对 Linux 中基本网络栈的介绍分为四层的 Internet 模型(如图 1 所示). + + +![图 1. 网络栈的 Internet 模型](../images/network_stack_layout.gif) + + + +这个栈的最底部是**链路层**, 链路层是指提供对物理层访问的设备驱动程序,这可以是各种介质,例如串口链路或以太网设备 + +链路层上面是**网络层**, 它负责将报文定向到目标位置. 再上一层称为传输层,负责端到端的通信(例如,在一台主机内部). 尽管网络层负责管理主机之间的通信,但是传输层需要负责管理主机内部各端之间的通信。最后一层是应用层,它通常是一个语义层,能够理解要传输的数据. 例如,超文本传输协议(HTTP)就负责传输服务器和客户机之间对 Web 内容的请求与响应。 + + +实际来说,网络栈的各个层次有一些更为人所熟知的名字. + +* 在**链路层**上,可以找到以太网, 这是最常用的一种高速介质. 更早的链路层协议包括一些串口协议,例如 SLIP(Serial Line Internet Protocol)、CSLIP(Compressed SLIP)和PPP(Point-to-Point Protocol) + +* 最常见的**网络层**协议是 IP(Internet Protocol),但是网络层中还存在一些满足其他需求的协议,例如 ICMP(Internet Control Message Protocol)和ARP( Address Resolution Protocol) + +* 在**传输层**上是 TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol) + +* 最后, **应用层**中包含很多大家都非常熟悉的协议,包括标准的 Web 协议 HTTP 和电子邮件协议 SMTP(Simple Mail Transfer Protocol). + +
+ +| TCP/IP层 | 协议 | +|:----------:|:-----:| +| 数据链路层 | ARP,RARP | +| 网络层 | IP,ICMP,IGMP | +| 传输层 | TCP ,UDP,UGP | +| 应用层 | Telnet,FTP,SMTP,SNMP | + + +#3 核心网络架构 +------- + +现在继续了解Linux网络栈的架构以及如何实现这种Internet模型. + +下图提供了 Linux 网络栈的高级视图 + + + +![图 2. Linux 高级网络栈架构](../images/advance_network_stack_layout.gif) + +最上面是用户空间层,或称为**应用层(Application layout)**,其中定义了网络栈的用户 + +底部是**物理设备(Physical device hardware)**, 提供了对网络的连接能力(串口或诸如以太网之类的高速网络). 中间是内核空间, 即网络子系统, 也是本文介绍的重点. 流经网络栈内部的是socket缓冲区(sk_buffs), 它负责在源和汇点之间传递报文数据. + +首先,让我们来快速浏览一下**Linux网络子系统的核心元素**, 后续章节中会更详细进行介绍. + +顶部是**系统调用接口(System call interface)**, 它简单地为用户空间的应用程序提供了一种访问内核网络子系统的方法 + +位于其下面的是一个**协议无关层(Protocol agnostic interface)**, 它提供了一种通用方法来使用底层传输层协议 + +然后是**实际协议(Network protocols)** , 在 Linux中包括内嵌的协议TCP、UDP, 当然还有IP. + +然后是另外一个**协议无关层(Device agnostic interface)**, 提供了与各个设备驱动程序通信的通用接口 + +最下面是**设备驱动程序(Device driders)**本身. + + +##3.1 系统调用接口 +------- + + +系统调用接口可以从两个角度进行描述. 用户发起网络调用时, 通过系统调用接口进入内核的过程应该是多路的. 最后调用`net/socket.c`中的`sys_socketcall` 结束该过程, 然后进一步将调用分路发送到指定目标. + +系统调用接口的另一种描述是使用普通文件操作作为网络I/O. 例如, 典型的读写操作可以在网络`socket`上执行(`socket`使用一个文件描述符表示, 与一个普通文件一样). 因此, 尽管有很多操作是网络专用的(使用`socket`调用创建一个 `socket`, 使用`connect`调用连接一个收信方, 等等), 但是也有一些标准的文件操作可以应用于网络对象, 就像操作普通文件一样. + +最后, 系统调用接口提供了在用户空间应用程序和内核之间转移控制的方法. + + +##3.2 协议无关接口 +------- + +`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` 等等). + + + +##3.3 网络协议 +------- + + +网络协议这一节对一些可用的特定网络协议作出了定义(例如TCP、UDP等). 它们都是在[`linux/net/ipv4/af_inet.c`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c)文件中一个名为[`inet_init`的函数](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1754)中进行初始化的(因为TCP和UDP都是inet簇协议的一部分). + +[`inet_init`函数](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1754)使用[`proto_register`](http://lxr.free-electrons.com/source/net/core/sock.c?v=4.7#L2902)函数来注册每个内嵌协议. 这个函数是在[`linux/net/core/sock.c`](http://lxr.free-electrons.com/source/net/core/sock.c?v=4.7)中定义的, 除了可以将这个协议添加到活动协议列表中之外, 如果需要, 该函数还可以选择分配一到多个`slab` 缓存. + +通过[`net/ipv4`](http://lxr.free-electrons.com/source/net/ipv4/?v=4.7)目录中[`udp.c`](http://lxr.free-electrons.com/source/net/ipv4/udp.c?v=4.7)和[`raw.c`](http://lxr.free-electrons.com/source/net/ipv4/raw.c?v=4.7)文件中的`proto`接口, 您可以了解各个协议是如何标识自己的. 这些协议接口每个都按照类型和协议映射到[`inetsw_array`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L999), 该数组将内嵌协议与操作映射到一起. [`inetsw_array`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L999)结构及其关系如图3 所示 + +![图 3. Internet 协议数组结构](../images/data_struct.gif) + + +最初, 会调用[`inet_init`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1754)中的[`inet_register_protosw`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1037)将这个数组中的每个协议都初始化为[`inetsw`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L128), 函数[`inet_init`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1754)也会对各个`inet`模块进行初始化, 例如ARP、ICMP和IP模块, 以及TCP和UDP模块. + +>Socket 协议的相互关系 +> +>回想以下在创建 socket 时,需要指定类型和协议,例如my_sock = socket( AF_INET, SOCK_STREAM, 0 )。AF_INET 表示一个 Internet 地址簇,它使用的是一个流 socket,定义为 SOCK_STREAM(如此处的 inetsw_array 所示). + + +注意在图中, [`proto`](http://lxr.free-electrons.com/source/include/net/sock.h?v=4.7#L970)结构定义了传输特有的方法, 而[`proto_ops`](http://lxr.free-electrons.com/source/include/linux/net.h?v=4.7#L132)结构则定义了通用的`socket`方法. 可以通过调用[`inet_register_protosw`](http://lxr.free-electrons.com/source/net/ipv4/af_inet.c?v=4.7#L1037)将其他协议加入到 inetsw协议中. 例如, SCTP就是通过调用[`net/sctp/protocol.c`](http://lxr.free-electrons.com/source/net/sctp/protocol.c?v=4.7) 中的 [`sctp_init`](http://lxr.free-electrons.com/source/net/sctp/protocol.c#L1353?v=4.7)加入其中的 + +有关`SCTP`的更多信息,请参阅[SCTP优化网络](http://www.ibm.com/developerworks/cn/linux/l-sctp/) + +`socket`中的数据移动是使用一个所谓的`socket`缓冲区([`sk_buff`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L626))的核心结构实现的. + +`sk_buff`中包含了报文数据, 以及涉及协议栈中多个层次的状态数据. 所发送或接收的每个报文都是使用一个`sk_buff `示的. `sk_buff`结构是在 [`linux/include/linux/skbuff.h`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7)中定义的, 如下图所示. + + +![图 4. Socket 缓冲区及其与其他结构的关系](../images/sk_buff_connection.gif) + + + + +多个`sk_buff`可以针对某个给定连接链接在一起. 每个`sk_buff`都在设备结构(`net_device`)中标识报文发送的目的地, 或者接收报文的来源地. 由于每个报文都是使用一个`sk_buff`表示的, 因此报文头都可以通过一组指针(th、iph 和mac[用于Media Access Control或者MAC头])方便地进行定位. + + +![多个`sk_buff`可以针对某个给定连接链接在一起](../images/dou_link.png) + + +由于`sk_buff`是`socket`数据管理的中心, 因此创建了很多支持函数来对它们进行管理. 其中有些函数用于创建和销毁`sk_buff`结构, 或对它进行克隆或排队管理. + + +针对给定的`socket`, `Socket`缓冲区可以链接在一起, 这样可以包含众多信息, 包括到协议头的链接、时间戳(报文是何时发送或接收的), 以及与这个报文相关的设备. + + +##3.4 设备无关接口 +------- + + +协议层下面是另外一个无关接口层, 它将协议与具有很多各种不同功能的硬件设备连接在一起。这一层提供了一组通用函数供底层网络设备驱动程序使用,让它们可以对高层协议栈进行操作. + + +* 首先, 设备驱动程序可能会通过调用[`register_netdevice`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L6983)或[`unregister_netdevice`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L2361)在内核中进行注册或注销. + + 1. 调用者首先填写[`net_device`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L1607)结构 + + 2. 然后传递这个结构进行注册. 内核调用它的init函数(如果定义了这种函数), 然后执行一组健全性检查, 并创建一个`sysfs`条目, 然后将新设备添加到设备列表中(内核中的活动设备链表). 在[`linux/include/linux/netdevice.h`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7)中可以找到这个[`net_device`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L1607)结构 + + 3. 这些函数都是在[`net/core/dev.c`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7)中实现的 + +* 要从协议层向设备中发送`sk_buff`, 就需要使用[`dev_queue_xmit`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3432)函数. 这个函数可以对`sk_buff`进行排队, 从而由底层设备驱动程序进行最终传输(使用`sk_buff`中引用的[`net_device`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L1607)或 [`sk_buff->dev`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L641)所定义的网络设备). dev结构[`net_device`](http://lxr.free-electrons.com/source/include/linux/netdevice.h?v=4.7#L1607)中包含了一个名为hard_start_xmit的方法(位于`net_device->net_device_ops->ndo_start_xmit`), 其中保存有发起`sk_buff`传输所使用的驱动程序函数. + +* 报文的接收通常是使用[`netif_rx`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3830)执行的. + + 1. 当底层设备驱动程序接收一个报文(包含在所分配的`sk_buff`中)时, 就会通过调用[`netif_rx`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3830)将[`sk_buff`](http://lxr.free-electrons.com/source/include/linux/skbuff.h?v=4.7#L626)上传至网络层. + + 2. 然后, 这个函数通过`__napi_schedule`(早期内核通过`netif_rx_schedule`)将 sk_buff 在上层协议队列中进行排队, 供以后进行处理。可以在 linux/net/core/dev.c 中找到[`dev_queue_xmit`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3432)和[`netif_rx`](http://lxr.free-electrons.com/source/net/core/dev.c?v=4.7#L3830)函数. + + + + +后来, 内核中引入了一种新的应用程序编程接口(NAPI), 该接口允许驱动程序与设备无关层(dev)进行交互. 有些驱动程序使用的是NAPI, 但是大多数驱动程序仍然在使用老式的帧接收接口(比例大约是6比1). NAPI在高负载的情况下可以产生更好的性能, 它避免了为每个传入的帧都产生中断. + + +`netif_rx_schedule`这个函数, 取而代之的是`__napi_schedule`, 可以到[`LXR?v=2.6.30;i=netif_rx_schedule`](http://lxr.free-electrons.com/ident?v=2.6.30;i=netif_rx_schedule)查证. + + +##3.5 设备驱动程序 +------- + + +网络栈底部是负责管理物理网络设备的设备驱动程序. 例如, 包串口使用的 SLIP 驱动程序以及以太网设备使用的以太网驱动程序都是这一层的设备. + +在进行初始化时, 设备驱动程序会分配一个`net_device`结构, 然后使用必须的程序对其进行初始化. + +这些程序中有一个是`hard_start_xmit`的方法(位于`net_device->net_device_ops->ndo_start_xmit`), 它定义了上层应该如何对 `sk_buff`排队进行传输. 这个程序的参数为`sk_buff`. 这个函数的操作取决于底层硬件, 但是通常`sk_buff`所描述的报文都会被移动到硬件环或队列中. 就像是设备无关层中所描述的一样, 对于NAPI兼容的网络驱动程序来说, 帧的接收使用了`netif_rx`和`netif_receive_skb`接口. + +NAPI 驱动程序会对底层硬件的能力进行一些限制. 有关更详细的信息,请参阅[NAPI接口和设计](http://linux-net.osdl.org/index.php/NAPI) + + +设备驱动程序在`dev`结构中配置好自己的接口之后, 调用`register_netdevice`便可以使用该配置. 在[`drivers/net`](http://lxr.free-electrons.com/source/drivers/net?v=4.7)中可以找出网络设备专用的驱动程序. + + +#4 展望 +------- + + +Linux 源代码是学习有关大多数设备类型的设备驱动程序设计最佳方法, 包括网络设备驱动程序. 在这里可以找到的是各种设计的变化以及对可用内核API的使用, 但是所学到的每一点都会非常有用, 都可以作为新设备驱动程序的起点. 除非您需要一种新协议, 否则网络栈中的其余代码都是通用的, 都会非常有用. 即使现在, TCP(用于流协议)或 UDP(用于基于消息的协议)的实现都可以作为开始新开发有用模块使用. + + diff --git a/study/kernel/04-net/images/advance_network_stack_layout.gif b/study/kernel/04-net/images/advance_network_stack_layout.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f13a12930b4717a6377e220edba7be5ebe3fcad GIT binary patch literal 8452 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 G_x}Lct)4Of literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/images/data_struct.gif b/study/kernel/04-net/images/data_struct.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9479ae675d2252fdcd8babfeb173986a201f4c0 GIT binary patch literal 11729 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 H2B`l(!GZsy literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/images/network_stack_layout.gif b/study/kernel/04-net/images/network_stack_layout.gif new file mode 100644 index 0000000000000000000000000000000000000000..3eacf56cecf11938c9409723767326e54ec281af GIT binary patch literal 6387 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 literal 0 HcmV?d00001 diff --git a/study/kernel/04-net/images/sk_buff_connection.gif b/study/kernel/04-net/images/sk_buff_connection.gif new file mode 100644 index 0000000000000000000000000000000000000000..5409a9292ba07a5f8693fe362e43c348760643ca GIT binary patch literal 9064 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%0A?|=s^ooI)>INc-PFiy)dmRCL&rpqLjD={1 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 T>)}3_MES>ro6mq$05JG}xp;w* literal 0 HcmV?d00001 From 430d9beb62ec9def4651951f2da0d9d10820af48 Mon Sep 17 00:00:00 2001 From: gatieme Date: Tue, 6 Sep 2016 23:53:53 +0800 Subject: [PATCH 6/6] ... --- study/kernel/04-net/02-description/README.md | 84 +++++++++++++++++--- 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/study/kernel/04-net/02-description/README.md b/study/kernel/04-net/02-description/README.md index 75a83a4..70552a7 100644 --- a/study/kernel/04-net/02-description/README.md +++ b/study/kernel/04-net/02-description/README.md @@ -60,34 +60,97 @@ ![图 2. Linux 高级网络栈架构](../images/advance_network_stack_layout.gif) + + 最上面是用户空间层,或称为**应用层(Application layout)**,其中定义了网络栈的用户 -底部是**物理设备(Physical device hardware)**, 提供了对网络的连接能力(串口或诸如以太网之类的高速网络). 中间是内核空间, 即网络子系统, 也是本文介绍的重点. 流经网络栈内部的是socket缓冲区(sk_buffs), 它负责在源和汇点之间传递报文数据. +底部是**物理设备(Physical device hardware)**, 提供了对网络的连接能力(串口或诸如以太网之类的高速网络). -首先,让我们来快速浏览一下**Linux网络子系统的核心元素**, 后续章节中会更详细进行介绍. +中间是内核空间, 即**网络子系统**, 也是本文介绍的重点. 流经网络栈内部的是socket缓冲区(sk_buffs), 它负责在源和汇点之间传递报文数据. -顶部是**系统调用接口(System call interface)**, 它简单地为用户空间的应用程序提供了一种访问内核网络子系统的方法 +| 层次 | 名称 |描述 | +|:-----:|:-----:|:----:| +| Application layout | 应用层 | 网络栈的用户, 即使用网络的各个应用程序 | +| Kernel Space | 内核空间的网络子系统 | 它简单地为用户空间的应用程序提供了一种访问内核网络子系统的方法
流经网络栈内部的是socket缓冲区(sk_buffs), 它负责在源和汇点之间传递报文数据 | +| Physical device hardware | 物理设备 | 提供了对网络的连接能力(串口或诸如以太网之类的高速网络). | -位于其下面的是一个**协议无关层(Protocol agnostic interface)**, 它提供了一种通用方法来使用底层传输层协议 +
+>* 内核在应用程序与网络物理设备之间插入了一个内核空间 +> +>* 内核空间为驱动着网络设备的正常运转, 同时又为应用程序提供可供使用的接口 +
-然后是**实际协议(Network protocols)** , 在 Linux中包括内嵌的协议TCP、UDP, 当然还有IP. -然后是另外一个**协议无关层(Device agnostic interface)**, 提供了与各个设备驱动程序通信的通用接口 +首先,让我们来快速浏览一下**Linux网络子系统的核心元素**, 后续章节中会更详细进行介绍. -最下面是**设备驱动程序(Device driders)**本身. +顶部是**系统调用接口(System call interface)**, 它简单地为用户空间的应用程序提供了一种访问内核网络子系统的方法 + +位于其下面的是一个**协议无关层(Protocol agnostic interface)**, 它提供了一种通用方法来使用底层传输层协议 + +然后是**实际协议(Network protocols)** , 在 Linux中包括内嵌的协议TCP、UDP, 当然还有IP. + +然后是另外一个**设备无关层(Device agnostic interface)**, 提供了与各个设备驱动程序通信的通用接口 + +最下面是**设备驱动程序(Device driders)**本身. + +如下所示 + +| 内核空间层次 | 名称 |描述 | +|:--------------:|:-----:|:----:| +| System call interface | 系统调用接口 | 它简单地为用户空间的应用程序提供了一种访问内核网络子系统的方法 | +| Protocol agnostic interface | 协议无关层 | 它提供了一种通用方法来使用底层传输层协议 | +| Network protocols | 实际协议 | 在 Linux中包括内嵌的协议TCP、UDP, 当然还有IP | +| Device agnostic interface | 设备无关层 | 提供了与各个设备驱动程序通信的通用接口 | +| Device driders | 设备驱动程序 | 提供了网络硬件设备的基础驱动 | + +
+>内核并没有简单的为内核网络子系统实现常规的系统调用接口, 协议层和设备驱动层次3个简单的层次, Linux内核必须支持各种不同的协议和不同的设备, 没有什么问题是通过一个虚拟层无法实现的, 因此内核在不同的层次之间插入了一个协议或者设备无关的层次 +> +>* 系统调用接口和实际协议层之间插入了一个协议无关层 +> +>* 实际协议层与设备驱动程序之间插入了一个设备无关层 +
##3.1 系统调用接口 ------- -系统调用接口可以从两个角度进行描述. 用户发起网络调用时, 通过系统调用接口进入内核的过程应该是多路的. 最后调用`net/socket.c`中的`sys_socketcall` 结束该过程, 然后进一步将调用分路发送到指定目标. +系统调用接口可以从两个角度进行描述. 用户发起网络调用时, 通过系统调用接口进入内核的过程应该是多路的. 最后调用[`net/socket.c`](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2315)中的[`sys_socketcall` ](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2340)结束该过程, 然后进一步将调用分路发送到指定目标. -系统调用接口的另一种描述是使用普通文件操作作为网络I/O. 例如, 典型的读写操作可以在网络`socket`上执行(`socket`使用一个文件描述符表示, 与一个普通文件一样). 因此, 尽管有很多操作是网络专用的(使用`socket`调用创建一个 `socket`, 使用`connect`调用连接一个收信方, 等等), 但是也有一些标准的文件操作可以应用于网络对象, 就像操作普通文件一样. +系统调用接口的另一种描述是使用普通文件操作作为网络I/O. 例如, 典型的读写操作可以在网络`socket`上执行(`socket`使用一个文件描述符表示, 与一个普通文件一样). 因此, 尽管有很多操作是网络专用的(使用`socket`调用创建一个 `socket`, 使用`connect`调用连接一个收信方, 等等), 但是也有一些标准的文件操作可以应用于网络对象, 就像操作普通文件一样. 最后, 系统调用接口提供了在用户空间应用程序和内核之间转移控制的方法. +| 系统调用 | 宏 |描述 | +|:---------:|:------:| +| socketcall | []() | socket系统调用 | +| socket | [SYS_SOCKET](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2341) | 建立socket | +| bind | [SYS_BIND](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2345) | 绑定socket到端口 | +| connect | [SYS_CONNECT](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2347) |连接远程主机 | +| listen | [SYS_LISTEN](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2350) | 监听socket端口 | +| accept | [SYS_ACCEPT](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2353) | 响应socket连接请求 | +| getsockname | [SYS_GETSOCKNAME](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2357) | 取得本地socket名字 | +| getpeername | [SYS_GETPEERNAME](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2362) | 获取通信对方的socket名字 | +| socketpair | [SYS_SOCKETPAIR](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2367) | 创建一对已联接的无名socket | +| send | [SYS_SEND](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2370) | 通过socket发送信息 | +| sendto | [SYS_SENDTO](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2373) | 发送UDP信息 | +| recv | [SYS_RECV](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2377) | 通过socket接收信息 | +| recvfrom | [SYS_RECVFROM](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2380) | 接收UDP信息 | +| recvmsg | 参见recv | +| select | 对多路同步I/O进行轮询 | +| shutdown | [SYS_SHUTDOWN](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2385) | 关闭socket上的连接 | +| getsockopt | [SYS_GETSOCKOPT](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2391) | 取端口设置 | +| setsockopt | [SYS_SETSOCKOPT](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2388) | 设置端口参数 | +| sendmsg | [SYS_SENDMSG](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2396) | 参见send | +| sendmmesg | [SYS_SENDMMSG](http://lxr.free-electrons.com/source/net/socket.c?v=4.7#L2399) | | +| | SYS_RECVMSG | | +| | SYS_RECVMMSG | | +| | SYS_ACCEPT4 | | +| sendfile | 在文件或端口间传输数据 | + + ##3.2 协议无关接口 ------- @@ -177,8 +240,7 @@ 后来, 内核中引入了一种新的应用程序编程接口(NAPI), 该接口允许驱动程序与设备无关层(dev)进行交互. 有些驱动程序使用的是NAPI, 但是大多数驱动程序仍然在使用老式的帧接收接口(比例大约是6比1). NAPI在高负载的情况下可以产生更好的性能, 它避免了为每个传入的帧都产生中断. - -`netif_rx_schedule`这个函数, 取而代之的是`__napi_schedule`, 可以到[`LXR?v=2.6.30;i=netif_rx_schedule`](http://lxr.free-electrons.com/ident?v=2.6.30;i=netif_rx_schedule)查证. +加入了NAPI后, `netif_rx_schedule`这个函数从内核中删除, 取而代之的是`__napi_schedule`, 可以到[`LXR?v=2.6.30;i=netif_rx_schedule`](http://lxr.free-electrons.com/ident?v=2.6.30;i=netif_rx_schedule)查证. ##3.5 设备驱动程序