前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

VLAN

原创
作者头像
Nujil
修改2023-04-14 11:22:57
1.4K0
修改2023-04-14 11:22:57
举报
文章被收录于专栏:CNotesCNotes

VLAN(Virtual LAN):

“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。广播域,指的是广播帧(目标MAC地址全部为1)所能传递到的范围,亦即能够直接通信的范围。严格地说,并不仅仅是广播帧,多播帧(Multicast Frame)和目标不明的单播帧(Unknown Unicast Frame)也能在同一个广播域中畅行无阻。

本来二层交换机只能构建单一的广播域,不过使用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可以和它们有大不同。

Cisco以及其他的厂商定义了很多的细节,而这些细节在IEEE 802.1q标准中并没有被定义,这些细节包括但不局限于以下几点: 

  1. 每一个VLAN交换机端口需要绑定一个VLAN id;
  2. 每一个VLAN交换机端口处于下面三类中的一类:access,trunk,hybrid。
    • access端口:从此类端口收到的数据帧是不打tag的,从此类端口发出的数据帧是不打tag的;
    • trunck端口:从此类端口收到的数据帧打着tag,从此类端口发出的数据帧需要打tag(不考虑缺省VLAN的情况);
    • hybrid: 略

VLAN 封装方式:802.1Q & ISL

在交换机的汇聚链接上,可以通过对数据帧附加VLAN信息,构建跨越多台交换机的VLAN。附加VLAN信息的方法,最具有代表性的有:

  • IEEE 802.1Q
  • ISL

IEEE 802.1Q

IEEE 802.1Q协议规定,在以太网数据帧的目的MAC地址和源MAC地址字段之后、协议类型字段之前加入4个字节的VLAN标签(又称VLAN Tag,简称Tag),用于标识数据帧所属的VLAN。

在数据帧中添加了4字节的内容,那么CRC值自然也会有所变化。这时数据帧上的CRC是插入TPID、TCI后,对包括它们在内的整个数据帧重新计算后所得的值。

在一个VLAN交换网络中,以太网帧主要有以下两种形式:

  • 有标记帧(Tagged帧):加入了4字节VLAN标签的帧。
  • 无标记帧(Untagged帧):原始的、未加入4字节VLAN标签的帧。

以太网链路包括接入链路(Access Link)和干道链路(Trunk Link)。

Access Link:

接入链路用于连接交换机和用户终端(如用户主机、服务器、傻瓜交换机等),只可以承载1个VLAN的数据帧。

在接入链路上传输的帧都是Untagged帧

Trunk Link:

干道链路用于交换机间互连或连接交换机与路由器,可以承载多个不同VLAN的数据帧。

在干道链路上传输的数据帧都是Tagged帧。

交换机内部处理的数据帧一律都是Tagged帧。从用户终端接收无标记帧后,交换机会为无标记帧添加VLAN标签,重新计算帧校验序列(FCS),然后通过干道链路发送帧;向用户终端发送帧前,交换机会去除VLAN标签,并通过接入链路向终端发送无标记帧。

VLAN标签包含4个字段,各字段含义如下所示:

TPID后面是两个字节的标签控制信息(TCI),细分为PRI, CFI 以及VID:

VLAN标签各字段含义

字段

长度

含义

取值

TPID

2Byte

Tag Protocol Identifier(标签协议标识符),表示数据帧类型。

取值为0x8100时表示IEEE 802.1Q的VLAN数据帧。如果不支持802.1Q的设备收到这样的帧,会将其丢弃。各设备厂商可以自定义该字段的值。当邻居设备将TPID值配置为非0x8100时, 为了能够识别这样的报文,实现互通,必须在本设备上修改TPID值,确保和邻居设备的TPID值配置一致。

PRI

3bit

Priority,表示数据帧的802.1p优先级。

取值范围为0~7,值越大优先级越高。当网络阻塞时,交换机优先发送优先级高的数据帧。

CFI

1bit

Canonical Format Indicator(标准格式指示位),表示MAC地址在不同的传输介质中是否以标准格式进行封装,用于兼容以太网和令牌环网。

CFI取值为0表示MAC地址以标准格式进行封装,为1表示以非标准格式封装。在以太网中,CFI的值为0。

VID

12bit

VLAN ID,表示该数据帧所属VLAN的编号。

VLAN ID取值范围是0~4095。由于0和4095为协议保留取值,所以VLAN ID的有效取值范围是1~4094。

而当数据帧离开汇聚链路时,TPID和TCI会被去除,这时还会进行一次CRC的重新计算。

TPID的值固定为0x8100,它标示网络帧承载的802.1Q类型,交换机通过它来确定数据帧内附加了基于IEEE 802.1Q的VLAN信息。

QinQ

