一:VLAN的流程图
二:VLAN基础知识
VLAN简介: VLAN 被设计来隔离广播数据,同时提高网络的可管理性和安全性。核心为:不同 VLAN 之间不能通过二层进行通信。也就是,如果只希望报文只在某些端口内广播,则可将,这些报文设置在同一 VLAN 即可,不属于此 VLAN 的端口则接收不到此广播报文。简单来说,VLAN就是用来隔离广播域的。
VLAN的数据格式: 与标准的以太网帧头相比,VLAN报文格式在源地址后增加了一个4字节的802.1Q标签。这个4字节标签由2字节的标签协议标识(TPID—Tag Protocol Identifier,值为0x8100)和2字节的标签控制信息(TCI—Tag Control Information)。
VLAN ID:表明数据包所属的VLAN,有4096个值(VID为0与0xFFF保留)。 Priority:这个主要用与当交换机阻塞的时候,优先发送优先级高的数据包。
三:基本VLAN配置
1.1 VLAN TPID的配置: 能定义4个外层和内层的TPID List,定义1个额外的TPID List.通过使能比特位来控制选择内层的TPID和外层的TPID 是多少以及是否选择多层TPID或者单层TPID。 举例:如下图。port1可以解析内层TPID为0x8100或者0x8400,外层TPID为0x88A8或者0x88A的报文。不能解析带有额外TPID的报文。
这些TPID List可以在hagt_vlan.c中通过调用函数rtk_vlan_tpidEntry_set(uint32 unit, rtk_vlan_tagType_t type,uint32 tpid_idx, uint32 tpid)来进行修改。 通过调用函数rtk_vlan_portIgrTpid_set(uint32 unit, rtk_port_t port, rtk_vlanType_t type,uint32 tpid_idx_mask)来设置端口匹配哪一个TPID,从而进行报文的识别。
最后看看实际应用中的SDK,可以看到外层的TPID List为
看到内层的TPID List为
额外的TPID List为
四:可接受的帧类型
每个端口都能配置 可以配置vlan-untagged only和vlan-tagged only和all frames
在S6220E项目中,这里用来配置可接收帧类型的api函数没有被调用过,都是默认的SDK配置为可接收所有帧,并且和测试确认过access端口也是需要能通过带tag的数据帧,所以不需要修改可接收的帧类型,都为accept all frame就可以。
举例:一个端口设置为access端口,并且加入到vlan10中,如果是只允许untag的帧通过,那么当打流的时候,发一个带有tag的数据包到这个端口,这个端口会把这个包丢弃,也学不到mac地址。 而如果需求是access端口允许带tag的数据包进入的话,那么此时只允许vid等于10的包进入。别的vid不等于10数据包都会被vlan-filter给丢弃掉。 问题:如何确定是被vlan-filter给丢弃的呢? 第一步:如果这个端口未应用任何vlan-Decision的功能,打一个vid等于20的数据包到该端口,由于不属于同一个vlan,该端口不会收到这个数据包,也不能学习到mac地址表中。第二步:根据vlan的流程图可以知道,vlan-Decision是在vlan-filter前面的,那么我此时在该端口配置一个vlan-classifier或者vlan-mapping,把进入的数据包替换成vlan10,此时可以看到该端口能接收到数据包,并且也能学习到Mac地址表,此时mac地址表中的vlan不是20,而是被替换成了10。
SDK的命令行如下。
五: VLAN入口决定(包括IVC和Vlan-classifier和Port-based Vlan)
5.1 优先级列表
根据优先级来决定,VLAN ACL优先级最高,原始tag 内层/外层优先级最低。当一个端口同时配置了VLAN ACL和IVC的话,只有VLAN ACL会生效。
5.2 Port-based VLAN
这里就是给配置一个PVID,端口5的PVID配置为50,如果没有其他的入口决定配置,并且原始报文为untag,这个端口就会给这个报文添加一个50的VID。
5.3 IVC(ingress VLAN conversion)
IVC包含16block,128个entries per-block,总共2048个entries。每个block能够被用作IVC或者MAC-based或者IP-subnet-based VLAN。 这里就是说2048个entries被VLAN映射和基于MAC或IP的VLAN分类来分。
VLAN分类中就是下面这个函数来进行分配entry大小的。
VLAN映射中就是下面这个函数来进行分配entry大小,其中HAGT_VLAN_CLASSIFIER_BLOCK_NUM等于8。
下图就是通过SDK对每个部分所分配的entry大小。
5.3.1 VlAN基于MAC与IP分类的流程
基于MAC或者IP进行分类就是根据传入的数据包的源MAC或者源IP进行分类,
举例说明: 第 1 条是基于 MAC 的规则,它将源 MAC 2222.2222.2222 分类到 VLAN 5; 第 2 条是基于 IP 的规则,它将源 IP 1.1.1.1 分类到 VLAN 5;
把规则1,2,加入到组 31,并且在三个接口上应用组 31。在 eth-0-1、 eth-0-2。 两个接口上应用不同的分类策略。 eth-0-1 基于MAC分类,意味着匹配 源MAC的数据包在这个接口上将转发到规则对应的 VLAN。 eth-0-2 基于IP分类,意味着匹配源IP 地址的数据包将转发到规则对应的 VLAN。
问题:如果接口49应用了VLAN_classifier的功能,且接口49为trunk模式VLAN allow 1和10,那么当打一个tag为20的数据流进入接口49,且该数据流的源MAC与VLAN_classifier的基于MAC的规则碰撞,那么此时这个流是否能从接口49进入,然后转发到接口50呢?还是在外部进行转发?
实验结果:当打tag为20的流,不能进入接口49,然后tag为10的流也不能进入接口49,并且也学不到mac。 然后当我49口允许tag为5的流通过后,此时我能学到mac,并且数据包能进入49接口。 这说明了,进入接口49之前是先进行vlan_classifier的VLAN替换,已经把当前tag为20或者10的数据包重新配置为tag为5,所以不能进入49口。Vlan_classifier并不是我想的进入了接口49之后再进行替换。而是要进入这个端口之前先进行vlan分类。
下发SDK的参数特别注意的一点,这里macEntry.igrvlanfilter_ignore = DISABLED;要设置为DISABLED,因为如果设置为ENABLED的话,表示忽略入口VLAN_Filtering的检查,会导致出现bug。DISABLED表示不忽略(follow the decision of Ingress VLAN Filtering)。
出现bug的原因是因为vlan_classifier在入口vlan过滤之后,当不检查入口vlan过滤,那么端口就是接受不属于该vlan内的报文。
5.3.2 VlAN映射
模式1:替换模式
应用在接口上,可以把进入端口的数据包的vid替换成所需要的vid。
例如这里的原始vlan为10,进入端口1,就会把该vlan替换为2。 这里需要注意的是,配置了入口vlan替换的同时就要配置与之相对应的出口vlan替换。也就是说,当接口1作为数据包的入口,会把vlan10替换为vlan2.那么当接口1作为数据包的出口,就要把vlan2替换为vlan10.
查看debug,这里入口entry就是从1025开始的。进入sdk查看,可以看到这里作为入口是把vlan100强制替换为vlan10,并且状态为ENABLE.作为出口的话,是把vlan10强制替换为100
模式2:基本QINQ模式 配置接口49为基本QINQ模式,可以接受所有类型的数据包(带不带tag都行,不在vlan1的数据包也能接受)。我这里打到tag为100的包进入49端口,进入后给数据包增加一层outer_tag且固定为1.
模式3:灵活QINQ模式,增加一层tag
? 基本QINQ在实际应用中局限性太大,灵活QINQ封装方法,既可以根据一些特性对用户数据进行流分类,然后不同的类别封装不同的外层VLAN标签。 ? 对untag加一层标签 ? 对vlan range加一层标签 ? 对out-of-range其他报文加标签
这里就是说,当一个tag为10的数据流进入了应用灵活QINQ模式的端口,那么就会对这个数据包增加一个tag为2的outer-tag,最后捕获到的数据包是带二层tag的。 当一个untag的数据流进入了应用灵活QINQ模式的端口,那么就会对这个数据包增加一个tag为20的outer-tag,最后捕获到的数据包是单层tag的数据包。
模式4:灵活QINQ模式,增加两层tag 这里的增加两层tag是对untag的流映射成带两层的数据流。
查看SDK:
特别说明: 打一个双tag的数据包,处理方式是忽略内层tag,只检查外层tag.然后再分配S-tag,最后收包是带三层tag的数据包。
六: VLAN入口过滤
入口过滤: 通过下图可以看到VLAN 的ingress-filter全部都是drop,都是基于端口的,这里的是SDK默认的初始化,代码中未进行修改,这里的含义是说如果该端口未加入vlan10,则对进入的含有vlan10的包进行丢弃。
hagt_if.c里面有个_hagt_if_set_vlan_filter_en()函数并不是真正的设置芯片的VLAN过滤功能,这里只是对平台下发的数据存一个软表(可以理解为存储在变量中,开发人员可以随时获取平台下发的数据是多少)。
七:VLAN出口过滤
1、 每个端口配置: 如果出口过滤使能,则会在对应的出端口那里检查VLAN membership 2、 对于已知的L2/IPv4/IPv6组播报文,会忽略出口vlan过滤检查,这里的已知就是表示已经学习到mac表的报文。如下图。
SDK的命令行如下图
全文查找了rtk_vlan_leakyStpFilter_set(uint32 unit, rtk_enable_t enable)和rtk_vlan_mcastLeakyEnable_set(uint32 unit, rtk_enable_t leaky)函数,发现并没有调用,下图的状态就是SDK默认的状态,代码中未修改。 rtk_vlan_mcastLeakyEnable_set()函数的功能是:无论目的端口和入端口是否在同一个VLAN,组播报文都可以转发。但是这里是不使能,也就是说组播报文只能在同一个vlan内部进行转发。
八:VLAN profile(VLAN 属性)
每个vlan都能绑定一个vlan profile,查看SDK,如果下发的entry为0,表示在该VLAN内,能够学习新的mac.
如果下发的entry为1,表示在该VLAN内,不能学习新的mac.
九:VLAN Remarking
9.1出口vid优先级决定
9.2、EVC
可以参考IVC的内容.
ivl和svl模式的区别:https://www.cnblogs.com/naodong/p/7072679.html
|