mzsm / 待分类 / linux内核TCP/IP协议栈(III)

分享

   

linux内核TCP/IP协议栈(III)

2015-05-22  mzsm
数据结构-net_device
结构所在文件:include/linux/netdevice.h,成员结构相当复杂,这个结构也是SKB中的一个成员之一。
unsigned longfeatures;
接口支持的特性。这些标志由内核管理,其中有些由接口在初始化期间设置,用来声明接口的各种能力及特性。
#define NETIF_F_SG1/* Scatter/gather IO. */
#define NETIF_F_IP_CSUM2/* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM4/* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM8/* Can checksum all the packets. */
#define NETIF_F_HIGHDMA32/* Can DMA to high memory. */
#define NETIF_F_FRAGLIST64/* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX128/* Transmit VLAN hw acceleration */
#define NETIF_F_HW_VLAN_RX256/* Receive VLAN hw acceleration */
#define NETIF_F_HW_VLAN_FILTER512/* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED 1024/* Device cannot handle VLAN packets */
#define NETIF_F_GSO2048/* Enable software GSO. */
#define NETIF_F_LLTX4096/* LockLess TX */

unsigned intflags;/* interface flags (a la BSD)*/

 unsignedmtu;/* interface MTU value*/
unsigned shorttype;/* interface hardware type*/
unsigned shorthard_header_len;/* hardware hdr length*/
硬件首部长度,以太网为14B
struct net_device*master;
在启用了bonding网络负载均衡以后,指向bonding的虚拟设备。
unsigned charperm_addr[MAX_ADDR_LEN]; /* permanent hw address */
硬件地址
void*ip_ptr;/* IPv4 specific data*/
IPv4相关设置存放在这个字段中,指针指向struct in_device。涉及到IP编址的部分内容,见下一个章节。
Int (*poll)(struct net_device *dev, int *quota);
网卡设备dev接收报文时候的轮询函数。
Int quota
读取数据包的配额,动态变化,每次从网络设备中读取数据包的时候,会从中减去本次读取的数据包数。当配额小于0时,结束轮询,这样即使当前网络设备上有大量的数据包输入,也能保证其他设备及时接收数据包。
网络设备的注册启用禁用
这部分内容并非协议栈的重点,这里不在展开来讲
IP编址
IP地址的组织
与IPv4相关的配置存放在in_device(IP配置快)结构中,IP地址、子网掩码、广播地址等信息放在in_ifaddr结构中。
 
struct in_device
所在文件:include/linux/inetdevice.h
IP配置块。
网络设备层与IPv4相关的配置再放在in_device结构中,应用层可以通过ip或者ifconfig工具来修改这些配置。该结构的实例保存在net_device结构成员ip_ptr指针中。只有为设备设置第一个IP地址的时候,在函数inetdev_init()中才会分配并初始化in_device结构实例。
struct in_ifaddr*ifa_list;/* IP ifaddr chain*/
指向in_ifaddr结构的链表。in_ifaddr结构中存储了网络设备的IP地址,因为一个网络设备可配置多个IP地址,因此需要链表来存储。
in_ifaddr结构
in_ifaddr结构:用于存储主机的IP地址、子网掩码、广播地址,这些配置属于主机,但是又配置到网络设备上,一个网络设备有多少个IP地址,就有多少了IP地址块。
管理函数
函数所在文件:net/ipv4/devinet.h
inetdev_init()
为通过参数指定的网络设备分配IP配置块。
inet_select_addr()
再通过输出网络设备向目的地址发送报文的时候,如果没有指定源地址,会调用这个函数来根据给定的设备、目的地址和作用范围,获取给定作用范围的主IP地址作为源地址。
Dev:获取源地址的网络设备
Dst:目的地址
Scope:作用范围
RT_SCOPE_HOST
RT_SCOPE_LINK
RT_SCOPE_UNIVERSE
使用for_primary_ifa宏遍历到第一个符合条件的IP地址。inet_ifa_match函数用来判断两个IP是不是属于一个字网。优先选定在一个网段的源IP,否则的话随便选一个。
IP地址的设置
Ifconfig---->ioctl
Ip address---->netlink

