当前位置:  技术问答>linux和unix

[百度分享]Bonding 模块代码及主要工作模式分析(2)

    来源: 互联网  发布时间:2016-08-28

    本文导语:     5. 代码分析          1. 关键数据结构                1. struct bond_params 文件:driver/net/bonding/Bonding.h      该结构是全局结构(每系统一个),对应于加载bonding模块时传入的各个参数 主要成员...

   5. 代码分析

         1. 关键数据结构

               1. struct bond_params

文件:driver/net/bonding/Bonding.h

     该结构是全局结构(每系统一个),对应于加载bonding模块时传入的各个参数

主要成员:
名称  类型  含义
mode  int  Bonding模块工作模式

BOND_MODE_ROUNDROBIN     balance-rr模式

BOND_MODE_ACTIVEBACKUP   active-backup模式

BOND_MODE_XOR            balance-xor模式

BOND_MODE_BROADCAST      broadcast模式

BOND_MODE_8023AD         IEEE 802.3ad动态链路聚合模式

BOND_MODE_TLB            自适应传输负载均衡模式

BOND_MODE_ALB            自适应负载均衡模式
miimon  int  使用MII链路状态监控时的时间间隔(ms)
arp_interval  int  使用arp链路状态监控时的时间间隔(ms)
use_carrier  int  使用MII链路状态监控时是否使用更新的carrier调用
updelay  int  使用MII链路状态监控时从BACK状态切换到UP状态的时延(ms)
downdelay  int  使用MII链路状态监控时从FAIL状态切换到DOWN状态的时延(ms)
primary  char[]  用来在active-backup、balance-tlb和balance-alb模式中指定主网卡
arp_targets  u32[]  在ARP链路状态监控中将向这些IP地址发送ARP请求。

               2. struct slave

文件:driver/net/bonding/Bonding.h

     每一个被管辖的物理网卡对应一个该数据结构的实例

主要成员:
名称  类型  含义
dev  struct net_device*  指向被绑定的物理网卡
next,prev  struct slave *  所有的slave数据结构通过这两个指针双向链接到一起形成*循环*链表
delay  s16  用于保存MII链路状态监控和ARP链路状态监控的时延值。
jiffies  u32  用于active-backup模式下的ARP状态监控
link  s8  表示对应网卡的链路状态,取下列四个值之一:

BOND_LINK_UP                上线状态

BOND_LINK_DOWN              故障状态

                              BOND_LINK_FAIL              网卡出现故障,状态BOND_LINK_DOWN切换中

                              BOND_LINK_BACK              网卡恢复,状态BOND_LINK_UP切换中

state  s8  表示对应网卡活动状态,取下列两个值之一:

BOND_STATE_ACTIVE            活动状态

BOND_STATE_BACKUP            后备状态
original_flags  u32  保存被绑定物理网卡原来的flags
perm_hwaddr  u8[]  保存被绑定物理网卡原来的MAC地址
ad_info  struct

ad_slave_info
记录IEEE 802.3ad动态链路聚合模式下的“每网卡”相关状态信息
tlb_info  struct tlb_slave_info  记录自适应传输负载均衡模式下的“每网卡”相关状态信息
link_failure_count  u32  网卡从BOND_LINK_FAIL切换到BOND_LINK_DOWN的次数
speed  u16  记录网卡的传输速度(10M/100M/1000G)
duplex  u8  网卡工作模式(全双工?)

               3. struct bonding

文件:driver/net/bonding/Bonding.h

     每一个虚拟网卡对应一个该数据结构的实例。

