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


網絡子係統33_網橋設備的配置更新

//	更新網橋配置信息
//	函數主要任務:
//		1.重新選擇根端口
//		2.重新選擇根網橋
1.1 void br_configuration_update(struct net_bridge *br)
{
	br_root_selection(br);//選擇根端口,根網橋
	br_designated_port_selection(br);//選擇指定端口
}

//	選擇根端口
//	調用路徑:br_configuration_update->br_root_selection
//	函數主要任務:
//		1.遍曆所有端口,選擇具備成為根端口的端口
//		2.沒有選擇出根端口,則更新網橋成為根網橋
//		3.否則更新可到達的根網橋,根路徑開銷

//	注:
//		1.網橋的根路徑開銷 = 根端口的指定開銷+端口的根路徑開銷
1.2 static void br_root_selection(struct net_bridge *br)
{
	struct net_bridge_port *p;
	u16 root_port = 0;

	list_for_each_entry(p, &br->port_list, list) {//遍曆所有端口
		if (br_should_become_root_port(p, root_port))//判斷端口是否應該成為根端口
			root_port = p->port_no;//根端口id
	}

	br->root_port = root_port;//網橋的根端口

	if (!root_port) {//沒有選出合適的根端口
		br->designated_root = br->bridge_id;//設置自己為根網橋,開始新一輪的網絡拓撲檢測
		br->root_path_cost = 0;
	} else {//成功選出根端口
		p = br_get_port(br, root_port);
		br->designated_root = p->designated_root;//此端口到達的根
		br->root_path_cost = p->designated_cost + p->path_cost;//計算路徑開銷
	}
}


//	端口成為根端口的條件

//	成為根端口的條件:
//		1.端口優先級高於網橋優先級
//		2.該端口<到達的根網橋優先級, 到達根網橋的開銷, 直連的網橋id的優先級>
//		與根端口<到達的根網橋優先級, 到達根網橋的開銷, 直連的網橋id的優先級>
//		優先級高的,可以成為根端口
1.3 static int br_should_become_root_port(const struct net_bridge_port *p, 
				      u16 root_port)
{
	struct net_bridge *br;
	struct net_bridge_port *rp;
	int t;

	br = p->br;
	if (p->state == BR_STATE_DISABLED ||
	    br_is_designated_port(p))//如果端口被關閉,或者為指定端口
		return 0;

	if (memcmp(&br->bridge_id, &p->designated_root, 8) <= 0)//網橋的id優先級高於等於端口能到達的根網橋的優先級
		return 0;

	if (!root_port)//之前沒有選擇到根端口,並且此端口到達的根網橋的優先級高於此網橋
		return 1;

	rp = br_get_port(br, root_port);//之前選擇到的根端口

	t = memcmp(&p->designated_root, &rp->designated_root, 8);//比較先前選擇的根端口能到達的根網橋id與當前的端口能到達的根網橋id
	if (t < 0)//選擇優先級高的
		return 1;
	else if (t > 0)
		return 0;

	if (p->designated_cost + p->path_cost <
	    rp->designated_cost + rp->path_cost)//選擇根路徑開銷小的端口
		return 1;
	else if (p->designated_cost + p->path_cost >
		 rp->designated_cost + rp->path_cost)
		return 0;

	t = memcmp(&p->designated_bridge, &rp->designated_bridge, 8);//當前端口直連的網橋id的優先級與之前端口直連的網橋的id
	if (t < 0)
		return 1;
	else if (t > 0)
		return 0;

	if (p->designated_port < rp->designated_port)//直連端口的id
		return 1;
	else if (p->designated_port > rp->designated_port)
		return 0;

	if (p->port_id < rp->port_id)
		return 1;

	return 0;
}

//	選擇指定端口
//	調用路徑:br_configuration_update->br_designated_port_selection
//	函數主要任務:
//		1.遍曆所有沒有被關閉的端口
//		2.端口具備成為指定端口的條件
//		3.更新端口信息,成為指定端口
1.4 static void br_designated_port_selection(struct net_bridge *br)
{
	struct net_bridge_port *p;

	list_for_each_entry(p, &br->port_list, list) {
		if (p->state != BR_STATE_DISABLED &&
		    br_should_become_designated_port(p))//如果當前端口應該成為指定端口
			br_become_designated_port(p);//則設置成為指定端口

	}
}

//	端口成為指定端口的條件
//	成為指定端口的條件:
//		1.端口能到達的根網橋,與網橋的根網橋不同,則滿足
//		2.端口到達根網橋的路徑開銷,大於網橋的根路徑開銷,則滿足
//		3.端口直連網橋id的優先級,小於本網橋id的優先級,則滿足
1.5 static int br_should_become_designated_port(const struct net_bridge_port *p)
{
	struct net_bridge *br;
	int t;

	br = p->br;
	if (br_is_designated_port(p))//如果端口此時為指定端口,則保持此狀態
		return 1;

	if (memcmp(&p->designated_root, &br->designated_root, 8))//1.如果此端口能到達的根網橋非網橋的根網橋
		return 1;

	if (br->root_path_cost < p->designated_cost)//2.如果網橋的根路徑開銷小於當前端口到達根網橋的開銷
		return 1;
	else if (br->root_path_cost > p->designated_cost)
		return 0;

	t = memcmp(&br->bridge_id, &p->designated_bridge, 8);//當前網橋id與端口直連的網橋id
	if (t < 0)//如果當前網橋的優先級高於端口直連的網橋的id
		return 1;
	else if (t > 0)
		return 0;

	if (p->port_id < p->designated_port)//當前端口的id小於直連的端口的id
		return 1;

	return 0;
}

最後更新:2017-04-03 14:53:55

  上一篇:go 壓力測試工具ab.exe簡介
  下一篇:go 關於對Floyd算法的思索