[百度分享]Bonding 模块代码及主要工作模式分析(3)
* bond_release
原型
static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
该函数在试图解除一个物理网卡的绑定状态时被调用,其中bond_dev表示虚拟的网卡,slave_dev表示真实的物理网卡。该函数主要做如下操作:
1. 取出bond_dev的私有数据,用bond指向它(struct bonding *)。
2. 寻找对应的slave结构。
3. 一系列的合法性检查,包括:
1. slave_dev->flags是否设置了IFF_SLAVE。
2. slave结构是否存在。
3. slave_dev原来的MAC地址是否和bond_dev相同,如果相同给出警告(防止MAC冲突)
4. 如果虚拟网卡工作在BOND_MODE_8023AD模式,调用bond_3ad_unbind_slave
5. 调用bond_detach_slave把slave从bond的链表中摘除(通过维护bond-> first_slave和slave结构的next,prev指针)。
6. 如果slave_dev是虚拟网卡以前的主物理网卡,则设置bond->primary_slave为NULL。
7. 如果slave_dev是虚拟网卡以前的活动网卡,则设置bond->active_slave为NULL(通过调用bond_change_active_slave函数)。
8. 如果虚拟网卡工作在模式BOND_MODE_TLB或者BOND_MODE_ALB则调用bond_alb_deinit_slave。
9. 如果slave_dev是虚拟网卡以前的活动网卡,则调用bond_select_active_slave寻找一个新的活动网卡。
10. 如果虚拟网卡再也没有管辖的物理网卡,清除虚拟网卡的MAC地址(如果新调用ifenslave绑定物理网卡,则重新设置这个MAC地址)。
11. 维护VLAN和Multicast相关的数据结构。
12. 调用netdev_set_master解除master和slave的绑定关系并且调用dev_close关闭slave_dev。
13. 恢复slave_dev的MAC地址(根据slave->perm_hwaddr)和flags(根据slave->original_flags)。
14. 调用kfree释放slave结构。
3. 网卡驱动通用接口(interface service routines)
既然bonding模块本质上是一个虚拟网卡的驱动模块,所以必须提供一组所有网卡驱动模块都遵守的通用接口函数。
1. open/close
* bond_open(net_device->open接口)
原型:
static int bond_open(struct net_device *bond_dev)
该函数在对应的虚拟网卡被打开时调用(即使用ifup/ifconfig工具启动网卡的时候),主要做如下操作(只分析三种主要模式):
1. 设置bond->kill_timers为0。
2. 如果使用MII链路状态监控:
1. 初始化mii_timer。
2. 设置超时时间mii_timer->expires为当前jiffies+1(立即调用bond_mii_monitor函数)
3. 设置bond_mii_monitor为定时器的超时处理函数。
3. 如果使用ARP链路状态监控:
1. 初始化arp_timer。
2. 设置超时时间arp_timer->expires为当前jiffies+1(立即调用定时器的超时处理函数)
&nbs