Linux下的Bridge也是一种虚拟设备,这多少和vlan有点相似,它依赖于一个或多个从设备。与VLAN不同的是,它不是虚拟出和从设备同一层次的镜像设备,而是虚拟出一个高一层次的设备,并把从设备虚拟化为端口port,且同时处理各个从设备的数据收发及转发,再加上netfilter框架的一些东西,使得它的实现相比vlan复杂得多。
1.Bridge的功能框图
它是Linux下虚拟出来bridge设备,Linux下可用brctl命令创建br设备,如下
brctl addbr brname
然后添加port,并进行相应配置,就可以使用了
brctl addif brname eth0
brctl addif brname eth1
ifconfig brname IP up
ifconfig eth0 0.0.0.0 up
ifconfig eth1 0.0.0.0 up
可见br设备是建立在从设备之上的(这些从设备可以是实际设备,也可以是vlan设备等),并且可以为br准备一个IP(br设备的MAC地址是它所有从设备中最小的MAC地址),这样该主机就可以通过这个br设备与网络中的其它主机通信了(详见发送功能框图)。
另外它的从设备被虚拟化为端口port,它们的IP及MAC都不再可用,且它们被设置为接收任何包,最终由bridge设备来决定数据包的去向:接收到本机、转发、丢弃(详见接收功能框图)。
发送功能 接收功能
简单的数据结构框图如下所示。
2.Bridge设备的创建
和Vlan一样,bridge也被当成一个module加载进内核,它的module_init()函数和vlan差不多,进行一些namespace的注册,特殊的是它还注册了一个netfilter_ops,在内核全局的HOOK函数表中增加了7个函数,其中5个的pf=Bridge,另两个的pf分别为INET、INET6,它们主要用于bridge中的netfilter操作(后面会细讲)。
最后,也是我们这最关心的是,它注册了一个ioctl函数br_ioctl_deviceless_stub(),该ioctl函数和vlan的一样,都会作为sock_ioctl()的特殊情况被调用。映射到应用层,它应该是对某个socket插口进行ioctl操作,详见brctl源码。该ioctl函数中最主要的就是br_add_bridge(net,buf),用于创建bridge设备,如下图所示:
该函数调用netdev_alloc(),申请net_device(),并分配私有空间net_bridge()结构,指明初始化函数为br_dev_setup(),最后register_netdev()把该设备组册进内核,可见bridge设备和一般的设备差不多。
主要看其中br_dev_setup(),首先初始化设备的type、flags为bridge,然后最关键的是设置其dev->netdev_ops = br_netdev_ops,即内核为bridge设备准备好了一套通用的驱动函数,这个直接关系到bridge的工作方法,后面再细讲。然后初始化私有空间net_bridge()结构,设置bridge的本地设备及从设备的list(当然这是还没有从设备加进来),然后设置了桥的group_address,即上一节所说的特殊的MAC地址,最后还初始化了timer相关的。
这时bridge还不完整,还需添加port从设备,由命令brctl addif brname portdev完成,但要注意,虽然还是brctl命令,但此时的操作对象是已经存在的bridge设备,映射到内核中就是br_netdev_ops->ioctl()中的br_add_if()(它是br设备的ioctl操作,和之前那个sock_ioctl的分支不是一个层次上的)。至于怎么从应用层直接操作底层的net_device设备的,可以参见brctl源码,以后再看吧,先看看这里的br_add_if(),如下图:
首先判断dev从设备必须不是loopback,不是bridge,不是其他bridge的port,且要是ethernet设备,才能继续;然后根据br、dev选择一个index号,并分配一个新的net_bridge_port结构,初始化之,并将它加入bridge的port_list中;最后br的一些物理参数,其MAC地址为所有从设备中MAC最小的(由上一节知,从设备被设置成全接收模式,其IP和MAC都没有了),且其MTU也为所有从设备中最小的。
上面设置br的相关参数,下面还要设置从设备,首先使dev->master=br_dev(实际上就是构成上一节数据结构中的索引关系);然后设置dev->prive_flags加上IFF_BRIDGE_PORT,这样它就不能再作为其他br的从设备了;最后也是最关键的,设置dev->rx_handler为br_handler_frame(),为数据接收作准备。
3.Bridge设备的发送流程
前面也讲过了,Linux下的bridge设备,对下层而言是一个桥设备,进行数据的转发(实际上对下也有接收能力,下一节讲)。而对上层而言,它就像普通的ethernet设备一样,有自己的IP和MAC地址,那么上层当然可以把它加入路由系统,并利用它发送数据啦,并且很容易想到,它的发射函数最终肯定是利用某个从设备的驱动去完成实际的发送的,这个和VLAN是相通的。具体看代码:
上层根据目的IP地址,路由选择了该br_dev设备发送,并且由ARP缓存中得到了对应的目的MAC,填写在了skb中,然后启动了发送流程dev_queue_xmit(skb)。因为此时的skb->dev为br_dev,无queue,直接去调用br设备的发送函数,该函数就是br_netdev_ops中定义的br_dev_xmit(skb,br_dev)。
该函数首先根据目的MAC地址,确定是广播还是单播,这里仅讨论单播时,根据DMAC在net_bridge的fdb_hash中找到相应的net_bridge_fdb_entry项,并索引到对应的端口net_bridge_port。最后利用该端口的从设备来发送数据,注意,这里是直接调用dev->ops->ndo_start_xmit(skb,dev)的,一放面这里的dev已经是从设备了,另一方面,这里没有像VLAN中那样重定位skb->dev,并重启发送流程dev_queue_xmit(),是因为一个从设备只能作为一个bridge的port,没有其它身份,不存在竞争问题。
4.Bridge设备的接收流程
和VLAN一样,实际接收由硬件设备完成,最终通过netif_receive_skb(skb)函数提交给上层,而在该函数中会处理vlan、bridge这类特殊设备。与LVAN的仅是把skb设备重定位以实现对上层透明的要求不同,Bridge接受过程复杂得多,因此专门注册了一个函数来处理,即前面提到的rx_handler(),它被注册在port设备的net_device结构中(这算是port设备失去自身IP、MAC的一个补偿吧J),如下图所示。只有作为bridge的从设备才会注册rx_handler(),并在这里执行,处理桥接,普通的设备不会执行到这里。
这里两种典型的返回值是RX_CONSUMED、RX_PASS,后者表示处理了一下回来,继续之前的流程,实际上就是对应的接收功能框图中的第一种情况;前者表示该skb已不再属于这个从设备了,而是被提交给了br设备,所以本次netif_receive_skb()就不用管啦,直接goto out,这里还要再分两种情况,一是转发的,这时br就真的充当了桥的角色,二是由br提交给上层的,这时br充当的是一个以太网设备,如前面所述。
要处理这么多情况,代码需设计得很巧妙,这里的rx_handler被设置为br_handle_frame(**pskb),看具体代码:
功能框架清楚了,代码流程就清楚了,就不细看了,有几个注意的地方:一是bridge的端口处于FORWARD或LEARNING状态没多大区别,只是FORWARD要多执行一个二层防火墙,所有用了一个中间没有break的switch结构;二是要时刻记着,bridge本身除了有转发端口外,自己也是一个设备,广播(多播)时也要发一份给自己,且是以br_dev的身份递交上层;三是所有的HOOK函数都会比较复杂,因为内核的netfilter框架建立在网络层,而bridge在链路层就转发了,相当于跳过了netfilter,所以在这些hook中都会去调用INET域的hook函数。
5.小结
通过对Bridge和vlan的学习,了解了网络栈底层的工作方式,发送这个主动过程相对简单,而接收过程则相对复杂,用到BH模型,NAPI等。
Vlan和bridge功能有所不同,但相似处很多,更重要的是:它们都对上层透明,所以不会牵扯到协议域的问题。
http://www.cnblogs.com/zmkeil/archive/2013/04/21/3034733.html
相关推荐
Linux内核中的Bridge技术是网络连接的关键组成部分,它在虚拟化环境和多接口通信中扮演着重要角色。本文将深入浅析Linux内核bridge的工作原理、功能及其在实际应用中的重要性。 首先,Linux桥接功能是Linux内核提供...
Linux内核通过创建一个虚拟的网桥设备(例如br0)来实现不同网络接口之间的桥接。这种桥接发生在数据链路层,对网络协议栈的上层透明。例如,当报文需要发送时,协议栈上层只需将报文发送到br0,由网桥处理代码负责...
它允许用户将多个网络接口(如以太网卡)连接在一起,形成一个逻辑上的单一网络接口,从而实现不同网络之间的通信或者创建虚拟网络环境。这种技术在服务器集群、虚拟化环境以及某些特定的网络配置中非常常见。 首先...
Linux 下 KVM 虚拟化环境部署和使用 KVM(Kernel-based Virtual Machine)是 Linux 内核虚拟化解决方案,提供了一个基于硬件的虚拟化环境。下面是 KVM 虚拟化环境的安装、搭建和使用方法: 一、环境要求 * 操作...
Linux Bridge 是 Linux 操作系统内建的一种虚拟网络设备,它允许在没有物理交换机的情况下创建一个虚拟的二层网络环境。在 OpenStack 的 Neutron 服务中,Linux Bridge 可以作为机制驱动(mechanism driver)来实现...
在μClinux环境下实现虚拟局域网(VLAN)是一项技术挑战,因为它涉及到对操作系统、硬件设备以及网络配置的深入理解。μClinux是一种轻量级的Linux发行版,特别适用于资源有限的嵌入式系统,如基于ARM架构的处理器。...
KVM(Kernel-based Virtual Machine)是一种开源的系统虚拟化模块,自 Linux 2.6.20 版本以后集成在 Linux 的主要发行版本中。KVM 使用 Linux 自身的调度器进行管理,因此相比 Xen,其核心源码很少。 KVM 的虚拟化...
标题中的"CP210x USB to UART Bridge VCP Drivers Linux.zip"指的是为Linux系统编写的CP210x USB转UART桥接器虚拟串口(VCP)驱动程序。这个压缩包包含了使Linux系统能够识别和通信通过USB接口与CP210x芯片进行UART...
Linux Bridge 和 VLAN 的结合实现了虚拟交换机的功能。Linux Bridge 实现了交换功能,而 VLAN 设备实现了隔离功能。通过将同一 VLAN 的子设备都挂载到一个 Bridge 上,设备之间就可以交换数据了。这样,Linux Bridge...
Linux Bridge在OpenStack网络中扮演了虚拟交换机的角色,它用于连接多个虚拟网络接口,实现不同网络间的数据转发。在VXLAN网络中,Linux Bridge将数据包封装到VXLAN报文中,并通过配置的物理网卡进行传输。 7. ...
Linux虚拟网络的核心是对二层物理网络的抽象和管理,它能够模拟物理网络卡和交换设备,实现虚拟化。在Linux系统中,常见的虚拟网络设备模型包括Bridge(桥接)、TAP(传输适配器)和VLAN(虚拟局域网)。Bridge可以...
虚拟交换技术在Linux操作系统中扮演着重要角色,它们是实现虚拟网络环境的关键组件,允许虚拟机与物理网络或其他虚拟机进行通信。在Linux系统中,主要有三种虚拟交换技术:bridge(网桥)、macvlan和Open vSwitch。...
本教程主要聚焦于在虚拟环境中配置Linux系统,特别是Red Hat Linux 9版本,以便于用户可以在虚拟机上实现网络连接。虚拟机允许我们在一台主机上运行多个独立的操作系统实例,而无需物理硬件的额外开销,这在开发、...
linux虚拟网络设备:veth、tap、tun、bridge
在 Neutron 中,Linux Bridge 是一种常用的网络模式,用于提供网络虚拟化和多租户隔离。 在本文中,我们将讨论 OpenStack 使用 Linux Bridge+VXLAN 模式的网络变化与分析。VXLAN(Virtual Extensible LAN)是一种-...
本文将深入探讨Linux网桥的实现原理、配置方法以及使用场景,帮助读者全面理解这一强大的功能。 一、Linux网桥的基本概念 Linux内核自2.2版本起内置了网桥功能,它通过软件实现了一种类似硬件网桥的机制,可以在多...