网桥转发的原理.docx
- 文档编号:25118957
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:31
- 大小:189.72KB
网桥转发的原理.docx
《网桥转发的原理.docx》由会员分享,可在线阅读,更多相关《网桥转发的原理.docx(31页珍藏版)》请在冰豆网上搜索。
网桥转发的原理
网桥的基本工作原理
数据链路层互联的设备是网桥(bridge),在网络互联中它起到数据接收、地址过滤与数据转发的作用,用来实现多个网络系统之间的数据交换。
网桥的基本特征
1.网桥在数据链路层上实现局域网互连;
2.网桥能够互连两个采用不同数据链路层协议、不同传输介质与不同传输速率的网络;
3.网桥以接收、存储、地址过滤与转发的方式实现互连的网络之间的通信;
4.网桥需要互连的网络在数据链路层以上采用相同的协议;
5.网桥可以分隔两个网络之间的广播通信量,有利于改善互连网络的性能与安全性。
网桥的工作过程
网桥最常见的用法是用于连接两个局域网,下图给出了两个局域网通过网桥互联的工作原理。
网桥的基本分类
网桥按照其路由表的建立方法分为两类
--透明网桥(transparentbridge)
--源路选网桥(sourceroutingbridge)
透明网桥的主要特点
透明网桥由各个网桥自己来决定路由选择,局域网上的各结点不负责路由选择,网桥对于互连局域网的各结点来说是“透明”的;
透明网桥一般用在两个使用同样的MAC层协议的网段之间的互连。
例如连接两个Ethernet网段,或两个令牌环网;
透明网桥的最大优点是容易安装,是一种即插即用设备。
Linux-网桥原理分析
(一)
时间:
2010-11-1512:
00:
56来源:
网络 作者:
未知 点击:
293次
目 录
1..... 前言
2 网桥的原理
2.1 桥接的概念
2.2 linux的桥接实现
2.3 网桥的功能
3 网桥的配置
4 网桥的实现
4.1 初始化
4.2 新建网桥
目录
1.....前言
2 网桥的原理
2.1 桥接的概念
2.2 linux的桥接实现
2.3 网桥的功能
3 网桥的配置
4 网桥的实现
4.1 初始化
4.2 新建网桥
4.3 添加删除端口
5 网桥数据结构
6 网桥数据库的维护
6.1 数据库的创建和销毁
6.2 数据库更新
6.3 创建数据项
6.4 查找数据项
6.5 MAC地址过期清理
7 网桥数据包的处理流程
7.1 netif_receive_skb
7.2 Br_handle_frame
7.3 Br_handle_frame_finish
7.4 Br_pass_frame_up
7.5 Br_forward
7.6 __br_forward
7.7 Br_forward_finish
7.8 Br_dev_queue_push_xmit
8.....参考文献
1前言
本文的参考分析的源代码版本是2.6.15,我是边学习边总结,学习的过程中得益于Linux论坛(
由于自身水平有限,且相关的参考资料较少,因此其中的结论不能保证完全正确,如果在阅读本文的过程中发现了问题欢迎及时与作者联系。
也希望能有机会和大家多多交流学习心得!
2网桥的原理
2.1 桥接的概念
简单来说,桥接就是把一台机器上的若干个网络接口“连接”起来。
其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。
以使得网口之间的报文能够互相转发。
交换机就是这样一个设备,它有若干个网口,并且这些网口是桥接起来的。
于是,与交换机相连的若干主机就能够通过交换机的报文转发而互相通信。
如下图:
主机A发送的报文被送到交换机S1的eth0口,由于eth0与eth1、eth2桥接在一起,故而报文被复制到eth1和eth2,并且发送出去,然后被主机B和交换机S2接收到。
而S2又会将报文转发给主机C、D。
交换机在报文转发的过程中并不会篡改报文数据,只是做原样复制。
然而桥接却并不是在物理层实现的,而是在数据链路层。
交换机能够理解数据链路层的报文,所以实际上桥接却又不是单纯的报文转发。
交换机会关心填写在报文的数据链路层头部中的Mac地址信息(包括源地址和目的地址),以便了解每个Mac地址所代表的主机都在什么位置(与本交换机的哪个网口相连)。
在报文转发时,交换机就只需要向特定的网口转发即可,从而避免不必要的网络交互。
这个就是交换机的“地址学习”。
但是如果交换机遇到一个自己未学习到的地址,就不会知道这个报文应该从哪个网口转发,则只好将报文转发给所有网口(接收报文的那个网口除外)。
比如主机C向主机A发送一个报文,报文来到了交换机S1的eth2网口上。
假设S1刚刚启动,还没有学习到任何地址,则它会将报文转发给eth0和eth1。
同时,S1会根据报文的源Mac地址,记录下“主机C是通过eth2网口接入的”。
于是当主机A向C发送报文时,S1只需要将报文转发到eth2网口即可。
而当主机D向C发送报文时,假设交换机S2将报文转发到了S1的eth2网口(实际上S2也多半会因为地址学习而不这么做),则S1会直接将报文丢弃而不做转发(因为主机C就是从eth2接入的)。
然而,网络拓扑不可能是永不改变的。
假设我们将主机B和主机C换个位置,当主机C发出报文时(不管发给谁),交换机S1的eth1口收到报文,于是交换机S1会更新其学习到的地址,将原来的“主机C是通过eth2网口接入的”改为“主机C是通过eth1网口接入的”。
但是如果主机C一直不发送报文呢?
S1将一直认为“主机C是通过eth2网口接入的”,于是将其他主机发送给C的报文都从eth2转发出去,结果报文就发丢了。
所以交换机的地址学习需要有超时策略。
对于交换机S1来说,如果距离最后一次收到主机C的报文已经过去一定时间了(默认为5分钟),则S1需要忘记“主机C是通过eth2网口接入的”这件事情。
这样一来,发往主机C的报文又会被转发到所有网口上去,而其中从eth1转发出去的报文将被主机C收到。
2.2 linux的桥接实现
linux内核支持网口的桥接(目前只支持以太网接口)。
但是与单纯的交换机不同,交换机只是一个二层设备,对于接收到的报文,要么转发、要么丢弃。
小型的交换机里面只需要一块交换芯片即可,并不需要CPU。
而运行着linux内核的机器本身就是一台主机,有可能就是网络报文的目的地。
其收到的报文除了转发和丢弃,还可能被送到网络协议栈的上层(网络层),从而被自己消化。
linux内核是通过一个虚拟的网桥设备来实现桥接的。
这个虚拟设备可以绑定若干个以太网接口设备,从而将它们桥接起来。
如下图(摘自ULNI):
网桥设备br0绑定了eth0和eth1。
对于网络协议栈的上层来说,只看得到br0,因为桥接是在数据链路层实现的,上层不需要关心桥接的细节。
于是协议栈上层需要发送的报文被送到br0,网桥设备的处理代码再来判断报文该被转发到eth0或是eth1,或者两者皆是;反过来,从eth0或从eth1接收到的报文被提交给网桥的处理代码,在这里会判断报文该转发、丢弃、或提交到协议栈上层。
而有时候eth0、eth1也可能会作为报文的源地址或目的地址,直接参与报文的发送与接收(从而绕过网桥)。
2.3 网桥的功能
概括来说,网桥实现最重要的两点:
1.MAC学习:
学习MAC地址,起初,网桥是没有任何地址与端口的对应关系的,它发送数据,还是得想HUB一样,但是每发送一个数据,它都会关心数据包的来源MAC是从自己的哪个端口来的,由于学习,建立地址-端口的对照表(CAM表)。
2.报文转发:
每发送一个数据包,网桥都会提取其目的MAC地址,从自己的地址-端口对照表(CAM表)中查找由哪个端口把数据包发送出去。
3网桥的配置
在Linux里面使用网桥非常简单,仅需要做两件事情就可以配置了。
其一是在编译内核里把CONFIG_BRIDGE或CONDIG_BRIDGE_MODULE编译选项打开;其二是安装brctl工具。
第一步是使内核协议栈支持网桥,第二步是安装用户空间工具,通过一系列的ioctl调用来配置网桥。
下面以一个相对简单的实例来贯穿全文,以便分析代码。
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地址分配在同一个网段。
Linux-网桥原理分析
(二)
时间:
2010-11-1512:
04:
25来源:
网络 作者:
未知 点击:
152次
4 网桥的实现
在内核,网桥是以模块的方式存在,注册源码路径:
et\brige\br.c:
4网桥的实现
在内核,网桥是以模块的方式存在,注册源码路径:
et\brige\br.c:
4.1初始化
staticint__initbr_init(void)
{
br_fdb_init();//网桥数据库初始化,分配slab缓冲区
#ifdefCONFIG_BRIDGE_NETFILTER
if(br_netfilter_init())//netfilter钩子初始化
return1;
#endif
brioctl_set(br_ioctl_deviceless_stub);//设置ioctl钩子函数:
br_ioctl_hook
br_handle_frame_hook=br_handle_frame;//设置报文处理钩子:
br_ioctl_hook
//网桥数据库处理钩子
br_fdb_get_hook=br_fdb_get;
br_fdb_put_hook=br_fdb_put;
//在netdev_chain通知链表上注册
register_netdevice_notifier(&br_device_notifier);
return0;
}
4.2新建网桥
前面说到通过brctladdbrbr0命令建立网桥,此处用户控件调用的brctl命令最终对应到内核中的br_ioctl_deviceless_stub处理函数:
intbr_ioctl_deviceless_stub(unsignedintcmd,void__user*uarg)
{
switch(cmd){
caseSIOCGIFBR:
caseSIOCSIFBR:
returnold_deviceless(uarg);
caseSIOCBRADDBR:
//新建网桥
caseSIOCBRDELBR:
//删除网桥
{
charbuf[IFNAMSIZ];
if(!
capable(CAP_NET_ADMIN))
return-EPERM;
//copy_from_user:
把用户空间的数据拷入内核空间
if(copy_from_user(buf,uarg,IFNAMSIZ))
return-EFAULT;
buf[IFNAMSIZ-1]=0;
if(cmd==SIOCBRADDBR)
returnbr_add_bridge(buf);
returnbr_del_bridge(buf);
}
}
return-EOPNOTSUPP;
}
在这里,我们传入的cmd为SIOCBRADDBR.转入br_add_bridge(buf)中进行:
intbr_add_bridge(constchar*name)
{
structnet_device*dev;
intret;
//为虚拟桥新建一个net_device
dev=new_bridge_dev(name);
if(!
dev)
return-ENOMEM;
rtnl_lock();
//由内核确定接口名字,例如eth0eth1等
if(strchr(dev->name,'%')){
ret=dev_alloc_name(dev,dev->name);
if(ret<0)
gotoerr1;
}
//向内核注册此网络设备
ret=register_netdevice(dev);
if(ret)
gotoerr2;
/*networkdevicekobjectisnotsetupuntil
*afterrtnl_unlockdoesit'shotplugmagic.
*soholdreferencetoavoidrace.
*/
dev_hold(dev);
rtnl_unlock();
//在sysfs中建立相关信息
ret=br_sysfs_addbr(dev);
dev_put(dev);
if(ret)
unregister_netdev(dev);
out:
returnret;
err2:
free_netdev(dev);
err1:
rtnl_unlock();
gotoout;
}
网桥是一个虚拟的设备,它的注册跟实际的物理网络设备注册是一样的。
我们关心的是网桥对应的net_device结构是什么样的,继续跟踪进new_bridge_dev:
staticstructnet_device*new_bridge_dev(constchar*name)
{
structnet_bridge*br;
structnet_device*dev;
//分配net_device
dev=alloc_netdev(sizeof(structnet_bridge),name,
br_dev_setup);
if(!
dev)
returnNULL;
//网桥的私区结构为net_bridge
br=netdev_priv(dev);
//私区结构中的dev字段指向设备本身
br->dev=dev;
spin_lock_init(&br->lock);
//队列初始化。
在port_list中保存了这个桥上的端口列表
INIT_LIST_HEAD(&br->port_list);
spin_lock_init(&br->hash_lock);
//下面这部份代码跟stp协议相关,我们暂不关心
br->bridge_id.prio[0]=0x80;
br->bridge_id.prio[1]=0x00;
memset(br->bridge_id.addr,0,ETH_ALEN);
br->stp_enabled=0;
br->designated_root=br->bridge_id;
br->root_path_cost=0;
br->root_port=0;
br->bridge_max_age=br->max_age=20*HZ;
br->bridge_hello_time=br->hello_time=2*HZ;
br->bridge_forward_delay=br->forward_delay=15*HZ;
br->topology_change=0;
br->topology_change_detected=0;
br->ageing_time=300*HZ;
INIT_LIST_HEAD(&br->age_list);
br_stp_timer_init(br);
returndev;
}
在br_dev_setup中还做了一些另外在函数指针初始化:
voidbr_dev_setup(structnet_device*dev)
{
//将桥的MAC地址设为零
memset(dev->dev_addr,0,ETH_ALEN);
//初始化dev的部分函数指针,因为目前网桥设备主适用于以及网,
//以太网的部分功能对它也适用
ether_setup(dev);
//设置设备的ioctl函数为br_dev_ioctl
dev->do_ioctl=br_dev_ioctl;
//网桥与一般网卡不同,网桥统一统计它的数据包和字节数等信息
dev->get_stats=br_dev_get_stats;
//网桥接口的数据包发送函数,真实设备要向外发送数据时,是通过网卡向外发送数据
//而该网桥设备要向外发送数据时,它的处理逻辑与网桥其它接口的基本一致。
dev->hard_start_xmit=br_dev_xmit;
dev->open=br_dev_open;
dev->set_multicast_list=br_dev_set_multicast_list;
dev->change_mtu=br_change_mtu;
dev->destructor=free_netdev;
SET_MODULE_OWNER(dev);
dev->stop=br_dev_stop;
dev->tx_queue_len=0;
dev->set_mac_address=NULL;
dev->priv_flags=IFF_EBRIDGE;
}
4.3 添加删除端口
仅仅创建网桥,还是不够的。
实际应用中的网桥需要添加实际的端口(即物理接口),如例子中的eth1,eth2等。
应用程序在使用ioctl来为网桥增加物理接口,对应内核函数br_dev_ioctl的代码和分析如下:
intbr_dev_ioctl(structnet_device*dev,structifreq*rq,intcmd)
{
structnet_bridge*br=netdev_priv(dev);
switch(cmd){
caseSIOCDEVPRIVATE:
returnold_dev_ioctl(dev,rq,cmd);
caseSIOCBRADDIF:
//添加
caseSIOCBRDELIF:
//删除
//同一处理函数,默认为添加
returnadd_del_if(br,rq->ifr_ifindex,cmd==SIOCBRADDIF);
}
pr_debug("Bridgedoesnotsupportioctl0x%x",cmd);
return-EOPNOTSUPP;
}
下面分析具体的添加删除函数add_del_if:
staticintadd_del_if(structnet_bridge*br,intifindex,intisadd)
{
structnet_device*dev;
intret;
if(!
capable(CAP_NET_ADMIN))
return-EPERM;
dev=dev_get_by_index(ifindex);
if(dev==NULL)
return-EINVAL;
if(isadd)
ret=br_add_if(br,dev);
else
ret=br_del_if(br,dev);
dev_put(dev);
returnret;
}
对应的添加删除函数分别为:
br_add_if,br_del_if;
br_add_if:
intbr_add_if(structnet_bridge*br,structnet_device*dev)
{
structnet_bridge_port*p;
interr=0;
/*--Kernel仅支持以太网网桥--*/
if(dev->flags&IFF_LOOPBACK||dev->type!
=ARPHRD_ETHER)
return-EINVAL;
/*--把网桥接口当作物理接口加入到另一个网桥中,是不行的,
逻辑和代码上都会出现loop--*/
if(dev->hard_start_xmit==br_dev_xmit)
return-EL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 转发 原理