Linux网桥介绍

1. 介绍

关于网桥相关知识,可参考<网桥技术介绍>

我们需要了解的是网桥是一种工作在数据链路层的存储转发设备,用来连接局域网,基于MAC地址来进行端口转发。
比较常见的即透明网桥(Transparent Bridge)

1.1 功能

网桥的作用主要如下

 - 源地址跟踪:     网桥通过转发表来记录网桥所能见到的连接站点地址, 为帧的转发提供了路径选择
- 帧的转发和过滤: 网桥可以对帧进行转发或者过滤

1.2 工作原理

如下图所示,br0是一个网桥,拥有两个端口eth0和eth1
对于协议栈上层的来说,只看得到br0,因为桥接是在数据链路层实现的,上层不需要关心桥接的细节
于是协议栈上层将需要发送的报文被送到br0,网桥设备来判断报文该被转发到eth0或是eth1,或者两者皆是;
反过来,从eth0或从eth1接收到的报文被提交给网桥来处理
在这里会判断报文该转发、丢弃、或提交到协议栈上层

而有时候eth0、eth1也可能会作为报文的源地址或目的地址,直接参与报文的发送与接收(从而绕过网桥)。

bridge

 

2. 实现

2.1 数据结构

在Linux中,网桥的主要数据结构有

 - net_bridge:           表示网桥
- net_bridge_port: 则表示网桥中的某个端口, 一般都是某个物理接口
- net_bridge_fdb_entry: 保存了MAC地址->端口映射对(hash表), 以数组的方式存储在net_bridge结构中

数据结构之间的关系如下图所示

data-relation 

2.2 数据处理

在v2.6.36以前, 网桥对于数据包的处理过程是通过直接调用hook函数br_handle_frame_hook()来进行

在v2.6.36以后,不再是使用hook函数的方式,而是以注册事件的方式netdev_rx_handler_register()
对不同设备的rx处理进行注册,在netif_receive_skb函数处理过程中,会将该设备的所有事件函数一一调用
而网桥端口注册的处理函数正是br_handle_frame()

故实际上网桥数据的处理入口点就是br_handle_frame()函数

br_handle_frame主要流程如下

1. 首先进行一些的检查
2. 判断是否本地链路保留地址,满足调用br_handle_local_finish()简单更新转发表就结束处理
3. 而对于非特殊链路地址,根据端口的状态决定对数据的处理(如下),最后调用br_handle_frame_finish()
   - LEARNING:   只是简单更新转发表,就丢弃报文。  
   - FORWARDING: 进行ebtables hook处理

br_handle_frame_finish()会判断数据的目的地,对于发往本地的地址调用br_pass_frame_up();需要转发的数据则通过br_forward()来完全网桥转发
注意:br_pass_frame_up()会再次调用netif_receive_skb(),但是此时不会再进入网桥处理,而是直接进行协议栈进行处理(因为此时skb->dev已经不是网卡设备了,而是网桥设备)

 

3. 使用

网桥在用户空间的工具室是通过bridge-util软件包,它提供了brctl命令来完成对网桥的使用

一个电脑上有四个网卡,下面我们把这四个端口加入到同一个桥中

首先新建一个网桥br0

# brctl addbr br0

将四个物理网卡加入网桥br0作为端口

# brctl addif br0 eth0
# brctl addif br0 eth1
# brctl addif br0 eth2
# brctl addif br0 eth3

网桥的每个物理网卡作为一个端口,运行于混杂模式,而且是在链路层工作,所以就不需要IP了

# ifconfig eth0 0.0.0.0
# ifconfig eth1 0.0.0.0
# ifconfig eth2 0.0.0.0
# ifconfig eth3 0.0.0.0

然后给br0的虚拟网卡配置IP:192.168.1.1

# ifconfig br0 192.168.1.1

参考
<Linux网桥的实现分析与使用>

posted @ 2013-08-14 19:48  北落不吉  阅读(3486)  评论(0编辑  收藏  举报