主要成员:
名称  类型  含义
dev  struct net_device*  指向虚拟网卡(例如bond0、bond1等等)
first_slave  struct   slave *  指向被绑定的第一个物理网卡对应的slave结构。
curr_active_slave  struct   slave *  指向当前活动的网卡对应的slave结构,在不同的工作模式下有不同的含义。
current_arp_slave  struct   slave *  用于ARP状态监控(只用于bond_activebackup_arp_mon)
primary_slave  struct   slave *  如果使用BOND_MODE_ACTIVEBACKUP、BOND_MODE_TLB或者BOND_MODE_ALB模式,则指向主物理网卡对应的slave结构(primary_slave)
slave_cnt  s32  虚拟网卡所管辖的物理网络接口的个数
lock  rwlock_t  每一个虚拟网卡管辖一系列物理网卡,每一个物理网卡对应一个slave结构,所有的slave被放在一个链表中,这个读写锁用来保护该链表。
curr_slave_lock  rwlock_t  用来保护curr_active_slave的读写锁。
mii_timer  struct   timer_list  用于MII链路状态监控的定时器
arp_timer  struct   timer_list  用于ARP链路状态监控的定时器
kill_timers  s8  如果该标志置位,所有的计时器超时后就不再重新设置,从而可以被安全删除
bond_list  struct   list_head  通过该结构,所有的bonding数据结构被连接为双向链表,链表头是全局变量bond_dev_list。

         2. 关键函数

    本节描述了bonding模块关键函数的操作流程,这些函数是基本的原子模块,其他没有被列举的函数仅仅是对这些函数的简单包装。

               1. 模块初始化/释放

                     1. 初始化

    * bonding_init

      原型:

      static int __init bonding_init(void)

   bonding_init作为bonging模块的初始化函数,在模块被加载时被调用。它主要做如下工作:

   1. 调用函数bond_check_params解析传入模块的参数并检查其合法性,结果放入数据结构params中。其中params是一个类型为bond_params的全局变量。
   2. 如果内核支持proc文件系统,调用bond_create_proc_dir在/proc/net下创建目录/proc/net/bonding。
   3. 如果传入参数指定了bond设备的个数(通过参数max_bonds),则通过下列步骤创建max_bonds个bond设备(从bond0到bondN)
         1. 调用alloc_netdev和dev_alloc_name创建网络设备,指定每一个设备的私有数据是一个bonding结构(dev->priv)。
         2. 为每一个新创建的虚拟网络设备调用bond_init函数。
         3. 调用register_netdevice注册这个新创建的网络设备。
   4. 调用register_netdevice_notifier,注册函数bond_netdev_notifier为网络事件处理函数。

    * bond_init

      原型:

      static int __init bond_init(struct net_device *bond_dev, struct bond_params *params)

      该函数对每一个新创建的虚拟网络设备调用一次。它主要做下列工作。

   1. 取出虚拟网络设备bond_dev的私有数据块,用bond指向它(struct bonding *bond)。
   2. 初始化两个读写锁bond->lock和bond->curr_slave_lock。
   3. 把bond->first_slave、bond->curr_active_slave、bond->current_arp_slave、bond->primary_slave全部置为NULL。bond->dev指向属主网络设备bond_dev。
   4. 设置bond_dev的一系列通用接口函数,例如open、close、get_stats、do_ioctl、set_multicast_list、change_mtu和set_mac_address。
   5. 根据不同的工作模式,设置bond_dev的通用接口函数hard_start_xmit 指向不同的目的函数。例如如果工作模式是BOND_MODE_ROUNDROBIN,则 hard_start_xmit指向函数bond_xmit_roundrobin。
   6. 设置bond_dev->tx_queue_len为0,表示发送队列大小没有限制。
   7. 设置bond_dev->flags为IFF_MASTER|IFF_MULTICAST表示该设备支持Muticase并且是一个流量均衡组中的master(被它管辖的其他物理网卡将被设置IFF_SLAVE标志)。
   8. 其他和VLAN相关的标志设置和初始化。
   9. 如果内核支持proc文件系统,调用bond_create_proc_entry在目录/proc/net/bonding下创建对应的proc文件。
  10. 调用list_add_tail把该bonding数据结构添加到bond_dev_list中。

                     2. 释放

    * bonding_exit

      原型:

      static void __exit bonding_exit(void)

      该函数在模块被卸载的时候被调用,它主要做如下工作:

         1. 调用unregister_netdevice_notifier注销网络事件处理函数。
         2. 调用bond_free_all注销所有形如bondN的虚拟网络接口。bond_free_all遍历bond_dev_list链表,并且对其中的每一个类型为 struct bonding*的数据结构bond做如下操作:
         1. 调用unregister_netdevice注销bond->dev
         2. 调用bond_deinit(bond->dev)
         3. 调用bond_destroy_proc_dir删除/proc/net/bonding目录

    * bond_deinit

      原型:

   static inline void bond_deinit(struct net_device *bond_dev)

   该函数对每一个虚拟网卡的实例调用一次,它主要做如下操作:

         1. 调用list_del把虚拟网卡对应的bonding数据结构从bond_dev_list链表中摘除。
         2. 调用bond_remove_proc_entry删除/proc/net/bonding目录中的对应文件。

               2. 物理网卡的绑定/解除绑定

   在下面的讨论中,假定ifenslave使用新的ABI接口,即:

    * 在绑定物理网卡时,如果虚拟的网卡还没有MAC地址,则ifenslave通过IOCTL把该虚拟网卡的MAC地址设置为该物理网卡的MAC地址(保证bond_enslave被调用时虚拟网卡已经有了MAC地址)。
    * 如果被绑定网卡处于UP状态,则ifenslave首先把它设置为DOWN状态(保证bond_enslave被调用时被绑定物理网卡处于DOWN状态)。

   如果使用旧版本的ABI接口,则虚拟的网卡的MAC地址由bonding模块在bond_enslave函数中自行设置,并且被绑定网卡在bond_enslave被调用时可能处于UP状态,需要由bond_enslave函数自行处理。

                     1. 绑定

    * bond_enslave

      原型:

      static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)

   该函数在试图把一个物理网卡绑定到一个虚拟的网卡时被调用,其中bond_dev表示虚拟的网卡,slave_dev表示真实的物理网卡。该函数主要做如下操作:

         1. 取出bond_dev的私有数据,用bond指向它(struct bonding *)。
         2. 一系列的合法性检查,包括:

         1. bond_dev的flags是否已经设置了IFF_UP(虚拟的网卡必须已经处于UP状态)
         2. slave_dev的flags是否没有设置IFF_SLAVE(防止同一个物理网卡被绑定两次)
         3. bond_dev的flags如果设置了NETIF_F_VLAN_CHALLENGED,则bond->vlan_list不能为空。
         4. slave_dev->flags是否没有设置IFF_UP(物理网卡应该处于DOWN状态)
         5. slave_dev->set_mac_address不能为NULL(物理网卡应该支持设置MAC地址)

         3. 调用kmalloc分配一个新的slave结构。

         4. 把slave_dev->flags保存在slave->original_flags中。
         5. 把slave_dev原有的MAC地址保存在slave-> perm_hwaddr中。
         6. 设置slave_dev新的MAC地址为虚拟网卡的MAC地址。
         7. 调用netdev_set_master设置slave_dev,该函数主要作如下操作:

         1. 设置slave_dev->flags的IFF_SLAVE标志。
         2. 设置slave_dev->master指向虚拟网卡bond_dev。

         8. 设置slave->dev指向slave_dev。

         9. 如果bond_dev工作在模式BOND_MODE_TLB或者BOND_MODE_ALB,对slave调用bond_alb_init_slave函数。
        10. 维护和Multicast以及VLAN相关的一系列数据结构。
        11. 调用bond_attach_slave把slave加入bond的链表(通过维护bond-> first_slave和slave结构的next,prev指针)
        12. 把slave的delay和link_failure_count都清零。
        13. 监测slave_dev的链路状态:

         1. 如果使用MII链路,并且bond_check_dev_link返回BMSR_LSTATUS(表示链路正常),或者不使用MII链路监控,则根据updelay是否为0把slave->link设置为BOND_LINK_BACK或者BOND_LINK_UP。
         2. 如果使用MII链路,并且bond_check_dev_link返回非BMSR_LSTATUS值,则设置slave->link为BOND_LINK_DOWN。

        14. 调用bond_update_speed_duplex更新slave_dev的链路速率,如果失败则设置slave_dev的链路速率为100M全双工。

        15. 如果虚拟网卡工作在BOND_MODE_ACTIVEBACKUP、BOND_MODE_TLB或者BOND_MODE_ALB模式下,并且slave_dev是用户指定的主网卡,则设置bond->primary_slave为slave_dev。
        16. 设置bond->curr_active_slave和slave的活动状态,维护VLAN和Multicast相关数据结构:

         1. 如果虚拟网卡工作在BOND_MODE_ACTIVEBACKUP:如果bond->curr_active_slave没有被设置或者bond->curr_active_slave不响应ARP(设置了IFF_NOARP标志),并且slave_dev不处于BOND_LINK_DOWN状态,则设置slave_dev为活动网卡(设置BOND_STATE_ACTIVE标志,清除IFF_NOARP标志),否则设置slave_dev为后备网卡(设置BOND_STATE_BACKUP标志,设置IFF_NOARP标志)。
         2. 如果虚拟网卡工作在BOND_MODE_ROUNDROBIN或者 BOND_MODE_BROADCAST:直接设置slave_dev的活动状态为BOND_STATE_ACTIVE(在BOND_MODE_ROUNDROBIN和BOND_MODE_BROADCAST 模式下,IFF_NOARP标志始终被清除),如果没有设置bond->curr_active_slave,则设置bond->curr_active_slave指向slave。
         3. 其他工作模式:(还没有加以分析)

                     2. 解除绑定

