赞
踩
某些网络管理任务会要求一个系统接收在一条共享缆线传输的所有帧,而不是仅限于地址直接指定给该系统的帧,一个设备如果可以接收所有封包,意味着其处于混杂模式。例如,应用程序检查其局域网段的性能或者安全缺陷时,就需要使用这种模式。桥接代码也会用到混杂模式。最后,不幸的是,对恶意的窥探者而言,这种模式显然有其价值所在。由于这个原因,除非数据被加密,否则局域网络上其他用户的数据都不安全。
net_device 结构包含一个名为promiscuity的计数器,表示一个设备处于混杂模式中,采用计数器而非简单标识的原因在于,多个客户程序可能都会要求混杂模式,因此,进入混杂模式时递增该计数器,而退出该模式时递减该计数器。除非计算器为零,否则该设备不会退出混杂模式。通常来讲,对此字段的操作时通过调用dev_set_promiscuity函数实现。
当promiscuity 为非零时,flags 的IFF_PROMISC标识也会设置,并且由配置此接口的函数进行检查。
下列取自drivers/net/3c59x.c 驱动程序的代码片段,说明了如何根据flags字段中的标识而设置不同的接受模式。
static void set_rx_mode(struct net_device *dev)
{
int ioaddr = dev->base_addr;
int new_mode;
if (dev->flags & IFF_PROMISC) {
if (corqscreq_debug > 3)
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
} else if (dev->mc_list ||dev->flags & IFF_ALLMULTI)
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast
else
new_mode = SetRxFilter | RxStation | RxBroadcast
outw(new_mode, ioaddr + EL3_CMD);
}
当IFF_PROMISC标识被置位时,就会对new_mode变量做初始化,从而接受地址指定该网卡的数据流,多播数据流,广播数据流以及其他数据流。El3_CMD 是对ioaddr 内存地址的偏移量,代表与设备交互时命令应该拷贝到何处。
数据统计
net_device 结构没有提供一个用来记录统计数据的收集字段,而是引入了一个由驱动程序设置的priv指针,指向一个存储有关接口信息的私有数据结构,私有数据由统计数据组成,如已收发的封包数目。
priv指向数据结构的格式取决于设备类型以及特定的模型,因此,不同的Ethernet卡使用不同的私有结构。然而,几乎所有结构都包括一个类型为net_device_stats的字段,该字段包含所有网络设备共有的统计数据,而且可以通过get_stats 方法获取,稍后说明。
无线设备的行为迥异于友先设备,致使net_device_stats 数据结构不适用于无线设备,因此,无线设备该用一个类型为iw_statistics的字段。可以通过调用get_wireless_stats 的方法获取,稍后说明。
priv 指向的数据结构有时名称会反映出其接口,而其他时候则只是简单成为net_local,不过net_local 中的字段依然是由每个设备驱动程序各自定义。
私有数据结构复杂度的多少,依赖于适配卡的功能,以及设备驱动程序编写者打算采用多精密的统计数据和复杂的设计以提高性能。例如,比较3c507 Ethernet卡所采用的通用net_local结构,以及3C59X ETHERNET 卡所采用的非常详尽的vortex_private结构,然而,这两种结构都包含一个类型为net_device_stats的字段。
在第八章将会看到,私有数据结构有时会添加到net_device结构资深,但有时也会分配成一个独立的区块。
设备状态
为了控制NIC之间的交互,每个设备驱动程序都必须维护一些信息,如表示接口需要哪种行为的时间戳和标识。在SMP系统中,内核也必须确保不同CPU对同一个设备并发访问的正确处理,net_device 结构以下几个字段就是专门用于这些类型的信息。
unsigned long state
由网络队列子系统所使用的一组标识,其索引值是enum netdev_state_t 中的常数,而为每位所定义的常数类似__LINK_STATE_XOFF 个别位的设置和清除都使用通用函数set_bit和clear_bit 而这两个函数的调用通常是通过一个包裹函数把用到的位的细节隐藏起来,例如,要停止一个设备队列时,子系统会调用netif_stop_queue, 如下列所示。
static inline void netif_stop_queue(struct net_device *dev)
{
set_bit(__LINK_STATE_XOFF, &dev->state);
}
第十一章简要的介绍流量控制子系统
enum {...} reg_state
设备的注册状态,参见第八章
unsigned long trans_start
最近的一个帧传输启动的时间,设备驱动程序会在传输前设置此值。如果在一段给定时间后传输没有完成,这个字段用于检测配置卡的问题。传输时间过长就意味着有地方出错,在这种情况下,驱动程序通常复位配置卡。
unsigned long last_rx
最后的一个封包到达的时间,此刻,不同任何特殊的目的,但是有需要的时候可以利用。
struct net_device *master
有些协议允许一组设备集群起来作为单一设备,这些协议包括EQL Bonding 以及流量控制的TEQL队列规则,群租中的一个设备背选定为所谓的主设备,扮演特殊角色,这个字段是一个指针,指向群组中主设备的net_device数据结构,如果此接口并非这类群组中的成员之一,则此指针就只是NULL.
spinlock_t xmit_lock
int xmit_lock_owner
xmit_lock 锁使驱动程序函数hard_start_xmit的访问串行化,这意味着,每个CPU一次只能对任何给定的一个设备做一次传输,xmit_lock_owner 是持有该锁的CPU的ID。对单处理器系统而言,其值总是0,而在SMP系统中当该锁没被取走时,其值就为-1。当设备驱动程序支持时,也有可能做无锁的传输。参见第十一章有关有锁的情况。
void *atalk_ptr
void *ip_ptr;
void *dn_ptr;
void *ip6_ptr
void *ec_ptr;
void *ax25_ptr
这6个字段都是指针,指向特定协议专用的数据结构,而每个数据结构都包含一些该协议私有的参数,例如,ip_ptr 指向一个类型为in_device 的数据结构,其中包含各种不同的与IPv4 相关的参数,其中有该接口上所配置的IP地址列表,本书其他章节会描述本书中涉及协议所使用的数据结构字段,多数时候,只有其中的一个字段在使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。