竭诚为您提供优质文档/双击可除linux,ip协议栈,虚拟网络接口
篇一:linux虚拟网桥
linux内核是通过一个虚拟的网桥设备来实现桥接的。这个虚拟设备可以绑定若干个以太网接口设备,从而将它们桥接起来。如下图(摘自ulni):
网桥设备br0绑定了eth0和eth1。对于网络协议栈的上层来说,只看得到br0,因为桥接是在数据链路层实现的,上层不需要关心桥接的细节。于是协议栈上层需要发送的报文被送到br0,网桥设备的处理代码再来判断报文该被转发到eth0或是eth1,或者两者皆是;反过来,从eth0或从eth1接收到的报文被提交给网桥的处理代码,在这里会判断报文该转发、丢弃、或提交到协议栈上层。
而有时候eth0、eth1也可能会作为报文的源地址或目的地址,直接参与报文的发送与接收(从而绕过网桥)。
网桥的配置
在linux里面使用网桥非常简单,仅需要做两件事情就
可以配置了。其一是在编译内核里把conFig_bRidge或condig_bRidge_module编译选项打开;其二是安装brctl工具。第一步是使内核协议栈支持网桥,第二步是安装用户空间工具,通过一系列的ioctl(linux,ip协议栈,虚拟网络接口)调用来配置网桥。下面以一个相对简单的实例来贯穿全文,以便分析代码。
linux机器有4个网卡,分别是eth0~eth4,其中eth0用于连接外网,而eth1,eth2,eth3都连接到一台pc机,用于配置网桥。只需要用下面的命令就可以完成网桥的配置:brctladdbrbr0(建立一个网桥br0,同时在linux内核里面创建虚拟网卡br0)brctladdifbr0eth1
brctladdifbr0eth2
brctladdifbr0eth3(分别为网桥br0添加接口
eth1,eth2和eth3)
其中br0作为一个网桥,同时也是虚拟的网络设备,它即可以用作网桥的管理端口,也可作为网桥所连接局域网的网关,具体情况视你的需求而定。要使用br0接口时,必需为它分配ip地址。为正常工作,pc1,pc2,pc3和br0的ip 地址分配在同一个网段。
篇二:linuxtcpip协议栈分析
sk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。它在中定义,并
包含很多成员变量供网络代码中的各子系统使用。
这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的成员变量以使得成员变量的布局更加清晰。它的成员变量可以大致分为以下几类:
layout布局
general通用
Feature-specific功能相关
managementfunctions管理函数
这个结构被不同的网络层(mac或者其他二层链路协议,三层的ip,四层的tcp或udp等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。l4向l3传递前会添加一个l4的头部,同样,l3向l2传递前,会添加一个l3的头部。添加头部比在不同层之间拷贝数据的效率更高。由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数
skb_reserve(在后面的章节中描述)来完成这个功能。协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。
skb_reserve同样被设备驱动使用来对齐接收到包的包头。如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。例如,l2的头部只有在网络驱动处理l2的协
议时有用,l3是不会关心它的信息的。但是,内核并没有把l2的头部从缓冲区中删除,而是把有效荷载的指针指向l3的头部,这样做,可以节省cpu时间。
1.网络参数和内核数据结构
就像你在浏览tcp/ip规范或者配置内核时所看到的一样,网络代码提供了很多有用的功能,但是这些功能并不是必须的,比如说,防火墙,多播,还有其他一些功能。大部分的功能都需要在内核数据结构中添加自己的成员变量。因此,sk_buff里面包含了很多像#ifdef这样的预编译指令。例如,在sk_buff结构的最后,你可以找到:
structsk_buff{
.........
#ifdefconFig_net_sched
__u32tc_index;
#ifdefconFig_net_cls_act
__u32tc_verd;
__u32tc_classid;
#endif
#endif
}
它表明,tc_index只有在编译时定义了
conFig_net_sched符号才有效。这个符号可以通过选择特定
的编译选项来定义(例如:"devicedriversnetworkingsupportnetworkingoptionsqos and/or
fairqueueing")。这些编译选项可以由管理员通过makeconfig来选择,或者通过一些自动安装工具来选择。
前面的例子有两个嵌套的选项:conFig_net_cls_act (包分类器)只有在选择支持“qosand/orfairqueueing”时才能生效。
顺便提一下,qos选项不能被编译成内核模块。原因就是,内核编译之后,由某个选项所控制的数据结构是不能动态变化的。一般来说,如果某个选项会修改内核数据结构(比如说,在sk_buff
里面增加一个项tc_index),那么,包含这个选项的组件就不能被编译成内核模块。
你可能经常需要查找是哪个makeconfig编译选项或者变种定义了某个#ifdef标记,以便理解内核中包含的某段代码。在2.6内核中,最快的,查找它们之间关联关系的方法,就是查找分布在内核源代码树中的kconfig文件中是否定义了相应的符号(每个目录都有一个这样的文件)。在
2.4内核中,你需要查看
documentation/configure.help文件。
youtFields