网络子系统32_网桥设备的开启与关闭
//网桥设备的开启//1.开启传输队列//2.初始化网桥使用的hello定时器//3.在每个指定端口,发送配置bpdu//4.使能每个端口//4.1 初始化每个端口为指定状态//4.2 初始化端口使用的定时器//4.3 开启端口状态选择//调用路径dev_open->br_dev_open1.1 static int br_dev_open(struct net_device *dev){//开启的传输功能,清除dev->state的__LINK_STATE_XOFF标志netif_start_queue(dev);br_stp_enable_bridge(dev->priv);//开启网桥的stpreturn 0;}//使能网桥,设置网桥为根网桥,在所有指定端口,发送本网桥的配置信息//调用路径dev_open->br_dev_open->br_stp_enable_bridge1.2 void br_stp_enable_bridge(struct net_bridge *br){struct net_bridge_port *p;spin_lock_bh(&br->lock);mod_timer(&br->hello_timer, jiffies + br->hello_time);//更新发送helloBPDU定时器br_config_bpdu_generation(br);//在每个使能的指定端口,发送配置BPDU,在端口被添加到网桥时,会自动指派其为指定端口,端口关闭时,也会被重置为指定角色list_for_each_entry(p, &br->port_list, list) {//遍历此网桥的所有端口if ((p->dev->flags & IFF_UP) && netif_carrier_ok(p->dev))//设备开启,检测dev->states是否清除了__LINK_STATE_NOCARRIER标志br_stp_enable_port(p);//开启端口的stp}spin_unlock_bh(&br->lock);}//向所有指定端口,发送配置信息//调用路径dev_open->br_dev_open->br_stp_enable_bridge->br_config_bpdu_generation1.3 void br_config_bpdu_generation(struct net_bridge *br){struct net_bridge_port *p;list_for_each_entry(p, &br->port_list, list) {//在每个指定端口发送配置BPDUif (p->state != BR_STATE_DISABLED &&//端口使能 br_is_designated_port(p))//为指定端口br_transmit_config(p);//发送配置BPDU}}//调用路径dev_open->br_dev_open->br_stp_enable_bridge->br_stp_enable_port//使能端口的stp,设置端口为指定端口,开启端口状态选择1.4 void br_stp_enable_port(struct net_bridge_port *p){br_init_port(p);//初始化端口br_port_state_selection(p->br);//开始执行端口状态的变化}//dev_open->br_dev_open->br_stp_enable_bridge->br_stp_enable_port->br_init_port1.5 void br_init_port(struct net_bridge_port *p){p->port_id = br_make_port_id(p->priority, p->port_no);//创建端口idbr_become_designated_port(p);//使能端口时,端口均被指派为指定端口的角色p->state = BR_STATE_BLOCKING;//起始状态为阻塞态p->topology_change_ack = 0;//p->config_pending = 0;br_stp_port_timer_init(p);//初始化端口使用的三个定时器message age, forward delay,hold}//关闭网桥设备//1.逐个关闭端口//1.1 设置端口disabled状态,设置为指定端口角色,删除端口使用的定时器//1.2 选择网桥的根端口和指定端口//1.3 如果网桥由非根网桥变为根网桥,则发送tc标志的bpdu//2.删除网桥使用的定时器//3.关闭设备队列//调用路径dev_close->br_dev_stop2.1 static int br_dev_stop(struct net_device *dev){br_stp_disable_bridge(dev->priv);//关闭网桥netif_stop_queue(dev);//修改dev->state,暂停设备传输return 0;}//调用路径dev_close->br_dev_stop->br_stp_disable_bridge2.2 void br_stp_disable_bridge(struct net_bridge *br){struct net_bridge_port *p;spin_lock(&br->lock);//获取桥的锁list_for_each_entry(p, &br->port_list, list) {if (p->state != BR_STATE_DISABLED)br_stp_disable_port(p);//关闭每个端口的stp,设置其为指定端口}br->topology_change = 0;br->topology_change_detected = 0;spin_unlock(&br->lock);//同步删除网桥的定时器del_timer_sync(&br->hello_timer);del_timer_sync(&br->topology_change_timer);del_timer_sync(&br->tcn_timer);}//删除端口定时器,设置端口成为指定端口,重新选择根端口和指定端口,如果网桥由非根网桥变为根网桥,更新网桥信息。//调用路径dev_close->br_dev_stop->br_stp_disable_bridge->br_stp_disable_port2.3 void br_stp_disable_port(struct net_bridge_port *p){struct net_bridge *br;int wasroot;br = p->br;printk(KERN_INFO "%s: port %i(%s) entering %s state\n", br->dev->name, p->port_no, p->dev->name, "disabled");wasroot = br_is_root_bridge(br);//根网桥br_become_designated_port(p);//关闭端口stp时,也会重置端口为指定端口p->state = BR_STATE_DISABLED;//设置端口为关闭状态p->topology_change_ack = 0;p->config_pending = 0;//删除定时器del_timer(&p->message_age_timer);del_timer(&p->forward_delay_timer);del_timer(&p->hold_timer);//更新根端口和指定端口br_configuration_update(br);//端口状态选择br_port_state_selection(br);//非根网桥转变为根网桥,if (br_is_root_bridge(br) && !wasroot)br_become_root_bridge(br);}//调用路径dev_close->br_dev_stop->br_stp_disable_bridge->br_stp_disable_port->br_become_root_bridge//更新根网桥使用的定时器,扩散设置tc标志的BPDU2.4 void br_become_root_bridge(struct net_bridge *br){ br->max_age = br->bridge_max_age; br->hello_time = br->bridge_hello_time; br->forward_delay = br->bridge_forward_delay; br_topology_change_detection(br);//拓扑发生改变 del_timer(&br->tcn_timer); if (br->dev->flags & IFF_UP) {//根网桥开启状态 br_config_bpdu_generation(br);//发送配置信息 mod_timer(&br->hello_timer, jiffies + br->hello_time); }}//调用路径dev_close->br_dev_stop->br_stp_disable_bridge->br_stp_disable_port->br_become_root_bridge->br_topology_change_detection//拓扑发生变化被检测到//1.根网桥,则启动topology_change_timer//2.非根网桥,则启动tcn_timer2.5 void br_topology_change_detection(struct net_bridge *br){ int isroot = br_is_root_bridge(br); pr_info("%s: topology change detected, %s\n", br->dev->name, isroot ? "propagating" : "sending tcn bpdu"); if (isroot) { br->topology_change = 1; mod_timer(&br->topology_change_timer, jiffies + br->bridge_forward_delay + br->bridge_max_age); } else if (!br->topology_change_detected) { br_transmit_tcn(br); mod_timer(&br->tcn_timer, jiffies + br->bridge_hello_time); } br->topology_change_detected = 1;}