搜档网
当前位置:搜档网 › Linux内核分析-网络[五]:网桥

Linux内核分析-网络[五]:网桥

Linux内核分析-网络[五]:网桥
Linux内核分析-网络[五]:网桥

看完了路由表,重新回到netif_receive_skb ()函数,在提交给上层协议处理前,会执行下面一句,这就是网桥的相关操作,也是这篇要讲解的容。

view plaincopy to clipboardprint?

1. s kb = handle_bridge(skb, &pt_prev, &ret, orig_dev);

网桥可以简单理解为交换机,以下图为例,一台linux机器可以看作网桥和路由的结合,网桥将物理上的两个局域网LAN1、LAN2当作一个局域网处理,路由连接了两个子网1.0和2.0。从eth0和eth1网卡收到的报文在Bridge模块中会被处理成是由Bridge收到的,因此Bridge也相当于一个虚拟网卡。

STP五种状态

DISABLED

BLOCKING

LISTENING

LEARNING

FORWARDING

创建新的网桥br_add_bridge [net\bridge\br_if.c]

当使用SIOCBRADDBR调用ioctl时,会创建新的网桥br_add_bridge。

首先是创建新的网桥:

view plaincopy to clipboardprint?

1. d ev = new_bridge_dev(net, name);

然后设置dev->dev.type为br_type,而br_type是个全局变量,只初始化了一个名字变量

view plaincopy to clipboardprint?

1. S ET_NETDEV_DEVTYPE(dev, &br_type);

2. s tatic struct device_type br_type = {

3. .name = "bridge",

4. };

然后注册新创建的设备dev,网桥就相当一个虚拟网卡设备,注册过的设备用ifconfig 就可查看到:

view plaincopy to clipboardprint?

1. r et = register_netdevice(dev);

最后在sysfs文件系统中也创建相应项,便于查看和管理:

view plaincopy to clipboardprint?

1. r et = br_sysfs_addbr(dev);

将端口加入网桥br_add_if() [net\bridge\br_if.c]

当使用SIOCBRADDIF调用ioctl时,会向网卡加入新的端口br_add_if。

创建新的net_bridge_port p,会从br->port_list中分配一个未用的port_no,p->br会指向br,p->state设为BR_STATE_DISABLED。这里的p实际代表的就是网卡设备。

view plaincopy to clipboardprint?

1. p = new_nbp(br, dev);

将新创建的p加入CAM表中,CAM表是用来记录mac地址与物理端口的对应关系;而刚刚创建了p,因此也要加入CAM表中,并且该表项应是local的[关系如下图],可以看到,CAM表在实现中作为net_bridge的hash表,以addr作为hash值,链入

net_bridge_fdb_entry,再由它的dst指向net_bridge_port。

view plaincopy to clipboardprint?

1. e rr = br_fdb_insert(br, p, dev->dev_addr);

设备的br_port指向p。这里要明白的是,net_bridge可以看作全局量,是网桥,而net_bridge_port则是与网卡相对应的端口,因此每个设备dev有个指针br_port指向该端口。

view plaincopy to clipboardprint?

1. r cu_assign_pointer(dev->br_port, p);

将新创建的net_bridge_port加入br的链表port_list中,在创建新的net_bridge_port 时,会分配一个未用的port_no,而这个port_no就是根据br->port_list中的已经添加的net_bridge_port来找到未用的port_no的[具体如下图]。

view plaincopy to clipboardprint?

1. l ist_add_rcu(&p->list, &br->port_list);

重新计算网桥的ID,这里根据br->port_list链表中的net_bridge_port的最小的addr 来作为网桥的ID。

view plaincopy to clipboardprint?

1. b r_stp_recalculate_bridge_id(br);

网卡设备的删除br_del_bridge()与端口的移除add_del_if()与添加差不多,不再详述。

熟悉了网桥的创建与添加,再来看下网桥是如何工作的。

当收到数据包,通过netif_receive_skb()->handle_bridge()处理网桥:

view plaincopy to clipboardprint?

1. s tatic inline struct sk_buff *handle_bridge(struct sk_buff *skb,

2. struct packet_type **pt_prev, int *ret,

3. struct net_device *orig_dev)

4. {

5. struct net_bridge_port *port;

6.

7. if (skb->pkt_type == PACKET_LOOPBACK ||

8. (port = rcu_dereference(skb->dev->br_port)) == NULL)

9. return skb;

10.

11. if (*pt_prev) {

12. *ret = deliver_skb(skb, *pt_prev, orig_dev);

13. *pt_prev = NULL;

14. }

15.

16. return br_handle_frame_hook(port, skb);

17. }

1. 如果报文来自lo设备,或者dev->br_port为空(skb->dev是收到报文的网卡设备,而在向网桥添加端口时,dev->br_port被赋予了创建的与网卡相对应的端口p),此时不需要网桥处理,直接返回报文;

2. 如果报文匹配了之前的ptype_all中的协议,则pt_prev不为空,此时要先进行ptype_all中协议的处理,再进行网桥的处理;

3. br_handle_frame_hook是网桥处理钩子函数,在br_init() [net\bridge\br.c]中

br_handle_frame_hook = br_handle_frame;

br_handle_frame() [net\bridge\br_input.c]是真正的网桥处理函数,

下面进入br_handle_frame()开始网桥部分的处理:

与前面802.1q讲的一样,首先检查users来决定是否复制报文:

view plaincopy to clipboardprint?

1. s kb = skb_share_check(skb, GFP_ATOMIC);

如果报文的目的地址是01:80:c2:00:00:0X,则是发往STP的多播地址,此时调用

br_handle_local_finish()来完成报文的进一步处理:

view plaincopy to clipboardprint?

1. i f (unlikely(is_link_local(dest))){

2. ……

3. i f (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,

4. NULL, br_handle_local_finish))

5. return NULL; /* frame consumed by filter */

6. else

7. return skb;

8. }

而br_handle_local_finish()所做的容很简单,因为是多播报文,主机要做的仅仅是更新报文的源mac与接收端口的关系(在CAM表中)。

STP原理及选举过程

实验1: STP 1、实验目的 通过本实验,读者可以掌握如下技能: (1)理解STP 的工作原理 (2)掌握STP的选举过程 2、实验原理 STP(STP,Spanning Tree Protocol)解决广播风暴、同一帧的多个拷贝、交换机CAM 表不稳定等问题,STP 基本思路是阻断一些交换机接口,构建一棵没有环路的转发树。STP 利用BPDU(Bridge Protocol Data Unit)和其他交换机进行通信,从而确定哪个交换机该阻断哪个接口。在BPDU 中有几个关键的字段,例如:根桥ID、路径代价、端口ID 等。 为了在网络中形成一个没有环路的拓扑,网络中的交换机要进行以下三个步骤:(1)选举根桥、(2)选举根端口、(3)选举指定端口。这些步骤中,哪个交换机能获胜将取决于以下因素(按顺序进行): (1)最低的根桥ID 由两部分组成:桥优先级(默认32768)和MAC地址 (2)最低的根路径代价

不是独立的协议标准,而是为标准做的一些必要性补充。 本实验中各种以太网类型的cost如下: 100M: 200000 10M: 100 2000000 (3)最低发送者桥ID 也就是发送者的桥ID,判断规则同(1)中的一样 (4)最低发送者端口ID 由两部分组成:端口优先级(默认32)和端口序列号(例:f0/3比f0/47优先级高) 每个交换机都具有一个唯一的桥ID,这个ID 由两部分组成:网桥优先级+MAC 地址(如果网桥优先级相同,才比较MAC地址)。网桥优先级是一个2个字节的数(0-61440),交换机的默认优先级为32768;MAC地址就是交换机的MAC地址。具有最低桥ID的交换机就是根桥。根桥上的接口都是指定口,会转发数据包。 选举了根桥后,其他的交换机就成为非根桥了。每台非根桥要选举一条到根桥的根路径。STP 使用路径Cost 来决定到达根桥的最佳路径(Cost 是累加的,带宽大的链路Cost 低),最低Cost 值的路径就是根路径,该接口就是根口;如果Cost 值一样,再根据最低发送者桥ID、最低发送者

Linux内核崩溃原因分析及错误跟踪技术

Linux内核崩溃原因分析及错误跟踪技术 随着嵌入式Linux系统的广泛应用,对系统的可靠性提出了更高的要求,尤其是涉及到生命财产等重要领域,要求系统达到安全完整性等级3级以上[1],故障率(每小时出现危险故障的可能性)为10-7以下,相当于系统的平均故障间隔时间(MTBF)至少要达到1141年以上,因此提高系统可靠性已成为一项艰巨的任务。对某公司在工业领域14 878个控制器系统的应用调查表明,从2004年初到2007年9月底,随着硬软件的不断改进,根据错误报告统计的故障率已降低到2004年的五分之一以下,但查找错误的时间却增加到原来的3倍以上。 这种解决问题所需时间呈上升的趋势固然有软件问题,但缺乏必要的手段以辅助解决问题才是主要的原因。通过对故障的统计跟踪发现,难以解决的软件错误和从发现到解决耗时较长的软件错误都集中在操作系统的核心部分,这其中又有很大比例集中在驱动程序部分[2]。因此,错误跟踪技术被看成是提高系统安全完整性等级的一个重要措施[1],大多数现代操作系统均为发展提供了操作系统内核“崩溃转储”机制,即在软件系统宕机时,将内存内容保存到磁盘[3],或者通过网络发送到故障服务器[3],或者直接启动内核调试器[4]等,以供事后分析改进。 基于Linux操作系统内核的崩溃转储机制近年来有以下几种: (1) LKCD(Linux Kernel Crash Dump)机制[3]; (2) KDUMP(Linux Kernel Dump)机制[4]; (3) KDB机制[5]; (4) KGDB机制[6]。 综合上述几种机制可以发现,这四种机制之间有以下三个共同点: (1) 适用于为运算资源丰富、存储空间充足的应用场合; (2) 发生系统崩溃后恢复时间无严格要求; (3) 主要针对较通用的硬件平台,如X86平台。 在嵌入式应用场合想要直接使用上列机制中的某一种,却遇到以下三个难点无法解决: (1) 存储空间不足 嵌入式系统一般采用Flash作为存储器,而Flash容量有限,且可能远远小于嵌入式系统中的内存容量。因此将全部内存内容保存到Flash不可行。

探究linux内核,超详细解析子系统

探究linux内核,超详细解析子系统 Perface 前面已经写过一篇《嵌入式linux内核的五个子系统》,概括性比较强,也比较简略,现在对其进行补充说明。 仅留此笔记,待日后查看及补充!Linux内核的子系统 内核是操作系统的核心。Linux内核提供很多基本功能,如虚拟内存、多任务、共享库、需求加载、共享写时拷贝(Copy-On-Write)以及网络功能等。增加各种不同功能导致内核代码不断增加。 Linux内核把不同功能分成不同的子系统的方法,通过一种整体的结构把各种功能集合在一起,提高了工作效率。同时还提供动态加载模块的方式,为动态修改内核功能提供了灵活性。系统调用接口用户程序通过软件中断后,调用系统内核提供的功能,这个在用户空间和内核提供的服务之间的接口称为系统调用。系统调用是Linux内核提供的,用户空间无法直接使用系统调用。在用户进程使用系统调用必须跨越应用程序和内核的界限。Linux内核向用户提供了统一的系统调用接口,但是在不同处理器上系统调用的方法

各不相同。Linux内核提供了大量的系统调用,现在从系统 调用的基本原理出发探究Linux系统调用的方法。这是在一个用户进程中通过GNU C库进行的系统调用示意图,系 统调用通过同一个入口点传入内核。以i386体系结构为例,约定使用EAX寄存器标记系统调用。 当加载了系统C库调用的索引和参数时,就会调用0x80软件中断,它将执行system_call函数,这个函数按照EAX 寄存器内容的标示处理所有的系统调用。经过几个单元测试,会使用EAX寄存器的内容的索引查system_call_table表得到系统调用的入口,然后执行系统调用。从系统调用返回后,最终执行system_exit,并调用resume_userspace函数返回用户空间。 linux内核系统调用的核心是系统多路分解表。最终通过EAX寄存器的系统调用标识和索引值从对应的系统调用表 中查出对应系统调用的入口地址,然后执行系统调用。 linux系统调用并不单层的调用关系,有的系统调用会由

linux内核IMQ源码实现分析

本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。 E-mail: wwwlkk@https://www.sodocs.net/doc/1217448508.html, 来源: https://www.sodocs.net/doc/1217448508.html,/?business&aid=6&un=wwwlkk#7 linux2.6.35内核IMQ源码实现分析 (1)数据包截留并重新注入协议栈技术 (1) (2)及时处理数据包技术 (2) (3)IMQ设备数据包重新注入协议栈流程 (4) (4)IMQ截留数据包流程 (4) (5)IMQ在软中断中及时将数据包重新注入协议栈 (7) (6)结束语 (9) 前言:IMQ用于入口流量整形和全局的流量控制,IMQ的配置是很简单的,但很少人分析过IMQ的内核实现,网络上也没有IMQ的源码分析文档,为了搞清楚IMQ的性能,稳定性,以及借鉴IMQ的技术,本文分析了IMQ的内核实现机制。 首先揭示IMQ的核心技术: 1.如何从协议栈中截留数据包,并能把数据包重新注入协议栈。 2.如何做到及时的将数据包重新注入协议栈。 实际上linux的标准内核已经解决了以上2个技术难点,第1个技术可以在NF_QUEUE机制中看到,第二个技术可以在发包软中断中看到。下面先介绍这2个技术。 (1)数据包截留并重新注入协议栈技术

(2)及时处理数据包技术 QoS有个技术难点:将数据包入队,然后发送队列中合适的数据包,那么如何做到队列中的数

激活状态的队列是否能保证队列中的数据包被及时的发送吗?接下来看一下,激活状态的队列的 证了数据包会被及时的发送。 这是linux内核发送软中断的机制,IMQ就是利用了这个机制,不同点在于:正常的发送队列是将数据包发送给网卡驱动,而IMQ队列是将数据包发送给okfn函数。

简析linux内核的内核执行流程图

简析linux核的执行流程 ----从bootsect.s到main.c(核版本0.11)Linux启动的第一阶段(从开机到main.c) 3个任务: A、启动BIOS,准备实模式下的中断向量表和中断服务程序。 B、从启动盘加载操作系统程序到存。 C、为执行32的main函数做过渡准备。 存变化如下: ①、0xFE000到0xFFFFF是BIOS启动块,其中上电后第一条指令在0xFFFF0。 ②、而后0x00000到0x003FF总共1KB存放中断向量表,而接下去的地址到0x004FF共256B存放BIOS数据,从0x0E05B 开始的约8KB的存中存放中断服务程序。 ③、利用BIOS中断0x19h把硬盘的第一扇区bootsect.s的代码加载到存中,即0x07c00处,后转到该处执行。 ④、将bootsect.s的代码复制到0x90000处。 ⑤、利用中断0x13h将setup.s程序加载到存0x90200处。 ⑥、再将剩余的约240个扇区的容加载到0x10000~0x2EFFF 处。 ⑦、开始转到setup.s处执行,第一件事就利用BIOS提供的中断服务程序从设备上获取核运行的所需系统数据并存在0x90000的地址处,这时将原来bootsect.s的代码覆盖得只剩2Byte的空间。

⑧、关中断并将系统代码复制到0x00000处,将原来放在这里的中断向量表与BIOS数据区覆盖掉,地址围是 0x00000~0x1EFFF。同时制作两表与两寄存器。 ⑨开地址线A20,寻址空间达到4GB,后对8259重新编程,改变中断号。 ⑩、转到head.s(大小是25K+184B)执行,执行该程序完后是这样的: 0x00000~0x04FFF:页目录与4个页表,每一项是4KB,共20KB;0x05000~0x05400:共1KB的空间是软盘缓冲区; 0x05401~0x054b8:共184B没用; 0x054b9~0x05cb8:共2KB的空间存中断描述符表; 0x05cb9~0x064b8:共2KB的空间存全局描述符表; 之后就是main函数的代码了! 第二阶段、从main.c函数到系统准备完毕阶段。 第一步:创建进程0,并让进程0具备在32位保护模式下载主机中的运算能力。流程是: 复制根设备和硬盘参数表(main.c中的102、110、111行) 物理存规划格局(main.c的112行~126行,其中有 rd_init函数定义在kernel/ramdisk.c中,此函数用于虚拟盘初始化;而mem_init函数是用于存管理结构初始化,定义在mem/memory.c中,该函数页面使用

桥接、nat、Host-only的工作原理

VMware网络配置详解一:三种网络模式简介 安装好虚拟机以后,在网络连接里面可以看到多了两块网卡: 其中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口,这些后面会详细介绍 选择虚拟机网络模式方法如下,单击Edit virtual machine settings,如图所示: 然后在Hardware选项卡中选择Ethernet,在左边Network connection框架中有如下四个单选项:

1. Bridged(桥接模式) 在桥接模式下,VMware虚拟出来的操作系统就像是局域网中的一独立的主机,它可以访问网内任何一台机器不过你需要多于一个的IP地址,并且需要手工为虚拟系统配置IP地址子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信 如果你想利用VMware在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式 2. NAT(网络地址转换模式) 使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网也就是说,使用NAT模式可以实现在虚拟系统里访问互联网NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯采用NAT模式最

大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机器能访问互联网即可 如果你想利用VMware安装一个新的虚拟系统,在虚拟系统中不用进行任何手工配置就能直接访问互联网,建议你采用NAT模式 3. Host-only(主机模式) 在某些特殊的网络调试环境中,要求将真实环境和虚拟环境隔离开,这时你就可采用Host-only模式在Host-only模式中,所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的可以利用Windows XP里面自带的Internet连接共享(实际上是一个简单的路由NAT)来让虚拟机通过主机真实的网卡进行外网的访问虚拟系统的TCP/IP配置信息(如IP地址网关地址DNS服务器等),都是由VMnet1(Host-only)虚拟网络的DHCP 服务器来动态分配的 如果你想利用VMware创建一个与网内其他机器相隔离的虚拟系统,进行某些特殊的网络调试工作,可以选择Host-only模式

(完整版)linux内核技术

一、教学目的 SMP、多核系统、高性能浮点处理器和新型总线等创新技术,带动操作系统不断发展。本课程使硕士生了解linux的基本原理和结构特征,提高应用现代操作系统的水平、能开发特定的内核功能、设备驱动程序和复杂应用软件的能力。 二、教学内容与要求 1掌握处理器在进程地址空间上的三种运行位置,了解内核编程不能使用C库函数和FPU,以及可能产生内存故障、核心栈溢出和四种内核竞争情形的原因。(2学时)2熟悉进程描述符的组织,进程上下文和进程状态转换,和fork,exec,wait,exit,clone,linux线程和内核线程的实现原理和应用。了解COW和避免出现孤儿进程技术。 (4小时) 3介绍支持SMP的O(1)调度,用户和内核抢占和进程上下文切换,了解优先级复算,睡眠和唤醒机制,SMP的负载均衡。(4小时) 4掌握在x86体系结构上系统调用的具体实现原理,接口参数传递,用户地址空间和核心地址空间之间的数据传输,和增加新的系统功能的方法。(2小时)5熟悉在x86体系结构上Linux中断和异常的处理原理,中断注册、共享、控制,和中断上下文的意义,中断和设备驱动程序的关系,以及设备驱动程序结构和用户接口。 (4小时) 6中断处理程序被分解为top half和bottom half的原因,介绍linux的softirq,tasklet,ksoftirqd和work queue,分析进程与top half,bottom half的竞争情形和同步。(4小时)7掌握内核同步原理和方法:原子操作,自旋锁,(读—写)信号量,完成变量,bkl,seqlock和延迟内核抢占。了解指令“路障”。(4小时) 8介绍系统时钟和硬件定时器,单处理器和多处理器上的linux计时体系结构,定时的时间插补原理,单处理器和多处理器上的时钟中断处理,动态定时器的数据结构和算法原理,定时器竞争情形,延迟函数。Time,gettimeofday,adjtimex,setitimer,alarm 的实现原理和应用。(4小时) 9熟悉进程地址空间的区和页,分配和释放物理页,物理地址与逻辑地址、虚地址之间的映射,slub分配原理和方法,高端物理内存的映射。(4小时) 10介绍VFS原理,超级块,inode结构和方法,dentry结构和方法,file结构和方法,以及进程打开文件表,linux中的文件系统。(2小时) 11讲解块设备缓冲,bio结构,I/O请求队列,和有最终期限的块I/O调度算法。(2小时) 12熟悉进程地址空间的分区,mm_struct结构,vm_area_struct结构和操作,,进程的页表文件映射接口mmap原理和方法。(2小时) 13熟悉页cache和radix_tree,缓冲区cache,和pdflush内核线程原理。(2小时) 三、教学方式 教学方式:课堂讲授 考试方式:堂上考试、考查都采用笔试。

全过程讲解电梯监控无线网桥如何安装

全过程讲解电梯监控无线网桥如何安 装? 一、电梯视频监控 电梯作为楼宇的重要密闭型公共区域和上下出入关键通道,电梯视频监控对整个区域的安防工作具有重要作用,是不可缺少的重要一环。电梯视频监控可实时掌握电梯轿厢内的情况,保障乘客安全。 电梯监控视频传输可分为有线和无线两种。 有线传输:采用的是专业电梯随行电缆,一般的随行线缆使用时损耗严重,寿命在一到二年之间。高层电梯线缆对抗拉伸强度和电气参数有较高要求,防止线缆负载自重时拉伸变形导致阻抗不匹配,视频信号信噪比衰减产生干扰。再次更换新随行线缆施工困难,施工周期长,而且更换随行电缆的成本也较高。 无线传输:无线传输采用点对点的方式,轿厢上安装一个发射点、电梯井端部安装一个接收点,数据可在电梯轿厢运动时自由传输。无线传输设备安装简单且寿命至少在3年以上,带宽完全满足高清监控视频传输。

随行线缆 二、如何部署 电梯井监控视频无线传输有两种安装方式。顶置式和底置式,如下图:

顶置式部署适合于监控中心在楼宇顶部,一般情况下都是采用底置式部署方式。

值得注意的是,网桥都是有发射端与接收端。 三、网桥如何组网? 轿厢端的网桥需设置为客户端模式,这种模式下网桥就相当于一个网卡。把网络摄像头的视频数据从电信号转变为无线信号。

组网原理图:

电梯井端部的网桥设置为AP模式,这种模式下网桥与NVR直接通过网线连接,将接收到的无线信号直接转变为有线信号传输到NVR。 总结成一句话就是:靠近摄像头端的网桥设置为客户端模式,靠近NVR端的网桥设置为AP模式。 安装到电梯井之前需要事先将网桥配对好。

Linux内核分析-网络[五]:网桥

看完了路由表,重新回到netif_receive_skb ()函数,在提交给上层协议处理前,会执行下面一句,这就是网桥的相关操作,也是这篇要讲解的容。 view plaincopy to clipboardprint? 1. s kb = handle_bridge(skb, &pt_prev, &ret, orig_dev); 网桥可以简单理解为交换机,以下图为例,一台linux机器可以看作网桥和路由的结合,网桥将物理上的两个局域网LAN1、LAN2当作一个局域网处理,路由连接了两个子网1.0和2.0。从eth0和eth1网卡收到的报文在Bridge模块中会被处理成是由Bridge收到的,因此Bridge也相当于一个虚拟网卡。 STP五种状态 DISABLED BLOCKING LISTENING LEARNING FORWARDING 创建新的网桥br_add_bridge [net\bridge\br_if.c] 当使用SIOCBRADDBR调用ioctl时,会创建新的网桥br_add_bridge。 首先是创建新的网桥: view plaincopy to clipboardprint?

1. d ev = new_bridge_dev(net, name); 然后设置dev->dev.type为br_type,而br_type是个全局变量,只初始化了一个名字变量 view plaincopy to clipboardprint? 1. S ET_NETDEV_DEVTYPE(dev, &br_type); 2. s tatic struct device_type br_type = { 3. .name = "bridge", 4. }; 然后注册新创建的设备dev,网桥就相当一个虚拟网卡设备,注册过的设备用ifconfig 就可查看到: view plaincopy to clipboardprint? 1. r et = register_netdevice(dev); 最后在sysfs文件系统中也创建相应项,便于查看和管理: view plaincopy to clipboardprint? 1. r et = br_sysfs_addbr(dev); 将端口加入网桥br_add_if() [net\bridge\br_if.c] 当使用SIOCBRADDIF调用ioctl时,会向网卡加入新的端口br_add_if。 创建新的net_bridge_port p,会从br->port_list中分配一个未用的port_no,p->br会指向br,p->state设为BR_STATE_DISABLED。这里的p实际代表的就是网卡设备。 view plaincopy to clipboardprint? 1. p = new_nbp(br, dev); 将新创建的p加入CAM表中,CAM表是用来记录mac地址与物理端口的对应关系;而刚刚创建了p,因此也要加入CAM表中,并且该表项应是local的[关系如下图],可以看到,CAM表在实现中作为net_bridge的hash表,以addr作为hash值,链入 net_bridge_fdb_entry,再由它的dst指向net_bridge_port。

《边学边干-Linux内核指导》学习笔记一

写在前面的话:刚毕业,找的工作是嵌入式开发,在学校自学了几年Windows平台下的C/C++开发,可现在工作是在Linux平台下,所以一切都要从头开始(当然语言基础还是有用的)。从操作系统应用开始学,再到开发,经过几个月的学习,现在基本能胜任工作。在这个几个月之中,自己感觉大学里面荒废了太多时间。在学校时,总是认为学的东西没用(我想大概现在很多在校的学生还是这么认为吧),到现在才感觉自己基本功不够扎实。所以,决定好好研究一下linux内核,一方面是为了对操作系统有更深层次的理解,另一方面在研究内核的同时,学习linux底层编程。我用的教材是浙江大学出版社《Linux内核情景分析》上下册还有就是现在看的这本。希望有相同兴趣的朋友多多交流。 第一章了解Linux内核 这一章是对Linux内核的总体概括,我把我学会以及自己在实践过程中的理解并且觉得比较容易用的到东西分别叙述如下: 一、重新编译内核 1. 首先要确认你系统里面是否有linux的源代码,在Linux安装的时候有选项是否安装源代码。如果你在安装时没有选,不用担心,你可以到https://www.sodocs.net/doc/1217448508.html,/pub/linux/kernel 去下载你的系统对应的内核源代码。 2. 下载以后当然是将源代码包解压到你所要放的目录下,书上用的是下面两个命令: #mv linux-2.4…. your directory #tar zxvf linux-2.4… 3.配置内核 配置内核的过程可以分为以下几步: a.清除目录下所有配置文件和先前生成核心时产生的中间文件,在你的源代码目录执行如下命令: #make mrproper 注意:Kernel HOWTO对上面这个命令是这样解释的: `make mrproper' 将会做更广泛的`清除' 工作.这个动作有时候是必须的,所以你可能会希望在每次修补的时候执行它.`make mrproper' 还会将你的配置文件杀掉,所以如果你认为它重要的话应该先做一备份(在.config). b.对内核进行配置,有以下几种方法可供选择: #make config(基于文本的传统界面) #make menuconfig(基于文本的选单式配置界面,书中推荐的方式) #make xconfig(基于图形的配置界面) #make oldconfig(用于在原来配置的基础上作些小的修改) 注:我在我的机器上(redhat 9)执行make oldconfig这个命令的时候,系统根本没有让我配置内核,而是自动执行了配置,那我要怎么样用这个命令来配置内核呢,希望知道的朋友可以告诉我。在Kernel Howto中对这个命令的解释是: make oldconfig' 会尝试由一旧的配置文件来配置你的核心.它会为你执行`make config'。如果你还未曾编译过核心或没有旧的配置文件,那么你可能不该做这个,因为你几乎确定会更改缺省的配置。 c.对每一个配置项,用户有三种选择: “Y”——将该功能编译进内核; “N”——不将该功能编译进内核; “M”——将该功能编译成可以在需要时动态插入到内核中的模块。 d.编译内核和模块 接下来需要运行下面两条命令:

双路由器桥接图解、原理及实战

两个路由器桥接网络原理及常见问题解析以下方法是为了更好地解释双路由器桥接原理而采用了不同网段设置(主路由用192.168.1.X,从路由用192.168.0.X)。 一、路由器设置和计算机设置 1)路由器设置Ⅰ(主路由器),见下图。 2)路由器设置Ⅱ(从路由器),见下图: 更改WAN 口地址,更改LAN 口地址,更改DHCP 地址范围。

