閱讀215 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go poj 3281 Dinicing
  下一篇:go 網絡子係統6_設備開啟與關閉