Linux内核实践 - 如何添加网络协议[二]:实现
设备的相关定义 一种设备就是net_device类型,而每种设备都有自 己的私有变量,它存储在net_device末尾,定义如下,其中real_dev指向下层设备,这是最基本属性,其余可以视需要自己设定 ,brcm_rx_stats则是该设备接收流量统计: struct brcm_dev_info{ struct net_device *real_dev; u16 brcm_port; unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; struct brcm_rx_stats __percpu *brcm_rx_stats; }; struct brcm_rx_stats { unsigned long rx_packets; unsigned long rx_bytes; unsigned long multicast; unsigned long rx_errors; }; 设备间的关系问题 如果brcm仅仅是只有一个设备,则无需数据结构来存储这种关系, 一个全局全变的brcm_dev就可以了。这里的设计考虑的是复杂的情况,可以存在多个下层设备,多个brcm设备,之间没有固定的 关系。所以需要一种数据结构来存储这种关系- brcm_group_hash。下面是一个简单的图示: 各个数据结构定义如下: static struct hlist_head brcm_group_hash [BRCM_GRP_HASH_SIZE]; struct brcm_group { struct hlist_node hlist; struct net_device *real_dev; int nr_ports; int killall; struct net_device *brcm_devices_array[BRCM_GROUP_ARRAY_LEN]; struct rcu_head rcu; }; brcm_group_hash作为全局变量存在,以hash表形式组织,brcm_group被插入到brcm_group_hash中,brcm_group存 储了它与下层设备的关系(eth与brcm),real_dev指向e下层设备,而brcm设备则存储在brcm_devices_array数组中。 下面完成由下层设备转换成brcm设备的函数,brcm_port是报头中的值,可以自己设定它的含义,这里设定它表 示报文来自于哪个端口。 struct net_device *find_brcm_dev(struct net_device *real_dev, u16 brcm_port) { struct brcm_group *grp = brcm_find_group(real_dev); if (grp) brcm_dev = grp->brcm_devices_array[brcm_port]; return NULL; } 因为在接收报文时,报文到达brcm层开始处理时,skb->dev指向的仍是下层设备,这时通过skb->dev查到 brcm_group->real_dev相匹配的hash项,然后通过报文brcm报头的信息,确定brcm_group->brcm_devices_array中哪个 brcm设备作为skb的新设备; 而在发送报文时,报文到达brcm层开始处理时,skb->dev指向的是brcm 设备,为了继续向下传递,需要变更为它的下层设备,在设备数据net_device的私有数据部分,一般会存储一个指针,指向它的 下层设备,因此skb->dev只要变更为brcm_dev_info(dev)->real_dev。 (编辑:淮北站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |