Linux关键数据结构

来源:互联网 发布:比较好的数据恢复软件 编辑:程序博客网 时间:2024/05/19 09:48
Linux网络子系统中存在一些很重要的数据结构,贯穿整个子系统,主要有以下两个:
struct sk_buff
    数据封包结构。所有网络分层都会使用这个结构来存储其报头、有关用户数据,协调其他工作的其他内部信息。
struct net_device
    在Linux内核中,每种网络设备都用这个数据结构表示,包括软硬件的配置信息。

一、套接字缓冲区:sk_buff结构
这可能是Linux网络代码中最重要的数据结构,表示数据报文。这个结构定义在头文件中,由巨大的变量堆组成,试图满足所有人的所有需求。
在网络系统的不同网络层都会使用这个结构,而当这个结构从一个分层传到另一个分层时,其不同的字段会随之发生改变。如L4层在传递给L3之前会附加一个报头,通用L3到L2之前也会加上自己的报头。附加报头比把数据从一个分层拷贝到另一个分层更有效率。
由于要在一个缓冲区开端新增空间(也就是修改指向缓冲区头部的指针),内核提供了skb_reserve函数来执行这个操作。所以,当缓冲区往下传递给每个网络层时,每层的协议首先要做的就是调用skb_reserve函数为该协议的报头预留空间。
而在缓冲区向上传递给上层网络时,并没有本层报头从缓冲区中删除,二是将直线有效数据的指针向前移到上层的报头位置。
由于网络代码提供了大量的选项性功能,不一定总是需要,如防火墙、多播、连接跟踪等,这些功能都会在sk_buff结构中附加上字段。因此,sk_buff结构中有许多由C预处理#ifdef指令附加的字段。一般而言,任何引起内核数据结构改变的选项,都不适合编译成一个模块进行动态加载。  
sk_buff元素列表



sk_buff_data_t tail
sk_buff_data_t end
unsigned char *head
unsigned char *data
这些字段代表缓冲区的边界以及其中的数据。当每一层为其工作而准备缓冲区时,可能会为了一个报头或更多的数据分配更多的空间。head和end指向已分配空间的开端和尾端,而data和tail指向实际数据的开端和尾端。


从第二层移往第三层时报头指针的初始化:


缓冲区的克隆和拷贝


二、net_device结构

net_device结构存储特定网络设备的所有信息。不管真实设备如网卡还是虚拟设备如网桥,都有这样一个结构。它插入在一个全局列表和两张hash表中(如下图)。这些不同的结构可以让内核按需求浏览或查询net_device数据库。


一个网络设备可用,就必须被内核认可,并且关联正确的驱动程序。驱动程序把设备需求的所有信息存储在私有数据结构中,然后与其他需要此设备的内核组件交互。因此,网络设备的注册和初始化任务一部分有内核完成,一部分有设备驱动程序负责。

设备和内核之间的交互方式:

    轮询:有内核侧驱动。内核定期检查设备状态,了解设备发生了什么。

    中断:有设备侧驱动。当设备需要内核注意时,向内核发送一个硬件信号(中断事件)。

热插拔设备

Linux内核引入热插拔是为了实现受欢迎的即插即用功能。这项功能让内核去侦测可热插拔设备的插入和删除,然后通知一个用户应用程序,使其在必须要时加载相关联的驱动程序,或者当驱动程序存在时应用相关联的配置。

虚拟设备

虚拟设备是建立在一个或多个设备上的抽象如下图:


linux允许定义多种不同的虚拟设备:

  • 绑定:虚拟设备绑定一组物理设备,使其如同单一设备;
  • 802.1Q:建立VLAN使用;
  • 桥接:桥接接口;
  • 别名接口:让同一个NIC具有不同的虚拟NIC;
  • 普通均衡器:用于流量控制;
  • 隧道接口:IP-over-IP隧道以及GRE协议的实现基础是虚拟设备的建立;
设备注册
在加载NIC设备驱动程序和插入热插拔网络设备时会进行网络设备的注册工作,这个时候就会分配一个dev即net_device结构数据。每个设备都会根据其设备类型被分配一个名字,而且为了唯一性还会包含一个数字,该数字的分配是按已注册的同类设备数量而连续指定,如Eth设备依次是eth0、eth1等。

设备注册状态通知
内核组件和用户空间应用程序可能都想知道何时发生网络设备注册、除名、关闭或者开启之事。这类事件通过两种两种通道传送:
netdev_chain
    内核组件可以注册此通知链。比如:路由、防火墙、ARP/IP、虚拟设备、RTnetlink等。
NetLink的多播群组
    用户空间应用程序可以注册RTnetlink的RTMGRP_LINK多播群组。比如Netplugd守候进程用于监测网络接口并在接口状态改变时执行命令。


0 0
原创粉丝点击