網絡子係統32_網橋設備的開啟與關閉
// 開啟網橋設備 // 調用路徑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; }
最後更新:2017-04-03 16:49:08