要点:路由器设置的WAN 口为动态IP 以便从第一个路由器那里获得IP 地址,更改它自己的IP 地址和DHCP 到另一个网段去使之与第一个路由器不在同一个网段。 如果从路由器LAN IP和主路由器在同一网段的话(如主路由192.168.1.1,从路由192.168.1.2),那从路由器必须关闭DHCP,因为从路由桥接只起到交换作用,局域网内的所有的终端包括交换部分都由第一台路由器管理,包括地址分配,否则,对同一个终端来说,到底是使用主路由分配的地址,还是用从路由分配的地址,就会产生冲突。

二、常见问题及设置注意点 1、如果从路由器经常死机,检查主路由器关闭WDS,从路由开启WDS。 2、如果更改从路由器ip后无法访问路由器进行设置,请用更改后的从路由器 ip192.168.0.1再访问。 3、从路由的DHCP关闭与否请看你的从路由器IP是否与主路由器在同一网段,关闭DHCP后从路由不会自动分配ip,网关和DNS,避免和主路由器冲突。 4、通过从路由器上网的机器如无法上网,请先检查该机器网卡的IP 地址是否与从路由器在同一个网段,以及网关地址是否正确(这里设从路由器的IP 地址为网关,如果主从路由器ip在同一网段,则这里的网关应设为主路由器ip),DNS 地址是否是主路由器的IP 地址,当然也可以是电信的IP 地址,比如61.177.7.1。 5、注意两个无线路由器AP的SSID必须相同/.两个无线路由器AP的无线网频道必须相同/相互注册对方AP的Wireless MAC address/两个AP的安全设置必须相同

