开发者社区> 亦侠> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

网络子系统35_BPDU的发送与接收

简介:
+关注继续查看
//	传输配置BPDU
//	函数主要任务:
//		1.检查速率限制
//		2.填充bpdu报文
//		3.发送配置bpdu

//	注:每个端口对bpdu的发送速率具有限制,通过net_bridge_port->hold_timer进行限制。
1.1 void br_transmit_config(struct net_bridge_port *p)
{
	struct br_config_bpdu bpdu;//配置bpdu
	struct net_bridge *br;


	if (timer_pending(&p->hold_timer)) {//如果在速率限制区间内,则设置config_pending,然后返回
		p->config_pending = 1;
		return;
	}

	br = p->br;//网桥的设备

	bpdu.topology_change = br->topology_change;//初始化配置bpdu协议相关项
	bpdu.topology_change_ack = p->topology_change_ack;
	bpdu.root = br->designated_root;
	bpdu.root_path_cost = br->root_path_cost;
	bpdu.bridge_id = br->bridge_id;
	bpdu.port_id = p->port_id;
	if (br_is_root_bridge(br))//根网桥
		bpdu.message_age = 0;//自从根网桥生成该BPDU中包含的信息后已经过的时间
	else {
		struct net_bridge_port *root
			= br_get_port(br, br->root_port);
		bpdu.message_age = br->max_age
			- (root->message_age_timer.expires - jiffies)
			+ MESSAGE_AGE_INCR;
	}
	bpdu.max_age = br->max_age;//配置BPDU的最大生存期
	bpdu.hello_time = br->hello_time;
	bpdu.forward_delay = br->forward_delay;

	if (bpdu.message_age < br->max_age) {
		br_send_config_bpdu(p, &bpdu);//发送配置BPDU
		p->topology_change_ack = 0;
		p->config_pending = 0;
		mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
	}
}

