网络子系统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;
}
时间: 2024-10-31 10:45:50

网络子系统32_网桥设备的开启与关闭的相关文章

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

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

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

手机QQ登陆设备保护开启与关闭方法

设备开启 1.进入新版的QQ以后依次点击[设置]---[登陆设备保护] 2.开启保护后可以保护你QQ账户的安全,在未验证的手机或电脑上登陆QQ,需要何手机短信验证一下或扫一扫才可以正常登陆.点击[开启保护] 3.此时手机会收到一条短信,验证码框中会自动抓取到手机短信中的验证码.如果抓取不到则需要手动输入验证码.点击[确定] 4.出现以如下图所示的界面则说明已开通了手机QQ登陆设备保护. 设备关闭 1.进入新版的QQ以后依次点击[设置]---[登陆设备保护] 2.进入登陆设备保护界面,点击[关闭保

网络子系统26_设备传输的开启和关闭

// 1.由设备驱动程序开启和关闭设备的传输功能 // 2.下边这些函数在驱动程序提供的open,close中被调用 // 开启设备的传输 1.1 static inline void netif_start_queue(struct net_device *dev) { clear_bit(__LINK_STATE_XOFF, &dev->state); } // 关闭设备传输 1.2 static inline void netif_stop_queue(struct net_devic

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

网络子系统2_设备子系统相关的初始化

//在socket文件系统注册之后,设备驱动程序注册之前被调用 //start_kernel->rest_init->kernel_thread->init->do_basic_setup->do_initcalls->net_dev_init 2.1 static int __init net_dev_init(void) { ... //proc文件系统中相关项的初始化 if (dev_proc_init()) goto out; //注册网络设备类 if (net