net_device结构有三个标识符,不能搞混。
int ifindex
独一无二的ID,当设备以dev_new_index注册时分派给的每个设备。
int iflink
这个字段主要是由隧道设备使用,可以用于标识抵达隧道另一端的真实设备。
unsigned short dev_id
目前在zSeries OSA NIC上由IPv6所用,此字段用于区别可由不同OS同时共享的同一种设备的诸多虚拟实例,参见/net/ipv6/addrconf.c 中的注释。
配置
有些配置字段由内核根据网络设备的各种类给定一个默认值,而其他字段给驱动程序填写,如前所述,驱动程序可以改变默认值,而有些字段甚至可以在执行期间通过像ifconfig 和ip
的命令予以改变,事实上,有些参数,--base_addr, if_port dma以及irq 通常是在设备模块加载时由用户设置的,另一方面,虚拟设备不会使用这些参数。
char name[IFNAMSIZ]
设备的名称
unsigned long mem_start;
unsigned long mem_end
这些字段描述设备所用的共享内存,用于设备鱼内核沟通,其初始化和访问智慧在设备驱动程序内进行, 较高分层不需要关心这些字段。
unsigned long base_addr
设备自有内存映射到IO内存的起始地址。
unsigned int irq
设备用于内核对话的中断编号,此值可以由多个设备共享,驱动程序适用request_irq函数分配此变量,并且使用free_irq予以释放。
unsigned char if_port
此接口所使用的端口类型,参见下一节 接口类型和端口
unsigned char dma
设备所使用的DMA通道,为了从内核获取和释放DMA通道,文件kernel/dma.c 定义了函数request_dma和free_dma,取得DMA通道之后,要予以开启或者关闭时,可以使用各种include/asm-architechture 文件中,所提供的enable dma和disable dma,这些函数由ISA设备使用,PCI设备采用了其他的方法,因而不需要这些函数。
并非所有设备都可以用DMA,因为有些总线不适用DMA。
unsigned short flags
unsigned short gflags
unsigned short priv_flags
flags字段中的某些位代表网络设备的功能,而其他位代表状态的改变,你可以在include/linuxi/if.h 中发现这些标识的完整列表,此设备驱动程序通常会初始化期间设置这些功能,而这些状态标识由内核管理,以响应外部事件,这些标识的设置可以通过熟悉的ifconfig命令查看。
ifconfig lo
这些例子中,UP_LOOKBACK RUNNING就相当于标识IFF_UP IFF_LOOPBACK以及IFF_RUNNING。
priv_flags 用于存储用户空间不可见的标识,目前而言,此字段由VLAN和Bridge虚拟设备使用,gflags 几乎已经不再使用了,只是由于兼容性的原因二存在,这些标识可通过dev_change_flags 函数进行修改。
int features
这是另一组标识位,用于存储其他一些设备功能,为此数据结构包含多个标识变量并非是多余的。features字段可报告适配卡的功能,以便与CPU通信,如适配卡能否对高端内存做DMA或者硬件能否对所有封包做校验和工作。可能的特征功能的列表定义在net_device 结构本身之内,此参数由设备驱动程序初始化。你可以在net_device数据结构定义中找到NETIF_F_XXX特征功能列表以及很好的注释。
unsigned mtu
MTU代表最大传输单元Maximum Transmission Unit 表示设备能处理的帧的最大尺寸,表2-1是最常见的网络技术的MTU取值。
设备类型 MTU
PPP 296
SLIP 296
Ethernet 1500
ISDN 1500
PLIP 1500
Wavelan 1500
EtherChannel 2024
FDDI 4352
Token Ring 4MB/s 4464
Token Bus 8182
Token Ring 16 MB/s 17914
Hyperchannel 65535
Ethernet MTU值有必要澄清一下。Ethernet帧规范把最大有效载荷尺寸定为1500个字节。有时候,你会发现Ethernet MTU定义为1518 或者1514,第一个Ethernet帧的最大尺寸包括报头在内,而第二个包括报头但不含帧检查序列
在1998年,Alten Networks 提议把Ehternet帧的最大载荷增加至9KB,后来,这项提议正式成为一份IETF因特网草案,但是IEEE没有接受,在IEEE规范中,帧的有效载荷若超过1500个字节,通常就称为巨大帧,与Gigabit Ethernet一起使用以增加吞吐量。这是因为对于大型数据传输,帧越大所需要的帧数目就越少,终端也就减少,因此CPU的使用也会减少,报头所需的消耗也会变少,等等。有关增加Ethernet MTU的有点以及为什么IEEE不同意让这周扩充规格标准化的讨论。
unsigned short type
设备所属的类型,include/linux/if_arp.h 包含可能类型的完整列表
unsigned short hard_header_len
以字节为单位的设备头的大小,例如,Ethernet报头是14字节。每个设备头的长度定义在该设备的头文件中。例如,对于Ethernet而言,ETH_HLAN就定义在include/linux/if_ether.h中。
unsigned char broadcast[MAX_ADDR_LEN]
链路层广播地址
unsigned char dev_addr[MAX_ADDR_LEN]
unsigned char addr_len
dev_addr是设备链路层地址,不要将其与L3或IP地址混淆,此地址的字节长度由addr_len指定,addr_len 的值依赖于设备的类型。Ethernet地址都是6个字节长
int promiscuity
接口类型和端口
有些设备有一个以上的连接器,允许用户根据需求选择其中之一使用。这个参数用于设置设备的端口类型。当设备驱动程序没有通过配置命令强制选择特定的端口类型时,就会简单选择默认的端口类型。有些情况下,一个设备驱动程序可以处理不同的接口类型,在这些情况下,该接口可以按特定次序尝试所有端口类型。下面显示的代码片段,是一个设备驱动程序如何根据已有的配置而设定其接口模式。
switch (dev->if_port)
case IF_PORT_10BASE2:
writeb(readb(addr) & 0xf8 | 1, addr);
break;
case IF_PORT_10BASET:
writeb((readb(addr)&0xf8), addr);
break;