//	处理入口bpdu帧
//	调用路径netif_receive_skb->...->br_stp_handle_bpdu
//	函数主要任务:
//		1.确保sk_buff->data足够bpdu协议格式
//		2.通过报文内容,区别配置bpdu,tc-bpdu,分别处理 
2.1 int br_stp_handle_bpdu(struct sk_buff *skb)
{
	struct net_bridge_port *p = skb->dev->br_port;
	struct net_bridge *br = p->br;
	unsigned char *buf;

	if (!pskb_may_pull(skb, sizeof(header)+1) ||//使skb->data到skb->tail的数据量足够 802 和 STP 协议最小的协议头
	    memcmp(skb->data, header, sizeof(header)))//拷贝协议头到header中
		goto err;

	buf = skb_pull(skb, sizeof(header));//skb->data向下移动n个字节,skb->len-=n

	spin_lock_bh(&br->lock);//获取网桥的锁
	if (p->state == BR_STATE_DISABLED //skb的接收端口被关闭
	    || !(br->dev->flags & IFF_UP)//网桥被关闭
	    || !br->stp_enabled)//网桥没有运行stp协议
		goto out;

	if (buf[0] == BPDU_TYPE_CONFIG) {//配置BPDU
		struct br_config_bpdu bpdu;
		//按照配置BPDU的报文格式填充结构
		if (!pskb_may_pull(skb, 32))
		    goto out;

		buf = skb->data;
		bpdu.topology_change = (buf[1] & 0x01) ? 1 : 0;//拓扑是否改变
		bpdu.topology_change_ack = (buf[1] & 0x80) ? 1 : 0;//拓扑改变BPDU的ack
		//优先级向量<根网桥id,根网桥开销,发送网桥id,发送网桥端口id>
		bpdu.root.prio[0] = buf[2];
		bpdu.root.prio[1] = buf[3];
		bpdu.root.addr[0] = buf[4];
		bpdu.root.addr[1] = buf[5];
		bpdu.root.addr[2] = buf[6];
		bpdu.root.addr[3] = buf[7];
		bpdu.root.addr[4] = buf[8];
		bpdu.root.addr[5] = buf[9];
		bpdu.root_path_cost =
			(buf[10] << 24) |
			(buf[11] << 16) |
			(buf[12] << 8) |
			buf[13];
		bpdu.bridge_id.prio[0] = buf[14];
		bpdu.bridge_id.prio[1] = buf[15];
		bpdu.bridge_id.addr[0] = buf[16];
		bpdu.bridge_id.addr[1] = buf[17];
		bpdu.bridge_id.addr[2] = buf[18];
		bpdu.bridge_id.addr[3] = buf[19];
		bpdu.bridge_id.addr[4] = buf[20];
		bpdu.bridge_id.addr[5] = buf[21];
		bpdu.port_id = (buf[22] << 8) | buf[23];

		bpdu.message_age = br_get_ticks(buf+24);//自从根网桥生成该bpdu以来,已经过去的时间
		bpdu.max_age = br_get_ticks(buf+26);//配置bpdu的最大生存期
		bpdu.hello_time = br_get_ticks(buf+28);//hello定时器所用的时限
		bpdu.forward_delay = br_get_ticks(buf+30);//forward delay所用的时限

		br_received_config_bpdu(p, &bpdu);//协议处理函数
	}

	else if (buf[0] == BPDU_TYPE_TCN) {//拓扑改变bpdu
		br_received_tcn_bpdu(p);
	}
 out:
	spin_unlock_bh(&br->lock);
 err:
	kfree_skb(skb);
	return 0;
}
//	处理配置BPDU
//	调用路径br_stp_handle_bpdu->br_received_config_bpdu
//	函数主要任务:
//		1.配置bpdu的优先级向量高于当前网桥的优先级向量
//			1.1 使用配置bpdu的配置信息
//			1.2 更新网桥配置信息, 重新选择根端口,指定端口
//			1.3 网桥端口的状态选择
//			1.4 如果网桥由非根网桥变为根网桥
//				1.4.1 使用tcn_timer,周期性向网络传输设置有tc标志的配置bpdu
//		2.配置bpdu的优先级向量低于当前网桥的优先级向量
//			2.1 如果接收端口是指定端口,则向指定端口发送本网桥使用的配置信息。
2.2 void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu)
{
	struct net_bridge *br;
	int was_root;
 
	br = p->br;
	was_root = br_is_root_bridge(br);//当前网桥是否为根网桥

	if (br_supersedes_port_info(p, bpdu)) {//配置bpdu中的优先级向量高于当前网桥的优先级向量
		br_record_config_information(p, bpdu);//更新接收到的端口优先级向量,修改message_age定时器的到期时间
		br_configuration_update(br);//更新网桥的配置信息,选择根端口,指定端口
		br_port_state_selection(br);//开启网桥端口状态的选择

		if (!br_is_root_bridge(br) && was_root) {//由根网桥变成了非根网桥
			del_timer(&br->hello_timer);//非根网桥不需要使用hello定时器
			if (br->topology_change_detected) {//检测到拓扑的变化设置该字段
				del_timer(&br->topology_change_timer);//根网桥检测到拓扑变化后,使用该定时器,通知其他网桥拓扑的变化
				br_transmit_tcn(br);//从根端口发送tcn

				mod_timer(&br->tcn_timer, 
					  jiffies + br->bridge_hello_time);//普通网桥检测到拓扑变化后,使用的定时器,等待接收到tca
			}
		}

		if (p->port_no == br->root_port) {//当前端口为根端口
			br_record_config_timeout_values(br, bpdu);//更新br->max_age,hello_time,forward delay,topology_change。当根网桥检测的拓扑变化后,会启动topology_change_timer,并且在发送的配置bpdu中设置tc标志,当根网桥的topology_change_timer到期后,之后发送的配置bpdu,都不会再有tc标志。其他非根网桥,在每次从根端口收到配置bpdu时,都会将其中的tc标志保存在br->topology_change字段中,然后从指定端口发送的配置bpdu时,根据该字段,决定是否设置tc标志。
			br_config_bpdu_generation(br);//在每个使能的指定端口,发送配置BPDU
			if (bpdu->topology_change_ack)//此bpdu时对本机之前发送的TCN的应答,TCN从根端口发送,然后从根端口接收到TCA的配置BPDU
				br_topology_change_acknowledged(br);//收到TCN应答
		}
	} else if (br_is_designated_port(p)) {//收到的bpdu优先级向量低于本网桥使用的优先级向量
		br_reply(p);//回复本网桥使用的配置信息		
	}
}



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Kali Linux 网络扫描秘籍 第七章 Web 应用扫描(三)
第七章 Web 应用扫描(三) 作者:Justin Hutchens 译者:飞龙 协议:CC BY-NC-SA 4.0 7.13 使用 BurpSuite Sequencer(序列器) Web 应用会话通常由会话 ID 标识来维护,它由随机或伪随机值组成。
1184 0
Kali Linux 网络扫描秘籍 第七章 Web 应用扫描(二)
第七章 Web 应用扫描(二) 作者:Justin Hutchens 译者:飞龙 协议:CC BY-NC-SA 4.0 7.7 使用 BurpSuite Web 代理 虽然它有许多可用工具,BurpSuite 的主要功能就是拦截代理。
1148 0
Kali Linux 网络扫描秘籍 第七章 Web 应用扫描(一)
第七章 Web 应用扫描(一) 作者:Justin Hutchens 译者:飞龙 协议:CC BY-NC-SA 4.0 7.1 使用 Nikto 扫描 Web 应用 Nikto 是 Kali 中的命令行工具,用于评估 Web 应用的已知安全问题。
1857 0
linux 网络Socket实战
Preface:就算调通API,也不值得太过自豪!!!悉心细心学习,最好的深度学习就是看-学...*.h/*.class ProtoType; 1,linux C ftp C/S简单实现 ftpS端码子 C端码子  码子测试 C语言编译错误:expected d...
697 0
批量Linux 网络安装环境建立工具cobbler/kickstart
批量Linux 网络安装环境建立工具网络安装服务器套件:     Cobbler(Red Hat 2008年发布的项目)    Kickstart(Red Hat08年前项目,相关脚本令人望而却步,现今应用渐移cobbler,在cobbler中仅遗骨架,事件类似于perl用户遗向pythno) 相...
1032 0
Linux 学习笔记_12_文件共享服务_3_NFS网络文件服务
NFS网络文件服务 NFS---- Network File System 用于UNIX/Linux【UNIX类操作系统】系统间通过网络进行文件共享,用户可以把网络中NFS服务器提供的共享目录挂载到本地文件目录中,用户可以像操作本地文件系统一样操作NFS文件系统中的内容。
881 0
Linux下并发网络设计之I/O复用
I/O 流:   首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象。   不管是文件,还是套接字,还是管道,我们都可以把他们看作流。   之后我们来讨论I/O的操作,通过read,我们可以从流中读入数据;通过write,我们可以往流写入数据。
596 0
vmware linux下配置 bridged网络
在vmware安装linux后一直都使用NAT的连接方式,使用了vmnet8的网络,只能保证虚拟机访问外网,而不能从外面访问虚拟机。  后来发现用bridged的方式可以使虚拟机具有独立的IP。 具体配置有以下步骤: 1, 点击vmware的 Edit--&gt;"Virtula network edit" 增加一个bridge的网络。采用 automic 方式 2,  在该虚拟机的s
1130 0
Linux基本配置和管理 1---- Linux网络基本配置
 1 IP编址     1 IP编址是一个双层的编址方案,一个IP编址标识一个主机(或一个网卡接口)     2 现在应用最为广泛的是ipv4,已经开始逐步香ipv6切换     3 ipv4地址为32位,ipv6为128位     ...
1153 0
Linux网络配置详解
<p><span style="font-size: 14pt;"> 搭建LAMP的形式分为:</span><br><span style="font-size: 14pt;">   ①:rpm----&gt;系统自带的软件(二进制软件包)</span><br><span style="font-size: 14pt;">   ②:.tar.gz----&gt; 源码的压缩文件</sp
1105 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
复杂网络架构下的网络故障智能处理—DC Brain之故障篇
立即下载
商业流量的精准在线分配
立即下载
企业级弹性公网IP发布
立即下载