Linux实现的IEEE 802 1Q VLAN
第一部分:VLAN的核心概念
说起IEEE 802.1q与VLAN的关系时大家都知道二者是密切相关的;提及VLAN这一概念即便是网络基础较为薄弱的人都能清楚明白地阐述其含义。然而说到实际操作尤其是针对Cisco或H3C等主流厂商设备的配置虽然大多数人都能在出口令时游刃有余但在面对基于Linux系统的VLAN配置却常常会遇到诸多困惑与不解的问题。这些问题之所以存在我认为主要源于两个方面的不足:一是缺乏对VLAN本质的理解;二是对基于Linux环境下的虚拟网络设备实现方式尚不够熟悉。
或许你已经深入掌握了802.1q的技术细节,并且研读过相关的文献资料;然而对于Linux平台下的桥接设备(Bridge)、端口转发器(tap)以及数据链路聚合(bond)等虚拟网络接口却不甚了解;这样一来就导致无法有效地配置VLAN网络。
对于VLAN概念的理解,请重点强调以下几点:
1.VLAN划分了广播域;
2.单独的一个VLAN模拟了一个常规的交换以太网网络架构;因此VLAN将一个物理交换机分割成了一个或多个逻辑交换机;
3.不同VLAN之间通信需要经过三层参与;
4.当多台交换机级联时;VLAN通过VID来识别该ID并插入到标准的以太帧中;这种机制被称为tag;
5.大多数情况下;tag并不是端到端的数据传输的一部分;通常是在数据帧下行链路的第一个VLAN交换机打上tag;而上行路上最后一个VLAN交换机会去除tag;
6.只有当一个数据帧不带tag时才无法确定其所属哪个VLAN才会打上tag;应该尽早地去除不必要的tag以减少不必要的开销;
7.IEEE 802.1q解决了VLAN中的tag问题。然而需要注意的是除了IEEE 802.1q之外其他实现方式并不完全相同;尽管Cisco H3C等厂商在实现上有许多相似之处但Linux系统与它们之间存在显著差异
1.每一个VLAN交换机端口需要绑定一个VLAN id;
2.每一个VLAN交换机端口处于下面三类中的一类:access,trunk,hybrid。
此类端口接收到的数据包均为无标签状态;此类端口发送出去的所有数据块也未附加任何标签。
2.2.trunck端口:该类端口接收的数据帧均需附加标签;而该类端口发送的数据帧也需附加标签(仅在非缺省VLAN情境下适用);
2.3.hybrid端口:略
实际上没有必要深入探讨Cisco/H3C设备上的命令细节以及其中涉及的三层端口分类问题。这种三分类的设计初衷是为了方便应用IEEE 802.1q标准来划分VLAN(即最终的IEEE 802.1q标准)。简单来说,trunk接口的存在是无奈之举,因为当多个VLAN的数据帧需要通过同一条物理链路传输时,仅仅依靠数据包标签无法区分各自的归属,因此必须引入这个标准以实现精确分组。为了使这一理论得以实际应用,厂商们开发了一系列相关的概念工具,例如带有标签的链路被称为trunk链路等。
明白了之后,我们就可以完全抛开具体的配置命令以及厂商定义的技术细节,直接依据IEEE 802.1q标准来进行VLAN配置设计了。这样一来,你完全可以在Linux系统上实现任意VLAN配置方案。
首先我们需要明确我们的配置目标以及对应的网络拓扑架构设计,这其中接线方式直接影响网络性能。
1.情况一.同一VLAN内部通信
1.1.同一交换机同一VLAN的不同端口进行通信
1.2.不同交换机的不同端口进行通信
2.情况二.不同VLAN之间通信
2.1.同一交换机不同VLAN之间进行通信
2.2.不同交换机的不同VLAN进行通信
从上述1.2可以看出,在实际应用中为了节省线缆资源并避免形成环状回路(即形成网环),两个VLAN交换机之间的端口如果承载相同的VLAN数据帧会导致冲突和信息混乱因此必须采用区分不同数据流的方法为此最直接的办法就是对每个数据帧添加一个标识符即所谓的trunk标签这样上述1.2中的端口J和端口K之间的链路上的数据帧就需要打上相应的trunk标签以实现相互识别其中端口J和端口K都属于同一个VLAN m而另一组端口可能属于另一个VLAN n(假设存在多个VLAN的情况下)。换句话说只要某个端口需要同时传输多个不同VLAN的数据帧那么该端口发出的所有数据帧都需要打上相应的trunk标签而接收的数据帧可以通过检查其trunk标签所属的VLAN来确定其归属用Cisco/H3C厂商的技术术语来说这种特殊的端口被称为trunk端口而连接两个trunk端口的链路则被定义为trunk链路
我们知道在常规网络架构中我们的PC设备通常直接连接到支持二层交换或者支持VLAN功能的交换机端口中而这些PC设备发送出来的默认都是普通的以太网数据帧这些数据帧并没有任何标识符因此并不知道802.1q机制的存在然而正是基于这种需求才有了VLAN技术的存在目标就是将一组PC设备划分为同一个逻辑域(即同一个VLAN)内实现本地通信隔离与其他组别设备通信的目的
为了满足多用户环境下的扩展需求我们通常会采用级联交换机的方式即通过将多个交换机串联起来使得单个交换机无法处理所有所需的链路需求从而形成了层次化的网络结构在这种情况下位于各个层级上的链路根据其功能分为两类:一类是负责传输不同子网络流量的主干链路即为trunk链路;另一类则是仅连接单个子网络内部设备不参与跨层级通信的普通连接链路即为access链路需要注意的是这里暂且不考虑hybrid模式(即将access链路与trunk链路结合使用的情况)
最后关于access链路上所连接的各种类型的设备它们不需要具备任何额外的标识符因为它们不会互相发送来自不同子网络的数据因此两端设备完全可以通过简单的流量控制即可实现有效的隔离与管理
1.设计目的
隔离广播域,节省物理设备,隔离安全策略域
2.IEEE 802.1q
为扩展VLAN的级联方案提供了一个标准的协议
3.如何使用VLAN
将某些端口归入一个VLAN,在依据MAC地址划分的同时...
第二部分:Linux上的VLAN
Linux上的VLAN与Cisco/H3C设备上的VLAN存在显著差异:前者直接提供了现成的VLAN功能(即"V"),而后者则需要通过桥接设备实现网络划分;在Linux系统中,默认情况下未安装桥接设备的情况下无法直接创建VLAN;因此在实际应用中需要先创建桥接设备再进行相应的配置操作
通过上述命令配置后,默认情况下eth0.10成为一个虚拟网卡设备(类似于br0、tap0、bond0等),其下挂接了一个真实网卡eth0;数据从eth0发送前需经过eth0.10打上相应的tag标记
该tag操作将由eth0.10的hard_xmit接口执行:首先打上tag信息后调用ethxmit函数发送数据至外部网络
一个真实的物理网卡如ethx为例,它能够支持多个vlan的数据帧传输,并由此可知其作为trunk端口的功能。
Linux的VLAN工具vconfig采用ethx.y的方式:以ethx作为trunk端口连接y号VLAN,并生成对应的虚拟设备链路来承载相应的VLAN数据帧编号标识符(ID)。具体而言:
- 创建一个单独的VLAN接口:
- 配置vconfig ethx.a
- 启用该接口:ifconfig ethx.a up
- 创建对应的桥接网络:brctl addbr brvlan1a
- 配置桥接接口:brctl addif brvlan1a ethx.a
- 类似地创建其他多个单独接口(如b, c, d)并按照上述步骤配置即可
基本上已经完成了Linux上VLAN的配置工作。剩下的内容就是掌握VLAN间通信的基本原理与实现方法。相对来说这一知识点最为简单,也就是采用路由机制即可实现不同VLAN之间的通信连接。因为采用路由机制就需要为网络中的每个设备分配一个唯一的IP地址作为网关,因此确定这些IP地址的位置自然就成为了需要解决的问题,我们可以确定的是这些IP地址必须配置在当前所在的VLAN内部网络部分,因此我们可以根据实际需求选择不同的位置来设置这些关键参数
在同一个VLAN上的路由器接口上,并且该路由器能够连接到目标VLAN(该接口为trunk端口)。
2. 位于同一个VLAN内的ethx.y虚拟接口上,并且该Linux Box配置了通往指定VLAN a的路由(最直接的方式是通过ethx'.a虚拟接口)。
3.位于同一个VLAN网络中(每个基于Linux的操作系统桥接器都自带一个本地接口,并支持配置IP地址),该Linux Box能够实现对特定VLAN a网络的连接(最直接的方法是通过ethx'.a虚拟接口或者目标VLAN对应的桥接器进行连接)。
其中的1和2实际上没有什么差别,本质上就是找一个能配置IP地址的地方,大多数情况下使用2,但是如果出现同一个VLAN在同一个Linux Box配置了两个trunk端口,那么就要使用Bridge的地址了,比如下面的配置:
brctl addbr brvlan10
brctl addif brvlan10 eth0.10
brctl addif brvlan10 eth1.10
ifconfig brvlan10 up
此时有两个ethx.y型的虚拟接口,为了不使路由冲突,只能配置一个IP,那么此IP地址就只能配置在brvlan10上了。不管配置在Bridge上还是配置在ethx.y上,都是要走IP路由的,只要MAC地址指向了本地的任意的一个接口,在netif_receive_skb调用handle_bridge的时候都会将数据帧导向本地的IP路由来处理。Linux作为一个软件,其并没有原生实现硬件cache转发,因此对于Linux而言,所谓的三层交换其实就是路由。
我们看一下一个被打上tag的数据帧什么时候脱去这个tag,在定义上,它是从access端口发出时脱去的,然而在语义上,只要能保证access端口发出的数据帧不带有tag即可,因此对于何时脱去tag并没有什么严格的要求。在Linux的VLAN实现上,packet_type的func作为一个第三层的处理函数来单独处理802.1q数据帧,802.1q此时和IP协议处于一个同等的位置,VLAN的func函数vlan_skb_recv正如IP的处理函数ip_rcv一样。在Linux实现的VLAN中,只有当一个端口收到了一个数据帧,并且该数据帧是发往本地的时候,才会到达第三层的packet_type的func处理,否则只会被第二层处理,也就是Bridge逻辑处理,Linux的原生Bridge实现并不能处理802.1q数据帧,甚至都不能识别它。整个trunk口收发数据帧,IEEE 802.1q帧处理,以及VLAN间通信的示意图如下:
而相比之下PVVLN作为一个软件驱动的解决方案其核心思想就是通过定义访问控制策略来实现对同一IP子网内主机与默认网关之间通信的有效限制从而达到网络隔离的效果。”
第三部分:几点总结
- 你要首要规划网络拓扑结构而非仅了解VLAN在Linux中的配置细节;
- 应透彻掌握其核心理念及具体设置;
- 需明确区分关键与辅助概念的不同作用;
- 无论采用何种架构或系统中设置VLAN都只需关注两件事:一是明确各端口所属的VLAN组;二是识别那些连接多 VLAN 的端口;
- 其余部分无需死记硬背而是要真正理解其重要性。
想分享一篇关于人工智能的基础学习资源。完全零基础无需担心!这是一篇通俗易懂且风趣幽默的文章,并且特别有趣的内容哦~欢迎加入我们的学习社区一起探索人工智能的世界!
