网络子系统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.设备使用了正确的队列规则

1.1 int dev_open(struct net_device *dev)
{
	int ret = 0;

	//检查设备是否已经开启
	if (dev->flags & IFF_UP)
		return 0;

	//检查设备是否存在
	if (!netif_device_present(dev))
		return -ENODEV;
	//设置设备可以进行接收
	set_bit(__LINK_STATE_START, &dev->state);
	if (dev->open) {
		//如果驱动程序提供了open函数,则调用
		ret = dev->open(dev);
		if (ret)
			clear_bit(__LINK_STATE_START, &dev->state);
	}
	if (!ret) {
		//设置开启标志
		dev->flags |= IFF_UP;
		//加载多播地址列表
		dev_mc_upload(dev);
		//激活设备,使能传输队列
		dev_activate(dev);
		//向netdev_chain通知有设备开启
		notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
	}
	return ret;
}

//	加载设备多播地址
//	调用路径:dev_open->dev_mc_upload
//	ip地址,mac地址之间的映射,参照http://blog.csdn.net/hxg130435477/article/details/8049271
1.2 void dev_mc_upload(struct net_device *dev)
{
	spin_lock_bh(&dev->xmit_lock);
	__dev_mc_upload(dev);
	spin_unlock_bh(&dev->xmit_lock);
}

//	调用路径:dev_open->dev_mc_upload->__dev_mc_upload
//	通过驱动程序的回调函数,设置设备的l2多播地址列表
1.3 static void __dev_mc_upload(struct net_device *dev)
{
	//设备应该处于关闭状态
	if (!(dev->flags&IFF_UP))
		return;
	//设备驱动提供了设置多播地址的方法
	if (dev->set_multicast_list == NULL ||
	    !netif_device_present(dev))
		return;
	//调用设备提供的设置多播地址的方法
	dev->set_multicast_list(dev);
}


//	调用路径:dev_open->dev_activate
//	函数主要任务:
//		1.更新设备的队列规则
//			1.1 如果设备没有使用队列规则,则dev->qdisc设置为noqueue_disc,防止不正确的使用该驱动的队列规则
//			1.2 如果设备使用队列规则:
//				1.2.1 如果设置第一次被激活,则分配新的队列规则,保存在dev->qdisc_sleeping
//				1.2.2 如果设备非第一次被激活
//				1.2.3 设置dev->qdisc=dev->qdisc_sleeping
//		2.启动看门狗
1.4 void dev_activate(struct net_device *dev)
{
	//设备没有关联队列规则
	if (dev->qdisc_sleeping == &noop_qdisc) {
		struct Qdisc *qdisc;
		//设备存在传输队列
		//dev->tx_queue_len的值由设备驱动程序设置
		if (dev->tx_queue_len) {
			//创建先进先出队列
			qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops);
			if (qdisc == NULL) {
				printk(KERN_INFO "%s: activation failed\n", dev->name);
				return;
			}
			//将队列规则添加到dev的队列规则链表头
			//说明一个dev可以有多个队列规则
			write_lock_bh(&qdisc_tree_lock);
			list_add_tail(&qdisc->list, &dev->qdisc_list);
			write_unlock_bh(&qdisc_tree_lock);
		} else {
			//如果驱动程序没有提供tx_queue_len,即=0
			//设置默认的队列
			qdisc =  &noqueue_qdisc;
		}
		write_lock_bh(&qdisc_tree_lock);
		//设置dev的qdisc_sleeping
		dev->qdisc_sleeping = qdisc;
		write_unlock_bh(&qdisc_tree_lock);
	}

	spin_lock_bh(&dev->queue_lock);
	//设置qdisc_sleep到qdisc字段
	rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
	if (dev->qdisc != &noqueue_qdisc) {
		dev->trans_start = jiffies;
		//唤醒看门狗
		dev_watchdog_up(dev);
	}
	spin_unlock_bh(&dev->queue_lock);
}


//	设备关闭
//	函数主要任务:
//		1.向netdev_chain发送消息NETDEV_GOING_DOWN
//		2.deactivate设备,
//		3.清除dev->state的__LINK_STATE_START
//		4.等待设备完成数据接收
//		5.调用驱动程序提供的关闭函数
//		6清除dev->flags中的IFF_UP
//		7.向netdev_chain发送消息NETDEV_DOWN

2.1 int dev_close(struct net_device *dev)
{
	//设备已经关闭,则直接返回
	if (!(dev->flags & IFF_UP))
		return 0;
	//向netdev_chain发送设备正在关闭消息
	notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);

	//关闭设备队列规则
	dev_deactivate(dev);

	//设置设备关闭传输
	clear_bit(__LINK_STATE_START, &dev->state);
	//内存屏障
	smp_mb__after_clear_bit(); 
		//设备还在接收输入流量
	while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
		//调度当前线程等待
		current->state = TASK_INTERRUPTIBLE;
		schedule_timeout(1);
	}
	//驱动提供了停止函数,则调用
	if (dev->stop)
		dev->stop(dev);

	//清除IFF_UP标志,表示设备已被关闭
	dev->flags &= ~IFF_UP;
	//通知netdev_chain已关闭消息
	notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);

	return 0;
}