基于Linux内核编程的实验报告(Linux内核分析实验报告)

基于Linux内核编程的实验报告(Linux内核分析实验 报告) 以下是为大家整理的基于Linux内核编程的实验报告(Linux内核分析实验报告)的相关范文,本文关键词为基于,Linux,内核,编程,实验,报告,分析,,您可以从右上方搜索框检索更多相关文章,如果您觉得有用,请继续关注我们并推荐给您的好友,您可以在教育文库中查看更多范文。 Linux内核分析实验报告

实验题目:文件系统实验 实验目的:linux文件系统使用虚拟文件系统VFs作为内核文件子系统。可以安装多种 不同形式的文件系统在其中共存并协同工作。VFs对用户提供了统一的文件访问接口。本实验的要求是 (1)编写一个get_FAT_boot函数,通过系统调用或动态模块调用它可以提 取和显示出FAT文件系统盘的引导扇区信息。这些信息的格式定义在内核文件的fat_boot_sector结构体中。函数可通过系统调用或动态模块调用。 (2)编写一个get_FAT_dir函数,通过系统调用或动态模块调用它可以 返回FAT文件系统的当 前目录表,从中找出和统计空闲的目录项(文件名以0x00打头的为从未使用过目录项,以0xe5打头的为已删除的目录项),将这些空闲的目录项集中调整到目录表的前部。这些信息的格式定义在内核文件的msdos_dir_entry结构体中。 硬件环境:内存1g以上 软件环境:Linux(ubuntu)2-6实验步骤: 一:实验原理: 以实验4为蓝本,在优盘中编译并加载模块,启动测试程序,查