|
很好,继续收藏。

|
好帖就顶。

    
 
 

您可能感兴趣的文章:

  • 【百度分享】Socket通讯模块压力及大数据对比工具开发之aperlib(二)
  • 【百度分享】Socket通讯模块压力及大数据对比工具开发之aperlib(八)
  • python发布模块的步骤分享
  • 【百度分享】Socket通讯模块压力及大数据对比工具开发之aperlib(三)
  • 【百度分享】Socket通讯模块压力及大数据对比工具开发之aperlib(七)
  • 【百度分享】Socket通讯模块压力及大数据对比工具开发之aperlib(一)
  • 【百度分享】基于内核模块的测试代码编写(一)
  • ubuntu12.04使用c编写php扩展模块教程分享
  • 【百度分享】基于内核模块的测试代码编写(三)
  • [百度分享]Bonding模块主要工作模式相关代码分析(一)
  • 用smtplib和email封装python发送邮件模块类分享
  • 【百度分享】基于内核模块的测试代码编写(二)
  • [百度分享]Bonding模块工作流程综述
  • [百度分享]Bonding 模块代码及主要工作模式分析(4)
  • [百度分享]Bonding 模块代码及主要工作模式分析(1)
  • 『分享』从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响!!! (转载)
  • [百度分享]Bonding 模块代码及主要工作模式分析(3)
  • [百度分享]Bonding模块主要工作模式相关代码分析(二)
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java单例模式4种使用方式分享
  • PHP中数据库单例模式的实现代码分享
  • 简单的观察者模式示例分享
  • java设计模式之实现对象池模式示例分享
  • 线程安全的单例模式的几种实现方法分享
  • [百度分享]Bonding 模块代码及主要工作模式分析(4) iis7站长之家
  • 浅析MVP模式中V-P交互问题及案例分享
  • ​docker之轻量虚拟化技术——docker实战分享
  • php利用腾讯ip分享计划获取地理位置示例分享
  • 点对点文件分享客户端 PeerProject
  • 网络文件分享 Giver
  • IM及文件分享软件 iptux
  • P2P分享软件 Alliance P2P
  • 文件分享软件 eMule Plus
  • P2P 文件分享软件 ShakesPeer
  • 分享页面内容插件 ContentShare
  • 社交分享按钮生成JS库 Socialite.js
  • P2P分享软件 Phex
  • 前端代码编辑和分享平台 RunJS
  • jQuery 分享按钮插件 Share Button
  • 昨天考过SCJP快乐大家分享
  • P2P文件分享 GNUnet
  • 响应式社交分享按钮 RRSSB
  • 谁有免费的英文Office2003(日文也成)分享一下吧!
  • 谁有qmail的日常维护,日志分析的资料分享下?
  • 代码分享
  • 谁有xml和libxml2的说明文档,分享一下吧
  • Java代码分享工具 Java Gems


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3