网络子系统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