Ioctl和netlink的相关知识不在本讲的范围内,请自行查阅相关资料。
第二部分 接口层
接口层的输入
1、背 景
系统如何得知数据包的到达并接收?
方案一:当数据包到达网络设备的时候,通常会触发硬件中断。系统在不支持软中断时,数据包的输入只能完全由硬件中断处理。缺点:频繁的硬件中断占用过多的CPU资源,使得用户进程处于饥渴状态。
方案二:数据包到达网络设备不会触发硬件中断,在这种情况下,只能通过定时器轮询网络设备的状态,发现有数据包到达时,才从网络设备中读取数据包并输入到协议栈。这种情况下,数据包的输入完全依赖于定时器触发的频率,如果频率过高,同样也消耗CPU资源,频率过低,数据包吞吐量过分低下。
2、接口层的初始化
net_dev_init():所在文件:net/core/dev.c
函数解释:
 softnet_data结构
位置:include/linux/netdevice.h
描述了与网络软中断处理相关的报文输入和输出队列,每个CPU有一个单独的softnet_data实例,因此在操作该结构中的成员时不必加锁。
struct net_device *output_queue:
数据包输出软中断中输出数据包的网络设备队列。处于报文输出状态的网络设备添加到该队列上,在数据包输出软中断中,会遍历该队列,从网络设备的排队规则中获取数据包并输出。
struct sk_buff_head input_pkt_queue:
非NAPI的接口缓存队列。对于非NAPI的驱动,通常在硬中断中或通过轮询读取报文后,调用netif_rx()将接收到的报文传递到上层,即先将报文缓存到input_pkt_queue队列中,然后产生一个数据包输入软中断,由软中断例程将报文传递到上层。这在接口接收数据包的速率比协议栈和应用层快的时候非常有用。队列长度上限参见系统参数netdev_max_backlog。
struct list_head poll_list:
网络设备轮询队列。处于报文接受状态的网络设备链接到该队列上,在数据报输入软中断中,会遍历该队列,通过轮询方式接受报文。
struct sk_buff *completion_queue:
完成发送数据包的等待释放队列。需在适当的时机释放发送完成的数据,在发送报文软中断中会检测该队列。
NAPI
NAPI是中断机制与轮询机制的混合体,能有效的提高网络处理速度。在网络负荷较重的时候,NAPI可以显著减少由于接受数据包而产生的硬中断数量,对于高速率、短长度的数据包的处理非常有效。
实现方法:当一批数据包中的第一个数据包到达网络设备的时候,会以硬中断的方式通知系统;在硬终端例程中(网卡设备的中断驱动程序),系统将该设备添加到CPU的设备轮询队列中,并关闭中断,同时激活数据包输入软中断;由软中断例程遍历轮询队列中的网络设备,从中读取数据包。这样,在内核从网络设备中接收报文的过程中,若有新的报文到来,NAPI也无需执行中断例程,只需要维护队列,就能读到新的报文。
网络设备中断例程
加红部分:禁止该网络设备上的中断,并将网络设备添加到网络设备轮询队列当中去。
软中断
Net_rx_action():文件位置:net/core/dev.c

if (dev->quota <= 0 || dev->poll(dev, &budget)) 
本次读取报文的配额已用完,或者经过一次轮询后还有报文没读完。
softnet_break:
对本次读取报文数量的总配额已经用完……..
轮询处理
文件位置:e100.c
E100_rx_clean()从网络设备中读取接收到的报文,并输入到上层协议中。
E100_tx_clean()释放已发送的报文(已经接收完毕)。
如果待输出和输入的报文都已经处理完成,则退出轮询模式,并从网络设备轮训队列中删除该网络设备。
ok ,就写到这里了,我想静静,下一节讲述接口层输入/出的处理等、(本文可作为读书笔记)[bm会心笑]










    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>