桥设备及端口的开启和关闭(四)

来源:互联网 发布:php过滤emoji的正则 编辑:程序博客网 时间:2024/05/21 20:21
关于设备的添加删除的基本动作,我们已经知道。这节,我们看看关于网桥设备以及桥设备上的端口的启动和关闭。我们说过,在初始化一个桥设备的时候有这样一个操作:dev->netdev_ops = &br_netdev_ops;br_netdev_ops这个参数,注册了很多函数,其中包括网桥设备的启动和关闭函数br_dev_open和br_dev_stop,这两个函数的工作主要是初始化桥设备的一些队列和桥设备上端口的一些启动和关闭动作。

启动和关闭网桥设备

br_dev_open相当与启动网桥的总设计师
static int br_dev_open(struct net_device *dev){    struct net_bridge *br = netdev_priv(dev);    /*重新更新网桥设备功能*/    netdev_update_features(dev);    /*函数启动进行设备传输*/    netif_start_queue(dev);    /*启动网桥设备*/    br_stp_enable_bridge(br);    /*初始化网桥本身的多播对列*/    br_multicast_open(br);    return 0;}
static int br_dev_stop(struct net_device *dev){    struct net_bridge *br = netdev_priv(dev);    /*关闭网桥设备*/    br_stp_disable_bridge(br);    /*关闭网桥设备的多播队列*/    br_multicast_stop(br);    /*关闭设备的传输,任何企图在设备上传输信息的尝试都会被拒绝*/    netif_stop_queue(dev);    return 0;}
启动网桥设备,当启动网桥设备时,先前绑定在该设备上的端口也会跟着启动
void br_stp_enable_bridge(struct net_bridge *br){    struct net_bridge_port *p;    /*锁定网桥*/    spin_lock_bh(&br->lock);    if (br->stp_enabled == BR_KERNEL_STP)        mod_timer(&br->hello_timer, jiffies + br->hello_time);    /* 当网桥启动时,设置次定时器,1/10秒到期一次 */    mod_timer(&br->gc_timer, jiffies + HZ/10);    /*TX配置bpdu*/    br_config_bpdu_generation(br);    list_for_each_entry(p, &br->port_list, list) {        if (netif_running(p->dev) && netif_oper_up(p->dev))            br_stp_enable_port(p);/*启动网桥设备的每个端口*/    }    /*给网桥解锁*/    spin_unlock_bh(&br->lock);}
关闭网桥设备void br_stp_disable_bridge(struct net_bridge *br){    struct net_bridge_port *p;    spin_lock_bh(&br->lock);    list_for_each_entry(p, &br->port_list, list) {        if (p->state != BR_STATE_DISABLED)            br_stp_disable_port(p);/*关闭网桥设备的每个端口*/    }    /*重新设置拓扑标识*/    br->topology_change = 0;    br->topology_change_detected = 0;    spin_unlock_bh(&br->lock);    /*删除在初始化桥设备时的定时器*/    del_timer_sync(&br->hello_timer);    del_timer_sync(&br->topology_change_timer);    del_timer_sync(&br->tcn_timer);    del_timer_sync(&br->gc_timer);}

启动和关闭网桥端口

要启动网桥端口,必须满足下列几个条件1.被管理的相关设备已用管理手段启动2.被绑定的相关设备有载波状态3.相关的网桥设备已用管理手段启动注意:网桥设备上没有载波状态,因为网桥是虚拟设备。当网桥是以用户空间命令建起来并且先前三个条件都满足时,该网桥端口就可以立即启用了但是,假设当端口建立时,由于上述三项条件至少有一项不满足无法启动端口时,下面的条件是每项条件最终满足时启用端口的场合:1.当被关闭的网桥设备重新启动时,其所有关闭的端口就会启用2.当被绑定的设备检测到载波状态时,桥程序会收到NETDE_CHANGE通知消息3.当被关掉的版定设备重启时,桥程序会收到NETDEV_UP的通知消息如若还不满足,网桥端口就会被关闭 
启动网桥上的端口void br_stp_enable_port(struct net_bridge_port *p){    /*初始化端口*/    br_init_port(p);    /*遍历所有端口,为端口指定合适的状态*/    br_port_state_selection(p->br);    /*捕捉一个端口变化信息的通知*/    br_ifinfo_notify(RTM_NEWLINK, p);}
关闭网桥上的端口void br_stp_disable_port(struct net_bridge_port *p){    struct net_bridge *br = p->br;    int wasroot;    /*判断是否是根网桥*/    wasroot = br_is_root_bridge(br);    /*分配制定角色*/    br_become_designated_port(p);    /*将关闭位置位*/    br_set_state(p, BR_STATE_DISABLED);    p->topology_change_ack = 0;    p->config_pending = 0;    br_ifinfo_notify(RTM_NEWLINK, p);    /*删除定时器*/    del_timer(&p->message_age_timer);    del_timer(&p->forward_delay_timer);    del_timer(&p->hold_timer);    /*更改转发表信息*/    br_fdb_delete_by_port(br, p, 0, 0);    br_multicast_disable_port(p);    /*更改桥的bpdu信息*/    br_configuration_update(br);    /*更新所有桥上端口的状态*/    br_port_state_selection(br);    /*处理非根网桥到根网桥的转移*/    if (br_is_root_bridge(br) && !wasroot)        br_become_root_bridge(br);}
 注意,当网桥端口关闭时,非根网桥可能会变成根网桥
原创粉丝点击