//	网络设备的看门狗:
//		1.当网络设备由于被开启而激活传输时,同时激活设备驱动程序的开门狗机制。
//		2.看门狗的定时周期由驱动程序通过dev->watchdog_time指定
//		3.看门狗的定时器由驱动程序通过dev->watchdog_timer提供

//	调用路径:dev_activate->dev_watchdog_up
3.1 static void dev_watchdog_up(struct net_device *dev)
{
	//在获取dev->xmit_lock传输锁时设置看门狗定时器
	spin_lock_bh(&dev->xmit_lock);
	__netdev_watchdog_up(dev);
	spin_unlock_bh(&dev->xmit_lock);
}

// 调用路径dev_activate->dev_watchdog_up->__netdev_watchdog_up
void __netdev_watchdog_up(struct net_device *dev)
{
	if (dev->tx_timeout) {
		if (dev->watchdog_timeo <= 0)//设备驱动没有设置看门狗的到期时间
			dev->watchdog_timeo = 5*HZ;
		if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
			dev_hold(dev);
	}
}


目录
相关文章
|
21天前
|
Ubuntu Windows
【Ubuntu/Arm】Ubuntu 系统如何链接有线网络(非虚拟机)?
【Ubuntu/Arm】Ubuntu 系统如何链接有线网络(非虚拟机)?
|
28天前
|
安全 网络安全 网络虚拟化
【软件设计师备考 专题 】常用网络设备和各类通信设备(一)
【软件设计师备考 专题 】常用网络设备和各类通信设备
97 2
|
11天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
31 6
|
4天前
|
安全 网络安全 网络虚拟化
《计算机网络简易速速上手小册》第3章:计算机网络设备和工具(2024 最新版)
《计算机网络简易速速上手小册》第3章:计算机网络设备和工具(2024 最新版)
21 1
|
13天前
|
JavaScript Java 测试技术
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
30 0
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
|
14天前
|
边缘计算 网络虚拟化 虚拟化
虚拟网络设备性能优化
在现代网络架构中,虚拟网络设备扮演着越来越重要的角色🌐,特别是在云计算☁️和容器化技术📦广泛应用的背景下。虚拟网络设备如虚拟以太网设备(veth)、虚拟交换机(vSwitch)、和虚拟路由器等,提供了灵活的网络连接和隔离方案🔗。然而,与物理网络设备相比,虚拟网络设备在处理能力💪、带宽利用率📈和延迟⏳方面可能存在性能瓶颈。因此,性能优化成为了虚拟网络设备管理中的一个重要议题🛠️。本文将探讨虚拟网络设备的性能优化手段,帮助网络管理员更有效地利用这些设备。
|
14天前
|
安全 网络安全 网络虚拟化
虚拟网络设备与网络安全:深入分析与实践应用
在数字化时代📲,网络安全🔒成为了企业和个人防御体系中不可或缺的一部分。随着网络攻击的日益复杂和频繁🔥,传统的物理网络安全措施已经无法满足快速发展的需求。虚拟网络设备🖧,作为网络架构中的重要组成部分,通过提供灵活的配置和强大的隔离能力🛡️,为网络安全提供了新的保障。本文将从多个维度深入分析虚拟网络设备是如何保障网络安全的,以及它们的实际意义和应用场景。
|
14天前
|
安全 网络安全 SDN
虚拟网络设备的真正使命:实现有控制的通信
虚拟网络设备确实提供了强大的网络隔离能力🛡️,但这种隔离本身并不是最终目的。实际上,更重要的是通过这种隔离能力实现有控制的通信🎛️,以满足特定的业务需求、安全要求和性能标准。换句话说,网络隔离是手段,而有控制的通信才是目的🎯。
虚拟网络设备的真正使命:实现有控制的通信
|
14天前
|
网络协议 Linux SDN
虚拟网络设备与Linux网络协议栈
在现代计算环境中,虚拟网络设备在实现灵活的网络配置和隔离方面发挥了至关重要的作用🔧,特别是在容器化和虚拟化技术广泛应用的今天🌐。而Linux网络协议栈则是操作系统处理网络通信的核心💻,它支持广泛的协议和网络服务🌍,确保数据正确地在网络中传输。本文将深入分析虚拟网络设备与Linux网络协议栈的关联,揭示它们如何共同工作以支持复杂的网络需求。
|
16天前
|
机器学习/深度学习 人工智能 运维
构建未来:AI驱动的自适应网络安全防御系统
【4月更文挑战第7天】 在数字时代的浪潮中,网络安全已成为维系信息完整性、保障用户隐私和确保商业连续性的关键。传统的安全防御策略,受限于其静态性质和对新型威胁的响应迟缓,已难以满足日益增长的安全需求。本文将探讨如何利用人工智能(AI)技术打造一个自适应的网络安全防御系统,该系统能够实时分析网络流量,自动识别并响应未知威胁,从而提供更为强大和灵活的保护机制。通过深入剖析AI算法的核心原理及其在网络安全中的应用,我们将展望一个由AI赋能的、更加智能和安全的网络环境。
27 0

热门文章

最新文章