因为IEEE 802.1Q中定义的VLAN Tag域只有12个比特,仅能表示4096个VLAN,无法满足城域以太网中标识大量用户的需求,于是产生了QinQ技术,拓展VLAN的数量空间。QinQ在原有的802.1Q报文的基础上增加一层802.1Q标签,使得VLAN数量增加到4094×4094。

在公网的传输过程中,设备只根据外层VLAN Tag转发报文,并根据报文的外层VLAN Tag进行MAC地址学习,

而用户的内层VLAN Tag将被当作报文的数据部分进行传输。QinQ的内外层标签可以代表不同的信息,如内层标签代表用户,外层标签代表业务。

802.1Q封装和QinQ封装:

帧大小

QinQ报文比802.1Q报文多四个字节,因此建议用户在组网时适当增加运营商网络中各接口的最大帧长(至少为1504 字节)。目前交换机缺省支持的最大帧长超过1504字节,不需要手动配置。

TPID

不同运营商的系统可能将QinQ帧外层VLAN标记的TPID设置为不同值。为实现与这些系统的兼容性,可以修改TPID值,使QinQ帧发送到公网时,承载与特定运营商相同的TPID值,从而实现与该运营商设备之间的互操作性。VLAN数据帧的TPID与不带VLAN标记的帧的协议类型字段位置相同,为避免在网络中转发和处理数据包时出现问题,不可将TPID值设置为以下表中的任意值:

协议类型字段数值及其表示的协议:

对应值

协议类型

0x0806

ARP

0x8035

RARP

0x0800

IP

0x86DD

IPv6

0x8863/0x8864

PPPoE

0x8847/0x8848

MPLS

0x8137

IPX/SPX

0x8809

LACP

0x888E

802.1x

0x88A7

HGMP

0xFFFD/0xFFFE/0xFFFF

设备保留

ISL(Inter Switch Link)

ISL,是Cisco产品支持的一种与IEEE 802.1Q类似的、用于在汇聚链路(Trunk)上附加VLAN信息的协议。

使用ISL后,每个数据帧头部都会被附加26字节的“ISL包头(ISL Header)”,并且在帧尾带上通过对包括ISL包头在内的整个数据帧进行计算后得到的4字节CRC值。换而言之,就是总共增加了30字节的信息。

在使用ISL的环境下,当数据帧离开汇聚链路时,只要简单地去除ISL包头和新CRC就可以了。由于原先的数据帧及其CRC都被完整保留,因此无需重新计算CRC。

Linux 中的VLAN

Linux上的VLAN和Cisco/H3C上的VLAN不同,后者的VLAN是现有了LAN,再有V,也就是说是先有一个大的LAN,再划分为不同的VLAN,而Linux则正好相反,由于Linux的Bridge设备是被创建出来的逻辑设备,因此Linux需要先创建VLAN,再创建一个Bridge关联到该VLAN,创建VLAN很简单: 

ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up 

当使用vconfig创建了eth0.10之后,它就是一个“真实意义”的虚拟网卡设备了,类似br0,tap0,bond0之类的,在这个虚拟网卡之下绑定的是一个真实网卡eth0,也就是数据从eth0这块真实网卡发出,

eth0.10中的“.10”表示它可以承载VLAN 10的数据帧,并且在通过eth0发出之前要打上tag。

那么打tag这件事自然而然就是通过eth0.10这个虚拟设备的hard_xmit来完成的,在这个hard_xmit中,打上相应的tag后,再调用eth0的hard_xmit将数据真正发出

因此一个真实的物理网卡比如ethx,它可以承载多个VLAN的数据帧,因此它就是trunk端口了:

Linux的VLAN工具vconfig采用ethx.y的方式以ethx为trunk端口加入VLAN id为y的VLAN中。类比Cisco/H3C,我们已经创建了trunk,总结一下:使用vconfig创建一个ethx.y的虚拟设备,就创建了一个trunk,其中ethx就是trunk口,而y代表该trunk口连接的trunk链路可以承载的VLAN数据帧的id,我们创建ethx.a,ethx.b,ethx.c,ethx.d,就说明ethx可以承载VLAN a,VLAN b,VLAN c,VLAN d的数据帧。 

接下来,我们看一下如何创建access端口。首先注意,由于Linux的Bridge是虚拟的,逻辑意义的,因此可以先创建了VLAN之后,再根据这个VLAN动态的创建Bridge,而不是“为每一个端口配置VLAN id”,我们需要做的很简单: 

创建VLAN:

代码语言:javascript
复制
ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up

为该VLAN创建Bridge:

代码语言:javascript
复制
brctl addbr brvlan10
brctl addif brvlan10 eth0.10

为该VLAN添加网卡:

代码语言:javascript
复制
ifconfig eth1 0.0.0.0 up
brctl addif brvlan10 eth1
ifconfig eth2 0.0.0.0 up
brctl addif brvlan10 eth2 

... 

这就完了。从此,eth1和eth2就是VLAN 10的access端口了,而eth0则是一个trunk端口,级联VLAN的时候要用到,如果不需要级联VLAN,而仅仅需要扩展VLAN 10,那么你大可将eth1连接在一个二层常规交换机或者hub上...同样的,你可以再创建一个VLAN,同样通过eth0来级联上游VLAN交换机: 

代码语言:javascript
复制
ifconfig eth0 0.0.0.0 up
vconfig eth0 20
ifconfig eth0.20 up
brctl addbr brvlan20
brctl addif brvlan20 eth0.20
ifconfig eth5 0.0.0.0 up
brctl addif brvlan20 eth5 

如图:

VLAN之间的通信

这个知识点最简单了,那就是使用路由,为此很多人把支持VLAN的三层交换机和路由器等同起来。既然使用路由就需要一个IP地址作为网关,那么如何能寻址到这个IP地址?我们要把这个IP配置在哪里呢?可以肯定的是,必须配置在当前VLAN的某处,于是我们有多个地方可以配置这个IP:

1.同属于一个VLAN的路由器接口上,且该路由器有到达目的VLAN的路由(该路由器接口为trunk口)。

2.同属于一个VLAN的ethx.y似的虚拟接口上,且该Linux Box拥有到指定VLAN a的路由(最显然的,拥有ethx'.a虚拟接口)。

3.同属于一个VLAN的Bridge设备上(Linux的Bridge默认带有一个本地接口,可以配置IP地址),且该Linux Box拥有到指定VLAN a的路由(最显然的,拥有ethx'.a虚拟接口或者目标VLAN的Bridge设备)。

其中的1和2实际上没有什么差别,本质上就是找一个能配置IP地址的地方,大多数情况下使用2,但是如果出现同一个VLAN在同一个Linux Box配置了两个trunk端口,那么就要使用Bridge的地址了,比如下面的配置: 

代码语言:javascript
复制
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间通信的示意图如下: 

Vlan子接口基础知识

vlan子接口定义:

通过协议和技术将一个物理接口(interface)虚拟出来的多个逻辑接口。vlan子接口共享物理网卡的流量。

相对子接口而言,这个物理接口称为主接口。每个子接口从功能、作用上来说,与每个物理接口是没有任何区别的,它的出现打破了每个设备存在物理接口数量有限的局限性。在路由器中,一个子接口的取值范围是0~4095,共4096个,当然受主接口物理性能限制,实际中并无法完全达到4096个,数量越多,各子接口性能越差。

子接口与主接口的关系:

子接口共用主接口的物理层参数,又可以分别配置各自的链路层和网络层参数。用户可以禁用或者激活子接口,这不会对主接口产生影响;但主接口状态的变化会对子接口产生影响,特别是只有主接口处于连通状态时子接口才能正常工作。

子接口产生的原因:

在VLAN虚拟局域网中,通常是一个物理接口对应一个 VLAN。在多个 VLAN 的网络上,无法使用单台路由器的一个物理接口实现 VLAN 间通信,同时路由器有其物理局限性,不可能带有大量的物理接口。

子接口的产生正是为了打破物理接口的局限性,它允许一个路由器的单个物理接口通过划分多个子接口的方式,实现多个VLAN间的路由和通信。

子接口的优缺点:

优点:打破物理接口的数量限制,在一个接口中实现多个VLAN间的路由和通信。

缺点:多个子接口共用主接口,性能比单个物理接口差,负载大的情况下容易成为网络流量瓶颈。

由于独立的物理接口无带宽争用现象,与子接口相比,物理接口的性能更好。来自所连接的各 VLAN 流量可访问与 VLAN 相连的物理路由器接口的全部带宽,以实现 VLAN 间路由。

子接口用于 VLAN 间路由时,被发送的流量会争用单个物理接口的带宽。网络繁忙时,会导致通信瓶颈。为均衡物理接口上的流量负载,可将子接口配置在多个物理接口上,以减轻 VLAN 流量之间竞争带宽的现象。

参考自:

https://blog.csdn.net/dog250/article/details/7354590

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • VLAN(Virtual LAN):
  • 对于VLAN概念的理解,有几点要强调:
  • VLAN 封装方式:802.1Q & ISL
    • IEEE 802.1Q
      • Access Link:
        • Trunk Link:
          • QinQ
            • ISL(Inter Switch Link)
            • Linux 中的VLAN
              • VLAN之间的通信
                • Vlan子接口基础知识
                  • vlan子接口定义:
                  • 子接口与主接口的关系:
                  • 子接口产生的原因:
                  • 子接口的优缺点:
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档