How to VLAN
介绍VLAN的基本概念和几种场景下的应用,而OpenWrt下VLAN处理机制和一般交换机有些不同,这里做了一个对比并给出了一种两台路由器之间的单线复用的方案
问题
计算机网络的教材对VLAN一笔带过,作业的却要用到交换机互联,之前看的VLAN的文章貌似都对应不到OpenWrt上去,也就很难有实践的机会;下面根据个人在宿舍组网上遇到的问题,一步步来探究VLAN的用法
后面又看到了N1盒子基于VLAN的单臂路由,又做了一些补充
多线接入
宿舍是上床下桌,每一张桌子下面有一个百兆的网口,通过负载均衡,很早就可以把网速跑到100Mbps了,这显然不够啊,因为宿舍WiFi是共用的,自然而然想到连接相邻的两个床位的网口,这样就有300Mbps了,这也是多线拨号的第一步
上图就是将LAN3与LAN4作双线接入,通过VLAN分别对应到eth0.3和eth0.4
此时LAN4与WAN是“直通”的,效果上来说,就是LAN4也可以插网线用电脑拨号了,如果是要给路由器做双线接入的话,则需要添加VLAN,再把一个LAN口添加到新VLAN中,最后建立接口拨号即可
交换
然而舍友还是需要网口拨号的,所以如果需要长期占用的话偶尔肯定是不太方便的,所以需要交换机来扩展一下网口,这一步已经可以通过简单的修改下OpenWrt路由器的Switch来实现,將LAN4和WAN划到同一个VLAN,两个接口就相当于在同一交换机下:
单线复用
然而,仅仅通过untagged只能实现多条线路的“汇聚”,能够达到100Mbps+的只有一台路由器而已,并没有实现“互通”,即每一台路由器都可以上到100Mbps+;不仅如此,还要实现相邻床位的路由器之间只用一根线连接就可以达到同样的网速,更具体的就是在一根网线传输不同的来源(网口)的数据
而VLAN的一个重要的功能恰好就是实现交换机之间的互通
单臂路由
这个需求源于有一台N1,之前看过VLAN的接入网络的方法,觉得网络结构更清晰,以此可以解决主路由算力不足的问题,但之前一直没有刷上OpenWrt,刷完之后发现居然没有交换机的Switch选项,赶紧翻出了之前看到的帖子:N1做主路由,新3做AP的最正统vlan连法教程,想起之前文档刚好有部分没看懂,刚好可以补充上
概念
首先还是OpenWrt的文档:VLAN,很早就读过,但是因为缺少具体的有解释的例子,当时没弄清楚VLAN tagged的机制
所以这里先结合华为的文档了解下基础的概念
VLAN Tag
首先需要理解VLAN标签是被添加到以太帧内部的一个4个字节的片段,其中VID也就是常说的VLAN ID
在一个VLAN交换网络中,以太网帧主要有以下两种形式:
- 有标记帧(Tagged帧):加入了4字节VLAN标签的帧
- 无标记帧(Untagged帧):原始的、未加入4字节VLAN标签的帧
常用设备中:
- 用户主机、服务器、Hub只能收发Untagged帧(Linux系统可以通过安装软件实现收发Tagged帧)
- 交换机、路由器和AC既能收发Tagged帧,也能收发Untagged帧
- 语音终端、AP等设备可以同时收发一个Tagged帧和一个Untagged帧
VID & PVID
VID也就是数据帧中的12bit的VLAN ID,表示该数据帧所属VLAN的编号,而PVID(Port Default VLAN ID)又称为缺省VLAN,可以用于和VID做比较来判断Tag的情况
应用
最主要的应用是划分广播域,这部分可以参考图文并茂VLAN详解,然而和本文的关系不是很大
为了提高处理效率,设备内部处理的数据帧一律都是Tagged帧,例如在交换机内部的,在数据帧进入交换机的时候可能会按照一定的规则被打上VLAN Tag以方便下一步的处理,OpenWrt的Old Wiki的一张图很好地体现了这一点:
以太帧进入端口后被打上VLAN Tag,之后在传输的CPU的线路内(Port5-CPU),就同时传输带两种VLAN Tag的包
另外在交换机之间,可以在一条链路上使用两个VLAN也叫做Ethernet trunking,也有人称作单线复用,常见的应用:
- 单臂路由(只有一个网口的路由器)
- 使用一根网线同时传输IPTV和宽带的数据
交换机
这里参考的是上面的华为的交换机的文档,不同交换机可能有些不一样
Incoming & Outgoing
以收发的设备作为主体,指的是数据帧到达接口而没有完全进出交换机内部,举个例子:
- 数据帧到达某一个接口时,路由器会对数据帧的VLAN情况做判断
- 如果符合通过的规则,则放行做后续处理,不符合则丢弃
- 后续处理可能就是剥离或者打上标签
链路类型和接口类型
配置VLAN:为了适应不同的连接和组网,设备定义了Access接口、Trunk接口和Hybrid接口3种接口类型,以及接入链路(Access Link)和干道链路(Trunk Link)两种链路类型,如下图所示
根据接口连接对象以及对收发数据帧处理的不同,以太网接口分为:
- Access接口
Access接口一般用于和不能识别Tag的用户终端相连,只能收发Untagged帧,且只能为Untagged帧添加唯一VLAN的Tag
- Trunk接口
Trunk接口一般用于连接交换机、路由器、AP以及可同时收发Tagged帧和Untagged帧的语音终端。它可以允许多个VLAN的帧带Tag通过,但只允许一个VLAN的帧从该类接口上发出时不带Tag(即剥除Tag)
- Hybrid接口
Hybrid接口可以允许多个VLAN的帧带Tag通过,且允许从该类接口发出的帧根据需要配置某些VLAN的帧带Tag(即不剥除Tag)、某些VLAN的帧不带Tag(即剥除Tag)
Hybrid接口和Trunk接口在很多应用场景下可以通用,但在某些应用场景下,必须使用Hybrid接口。比如一个接口连接不同VLAN网段的场景(如图所示的Router连接Hub的接口)中,因为一个接口需要给多个Untagged报文添加Tag,所以必须使用Hybrid接口。
- 接入链路只可以承载1个VLAN的数据帧,用于连接设备和用户终端
- 干道链路可以承载多个不同VLAN的数据帧,用于设备间互连
处理机制
OpenWrt对VLAN Tag的处理机制见后文引用文档的加粗部分,此处暂作为理解的参考
- Access端口
- Trunk端口
- Hybird端口
OpenWrt VLAN
OpenWrt的文档没怎么提及接口类型的概念,OpenWrt对VLAN设置的组织形式和普通的交换机有所不同,从机制介绍来看是比较接近Trunk端口的:发出的数据帧只有一个VLAN的数据帧不带Tag
OpenWrt文档所提到的:An untagged port can have only 1 VLAN ID 反映在:OpenWrt中的Switch设置VLAN时单个untagged Port无法再再其他VLAN上为Untagged,否则回提示:LAN 1 is untagged in multiple VLANs!
故抛开之前的端口类型,遵守VLAN的规则,兼容且实用就行
另外,不是所有OpenWrt设备都有Switch这个LuCI的配置选项,比如N1就没有,但是照样可以配置VLAN,位置在Interface的接口物理配置部分,由于无法像Switch那样有Tag之类的选项,
Tag机制
官方文档对Tag机制的介绍如下(散落在两处):
- Tagged on “CPU (eth0)” means that the two VLAN ID tags used in this example (1, 2) are sent to the router CPU “as tagged data”. Remember: you can only send Tagged data to VLAN-aware devices configured to deal with it properly.
- Untagged means that on these ports the switch will accept only the incoming traffic without any VLAN IDs (i.e. normal ethernet traffic). The switch will remove VLAN IDs on outgoing data in such ports. Each port can only be assigned as “untagged” to exactly one VLAN ID.
- Off: no traffic to or from the tagged ports of this VLAN ID will reach these ports.
Ports can be tagged or untagged:
- The tagged port (t is appended to the port number) is the one that forces usage of VLAN tags, i.e. when the packet is outgoing, the VLAN ID tag with vlan value is added to the packet, and when the packet is incoming, the VLAN ID tag has to be present and match the configured vlan value(s).
- The untagged port is removing the VLAN ID tag when leaving the port – this is used for communication with ordinary devices that does not have any clue about VLANs. When the untagged packet arrives to the port, the default port VLAN ID (called pvid) is assigned to the packet automatically. The pvid value can be selected by the switch_port section.
特别指出,但是一般也用不上,在LuCI界面上看不到的PVID设置,设置具体在uci network switch_port部分:
Port PVID; the VLAN tag to assign to untagged ingress packets
无Switch配置
官方文档的位置在 Creating driver-level VLANs 一节,配置方式是通过在接口设置,选择自定义接口,在名称在做文章:如在物理网卡eth1上,通过自定义eth1.2接口的方式建立一个VLAN ID为2的接口,在使用Switch设置VLAN,如添加VLAN ID为3的VLAN之后,接口处也会出现eth0.3,逻辑上还是统一的;下面来看下文档对处理机制的描述:
If the incoming packet arrives to the interface with software VLANs (incoming packet to eth1) and has a VLAN ID tag set, it appears on the respective software-VLAN-interface instead (VLAN ID 2 tag arrives on eth1.2) – if it exists in the configuration! Otherwise the packet is dropped. Non-tagged packets are deliveded to non-VLAN interface (eth1) as usual.
即处理流入的包:接口只接收有相应Tag的包,相当于Switch中的VLAN在该接口设置为Tag
这样一来,一个物理网口可以同时收发带Untagged帧和Tagged帧,故使用VLAN来实现单臂路由也就很好理解了,配置的方式也不唯一
解决方案
回到本文开头提到的问题,仿照上面的Switch内部VLAN机制的图的形式,画了一张两台OpenWrt路由器通过VLAN互通,进而实现让两台路由器可以得到宿舍三个网口合计300Mbps的接入
需要说明的是:
- 因为所有的VLAN都需要为拨号服务,所以这里略去了VLAN到CPU的一段
- 格式为了照顾LuCI的设置界面显示,可能看起来有些不寻常
- VLAN ID的外层意义就是接入的网口的标识,中间的TRUNK链路如何并不重要
- 对WAN Interface的命名就相对随意了,例如Router 1的WAN_1应该命名为WAN_21更合适一点
最后的在宿舍的书桌背后的路由器如图