/proc/mydir/myfile的文件内容。从优盘得到fat文件系统的内容存在msdos_sb_info结构中,然后得到msdos_sb_info结构相应的属性值,得到实验一的数据。实验二中,得到fat文件系统第一个扇区的十六个文件信息。然后按照文件名头文字的比较方法,应用归并排序的方法,将头文件是0x00和0xe5的文件调到前面,其他的文件调到后面 二:主要数据结构说明: (1)超级块对象: 数据结构说明:一个已经安装的文件系统的安装点由超级块对象代表。 structsuper_block{... conststructsuper_operations*s_op;} (2)索引i节点对象 数据结构说明:索引i节点对象包含了内核要操作的文件的全部控制信息,对应着打开文件的i节点表。structinode{ conststructinode_operations*i_op;...} (3)目录项对象 数据结构说明:录项对象代表了文件路径名的各个部分,目录文件名和普 通文件名都属于目录项对象。structdentry{

一文详解Linux内核的栈回溯与妙用

一文详解Linux内核的栈回溯与妙用 1 前言 说起linux内核的栈回溯功能,我想这对每个Linux内核或驱动开发人员来说,太常见了。如下演示的是linux内核崩溃的一个栈回溯打印,有了这个崩溃打印我们能很快定位到在内核哪个函数崩溃,大概在函数什么位置,大大简化了问题排查过程。 网上或多或少都能找到栈回溯的一些文章,但是讲的都并不完整,没有将内核栈回溯的功能用于实际的内核、应用程序调试,这是本篇文章的核心:尽可能引导读者将栈回溯的功能用于实际项目调试,栈回溯的功能很强大。 本文详细讲解了基于mips、arm架构linux内核栈回溯原理,通过不少例子,尽可能全面给读者展示各种栈回溯的原理,期望读者理解透彻栈回溯。在这个基础上,讲解笔者近几年项目开发过程中使用linux内核栈回溯功能的几处重点应用。 1 当内核某处陷入死循环,有时运行sysrq的内核线程栈回溯功能可以排查,但并不适用所用情况,笔者实际项目遇到过。最后是在系统定时钟中断函数,对死循环线程栈回溯20多级终于找到死循环的函数。 2 当应用程序段错误,内核捕捉到崩溃,对崩溃的应用空间进程/线程栈回溯,像内核栈回溯一样,打印应用段错误进程/线程的层层函数调用关系。虽然运用core文件分析或者gdb也很简便排查应用崩溃问题,但是对于不容易复现、测试部偶先的、客户现场偶先的,这二者就很难发挥作用。还有就是如果崩溃发生在C库中,CPU的pc和lr(arm架构)寄存器指向的函数指令在C库的用户空间,很难找到应用的代码哪里调用了C库的函数。arm架构网上能找到应用层栈回溯的例子,但是编译较麻烦,代码并不容易理解,况且mips能在应用层实现吗?还是在内核实现应用程序栈回溯比较方便。 3 应用程序发生double free,运用内核的栈回溯功能,找到应用代码哪里发生了double free。double free是C库层发现并截获该事件,然后向当前进程/线程发送SIGABRT进程终止信号,后续就是内核强制清理该进程/线程。double free比应用程序段错误更麻烦,后

二层交换机、三层交换机和路由器的基本工作原理.

二层交换机:二层交换技术是发展比较成熟,二层交换机属数据链路层设备,可以识别数据包中的地址信息,根据地址进行转发,并将这些地址与对应的端口记录在自己内部的一个地址表中. 具体如下: (1当交换机从某个端口收到一个数据包,它先读取包头中的源地址,这样它就知道源地址的机器是连在哪个端口上; (2再去读取包头中的目的地址,并在地址表中查找相应的端口 (3如表中有与这目的地址对应的端口,把数据包直接复制到这端口上 三层交换机: 三层交换技术就是将路由技术与交换技术合二为一的技术。在对第一个数据流进行路由后,它将会产生一个地址与地址的映射表,当同样的数据流再次通过时,将根据此表直接从二层通过而不是再次路由,从而消除了路由器进行路由选择而造成网络的延迟,提高了数据包转发的效率. 路由器:传统地,路由器工作于七层协议中的第三层,其主要任务是接收来自一个网络接口的数据包,根据其中所含的目的地址,决定转发到下一个目的地址。因此,路由器首先得在转发路由表中查找它的目的地址,若找到了目的地址,就在数据包的帧格前添加下一个地址,同时数据包头的( 域也开始减数,并重新计算校验和。当数据包被送到输出端口时,它需要按顺序等待,以便被传送到输出链路上。 路由器在工作时能够按照某种路由通信协议查找设备中的路由表。如果到某一特定节点有一条以上的路径,则基本预先确定的路由准则是选择最优(或最经济的传输路径。由于各种网络段和其相互连接情况可能会因环境变化而变化,因此路由情况的信息一般也按所使用的路由信息协议的规定而定时更新。 主要区别:二层交换机工作在数据链路层,三层交换机工作在网络层,路由器工作在网络层。 具体区别如下:

Linux内核启动流程分析(一)

很久以前分析的,一直在电脑的一个角落,今天发现贴出来和大家分享下。由于是word直接粘过来的有点乱,敬请谅解! S3C2410 Linux 2.6.35.7启动分析(第一阶段) arm linux 内核生成过程 1. 依据arch/arm/kernel/vmlinux.lds 生成linux内核源码根目录下的vmlinux,这个vmlinux属于未压缩, 带调试信息、符号表的最初的内核,大小约23MB; 命令:arm-linux-gnu-ld -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o init/built-in.o --start-group arch/arm/mach-s3c2410/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o drivers/built-in.o net/built-in.o --end-group .tmp_kallsyms2.o 2. 将上面的vmlinux去除调试信息、注释、符号表等内容,生成arch/arm/boot/Image,这是不带多余信息的linux内核,Image的大小约 3.2MB; 命令:arm-linux-gnu-objcopy -O binary -S vmlinux arch/arm/boot/Image 3.将 arch/arm/boot/Image 用gzip -9 压缩生成arch/arm/boot/compressed/piggy.gz大小约 1.5MB;命令:gzip -f -9 < arch/arm/boot/compressed/../Image > arch/arm/boot/compressed/piggy.gz 4. 编译arch/arm/boot/compressed/piggy.S 生成arch/arm/boot/compressed/piggy.o大小约1.5MB,这里实 际上是将piggy.gz通过piggy.S编译进piggy.o文件中。而piggy.S文件仅有6行,只是包含了文件piggy.gz; 命令:arm-linux-gnu-gcc -o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/piggy.S 5. 依据arch/arm/boot/compressed/vmlinux.lds 将arch/arm/boot/compressed/目录下的文件head.o 、piggy.o 、misc.o链接生成arch/arm/boot/compressed/vmlinux,这个vmlinux是经过压缩且含有自解压代码的内核, 大小约1.5MB; 命 令:arm-linux-gnu-ld zreladdr=0x30008000 params_phys=0x30000100 -T arch/arm/boot/compressed/vmlinux.lds a rch/arm/boot/compressed/head.o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/misc.o -o arch/arm /boot/compressed/vmlinux

STP生成树的工作原理

STP生成树的工作原理 一、STP生成树的工作原理 STP的基本原理可以归纳为三步,选择根网桥RB、选择根端口RP、选择指定端口DP。然后把根端口、指定端口设为转发状态,其它接口设为阻塞状态,这样一个逻辑上无环路的网络拓扑就形成了。 1.选择根网桥 选择根网桥的依据是网桥ID,由优先级和MAC地址组成,先看优先级,优先级相同时再看MAC地址,值越小越优先选择。根网桥的选择过程与政治选举类似。 2.选择根端口 每一个非根网桥将从其接口选出一个到根网桥管理成本(ad ministrative cost)最低的接口作为根端口,选择的依据是 (1)自身到达根网桥的根路径成本最低的接口。 根路径成本的计算是,接口收到BPDU中所包含的成本与接口的成本的累加。 (2)直连网桥ID最小 (3)端口ID最小 3.选择指定端口

当一个网段中有多个网桥时,这些网桥会将他们到根网桥的管理成本都通告出去,其中具有最低管理成本的网桥将作为指定(designated)网桥。指定网桥中发送最低管理成本的BPDU的接口是该网段中的指定端口。在每段链路上,选择一个指定端口,选择的依据是: (1)发送最低根路径成本的BPDU的接口 (2)所在网桥ID最小 (3)端口ID最小 总结: 选举根端口,比较接收的BPDU 选举指定端口,比较发送的BPDU 二、STP拓扑稳定后,所以工作中的交换机接口都将处于转发或阻塞状态,生成树的工作过程如下: (1)根交换机创建成本为0的Hello BPDU,并向其所有接口转发出去

(2)邻接的非根网桥将接收的hello数据包中的成本加上接收端口的成本后,从指定端口转发出去。 (3)每经过一个hello时间周期根网桥重复步骤(1),非根网桥重复步骤(2),直到网络拓扑发生变化。 总结一下: STP拓扑稳定后,根网桥通过每2s的hello时间创建和发送helloBPDU,非根网桥通过根端口接收BPDU,并且从从指定端口转发改变后的BPDU。各交换机通过接收到得的BP DU 消息,来保持各端口状态的有效,直到拓扑发生变化。 三、网络对变化时生成树的状态

(完整版)Linux内核实验报告——实验4

Linux内核实验报告 实验题目:动态模块设计实验 实验目的: Linux 模块是一些可以独立于内核单独编译的内核函数和数据类型集合,是可增删的 内核部分。模块在内核启动时装载称为静态装载,在内核已经运行时装载称为动态装载。 模块可以扩充内核所期望的任何功能,但通常用于实现设备驱动程序。 通过本实验,将学习到动态模块的设计过程,以及Proc文件系统的部分知识。 硬件环境: Pentium(R) Dual-Core CPU T4400 @ 2.20GHz 软件环境: Ubuntu12.04 gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

内核版本:3.0.24 实验步骤: 1、代码分析 模块初始化和模块卸载的函数都类同,同时读取proc文件的函数在本次实验中没有用到,所以着重描述写驱动函数。 实验A: 在这个proc函数中只是简单得输出jiffies的数值。 实验B:遍历父进程和所有进程,依然是在proc_read中,通过以下代码片段完成功能,注意在这里,我们是通过直接向系统分配的那一个page直接写入来得到的,所以每次不同的进程访问该proc文件的时候得到的结果都不一样 遍历父进程: len += sprintf(page+len,"遍历父进程\npid\tppid\tcomm\n"); while (task != &init_task){ len += sprintf(page + len,"%d\t%d\t[%s]\n",task->pid,task->parent->pid,task->comm); task = task->parent; } 遍历所有进程,通过for_each_process(task)这个宏来遍历所有进程:

linux内核gpio操作函数解析

详解内核驱动操作GPIO引脚API函数 函数原型: void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function); unsigned int s3c2410_gpio_getcfg(unsigned int pin); void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); unsigned int s3c2410_gpio_getpin(unsigned int pin); unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change); int s3c2410_gpio_getirq(unsigned int pin); 关于函数中用到的虚拟地址到物理地址转换的变量及算法可以参考 https://www.sodocs.net/doc/1217448508.html,/hefeng330467115@126/blog/static/78205842201 0620511659/ 或https://www.sodocs.net/doc/1217448508.html,/u3/102836/showart_2065945.html 看简单led驱动程序是用到的文件及头文件可能有: linux/include/asm-arm/arch-s3c2410/map.h linux/include/asm-arm/arch-s3c2410/regs-gpio.h linux/arch/arm/plat-s3c24xx/gpio.c linux/include/asm-arm/io.h 用Source Insight 打开这些文件,然后再看驱动程序,可以随意跳转到定义处,很是方便 pin参数: gpio引脚及特殊功能寄存器助记符都在 linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义: eg: S3C2410_GPACON S3C2410_GPADAT S3C2410_GPA0 - S3C2410_GPA22 //引脚 S3C2410_GPA0_OUT - S3C2410_GPA22_OUT //设置引脚为输出 用到哪个不清楚的可以直接到这个文件去查找 还有中断和GSTATUS: S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23 …… function参数: 指定引脚功能:输出、输入还是特殊功能,也在 linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义。 函数功能: 1原型:void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int

相关主题