// 开启网桥设备 // 调用路径dev_open->br_dev_open // 函数主要任务: // 1.开启传输队列 // 2.使能网桥 1.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);//使能网桥 return 0; } // 使能网桥 // 调用路径dev_open->br_dev_open->br_stp_enable_bridge // 函数主要任务: // 1.设置网桥为根网桥 // 2.在每个指定端口上发送配置bpdu // 3.使能网桥的每个端口 1.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); } // 发送配置bpdu // 函数主要任务: // 1.遍历所有端口 // 1.1如果端口为指定端口,并且端口已经使能,则发送配置BPDU 1.3 void br_config_bpdu_generation(struct net_bridge *br) { struct net_bridge_port *p; list_for_each_entry(p, &br->port_list, list) {//在每个指定端口发送配置BPDU if (p->state != BR_STATE_DISABLED &&//端口使能 br_is_designated_port(p))//为指定端口 br_transmit_config(p);//发送配置BPDU } } // 使能端口 // 函数主要任务: // 1.初始化端口 // 2.开启端口的状态选择 1.4 void br_stp_enable_port(struct net_bridge_port *p) { br_init_port(p);//初始化端口 br_port_state_selection(p->br);//开始执行端口状态的变化 } // 初始化端口 // 调用路径:br_stp_enable_port->br_init_port // 函数主要任务: // 1.计算端口id // 2.设置端口为指定角色 // 3.设置端口为阻塞状态 // 4.初始化端口的定时器 1.5 void br_init_port(struct net_bridge_port *p) { p->port_id = br_make_port_id(p->priority, p->port_no);//创建端口id br_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.disable网桥设备 // 2.关闭设备队列 //调用路径dev_close->br_dev_stop 2.1 static int br_dev_stop(struct net_device *dev) { br_stp_disable_bridge(dev->priv);//disable网桥 netif_stop_queue(dev);//修改dev->state,关闭传输传输 return 0; } // disable网桥 // 函数主要功能: // 1.关闭所有端口 // 2.设置标志没有拓扑变化 // 3.删除网桥使用的定时器 //调用路径dev_close->br_dev_stop->br_stp_disable_bridge 2.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); } // disable网桥端口: // 函数主要任务: // 1.设置为指定端口角色 // 2.删除端口使用的定时器 // 3.由于端口关闭而更新网桥配置 // 4.设置端口状态 // 3.由于端口的关闭,使非根网桥变为根网桥,更新网桥信息 //调用路径dev_close->br_dev_stop->br_stp_disable_bridge->br_stp_disable_port 2.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); } // 成为网桥: // 被调用情景: // 当网桥由非根网桥变化为根网桥时,调用。 // 函数主要任务: // 1.每个网桥在启动时,在birdge_max_age, bridge_hello_time, bridge_forward_delay字段保存当自己成为根网桥时使用的到期时间。 // 2.更新定时器使用的到期时间。 // 3.设置网桥发生了拓扑变化。 // 4.发送配置信息。 2.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); } } // 拓扑发生变化: // 函数主要任务: // 1.如果为根网桥 // 1.1 启动topology_change_timer定时器 // 1.2 设置topology_change标志 // 2.非根网桥,之前没有检测到拓扑变化 // 2.1 发送设有tc标志的配置bpdu // 2.2 启动tcn_timer定时器 // 3.设置topology_change_detected=1,表示拓扑变化被检测到。 2.5 void br_topology_change_detection(struct net_bridge *br) { int isroot = br_is_root_bridge(br); 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; }
时间: 2024-10-31 10:45:50