网络子系统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;
}
时间: 2024-09-14 19:43:06

网络子系统33_网桥设备的配置更新的相关文章

网络子系统34_网桥设备的传输与接收

// 网桥设备驱动程序的hard_start_xmit函数 // 函数主要任务: // 1.广播或多播地址,在所有端口上扩散 // 2.存在转发项,在指定端口上发送 // 3.没有找到转发项,在所有端口上扩散 1.1 int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); const unsigned char *dest = skb->dat

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

网络子系统19_积压设备

// 1.积压设备的目的: // napi设备,非napi设备同一处理接口,linux为所有不使用napi的驱动程序,提供了一个虚拟设备,叫做积压设备. // 2.与积压设备有关的数据结构: // 2.1 每个cpu都有一个积压设备,保存在softnet_data->backlog_dev // 2.2 每个cpu都有一个积压设备的输入队列,保存在softnet_data->input_pkt_queue,所有非napi设备的入口skb,均挂载到此队列. // 2.3 内核为积压设备的提供po

网络子系统37_网桥、端口定时器

// 网桥定时器初始化 // 在添加网桥时,同时创建网桥使用的定时器 // 调用路径:br_add_bridge->new_bridge_dev->br_stp_timer_init // 网桥使用的定时器:hello, tcn, tc, gc 1.1 void br_stp_timer_init(struct net_bridge *br) { //根网桥周期性向通过指定端口向其他网桥发送配置BPDU setup_timer(&br->hello_timer, br_hello

网络子系统68_路由表处理设备ip配置事件

// 路由表处理inet配置事件 // 在ip_rt_init->ip_fib_init中注册 1.1 static struct notifier_block fib_inetaddr_notifier = { .notifier_call = fib_inetaddr_event, }; // 路由表处理地址配置事件 // 函数主要功能: // 1.设备配置ip地址 // 1.1 将ip地址添加到路由表 // 1.2 同步多路径路由 // 1.3 刷新路由缓存 // 2.设备删除ip地址 /

网络子系统6_设备开启与关闭

// 网络设备开启 // 函数主要任务: // 1.设置dev->state=__LINK_STATE_START // 2.调用驱动程序的回调函数open // 3.设置dev->flags |= IFF_UP表示设备开启 // 4.更新多播列表, // 5.激活设备 // 6.通知监听器,设置dev->flags // 设备开启之后应该具备的特征: // 1.dev->state, 表示设备可以进行传输接收 // 2.dev->flags,表示设备已经开启 // 3.设备

网络子系统27_桥接子系统初始化

//桥接子系统以模块的形式提供 //函数主要任务: // 1.转发数据库slab缓存 // 2.向socket的ioctl添加回调函数 // 3.在netif_receive_skb中路径上添加回调函数 // 4.向netdev_chain注册监听块 1.1 static int __init br_init(void) { //转发数据库初始化 br_fdb_init(); //桥接子系统中有关netfilter的初始化 ... //向socket的ioctl注册回调函数,处理对网桥的io命令

网络子系统25_生成树协议

//参考 深入理解linux网络技术内幕 //生成树协议(Spanning Tree Protocol, STP)是用于消除环路拓扑的分布式算法. //生成树协议的基本元素: // 1.链路开销,当链路没有指定开销,或者都设置成相同开销时,一个节点到达根的距离用网络跃点数来测量. // 2.BPDU,STP通过让各个网桥之间交换称为网络协议数据单元(BPDU)的特殊帧来传递配置信息. // 3.根网桥,唯一能产生BPDU的网桥,其他网桥只有在接收到BPDU时才会传输BPDU(当网桥第一次加入时,

网络子系统30_桥接子系统通用接口

// 添加网桥设备 // 参数: // name,需要全局唯一 // 调用路径:socket ioctl->br_add_bridge // 函数主要任务: // 1.创建一个新的网络设备 // 2.初始化网络设备的通用字段以及网桥设备的字段 // 3.向系统注册网络设备 1.1 int br_add_bridge(const char *name) { struct net_device *dev;//net_bridge->dev int ret; dev = new_bridge_dev