網絡子係統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