一、概述
MAC转发表是二层交换机原型中的核心内容,所有的数据操作都是围绕这张表而来。前一篇文章中讲到了该表涉及的两个核心字段:端口号与MAC地址。本篇文章专门讲解一下该MAC转发表的设计与表的操作方法。
二、MAC转发表的设计
MAC转发表的设计我们还是遵循渐进式的方法,从最基本的字段开始,根据需要再逐步增加。
1)字段设计
从前一篇文章分析,对于MAC转发表来说,其核心字段就2个:端口号和MAC地址,故我们对其字段的设计也就采用此二元数据。交换机的端口号一般不超过64,故用char(8位)类型定义即可,MAC地址的位宽为48位,可定义为6个字节数组。一般在协议字段中或以协议字段作为字段的表结构定义中,采用无符号类型做定义,这样方便数据与或运算,也方便硬件移植。字段数据类型的定义一般也建议重定义为简写方式,在读写代码时,更好理解和把握数据是否溢出、越界等。
数据类型重定义如下:
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
//typedef unsigned long u64;/*64位系统*/
/*请特别的注意!!!在32位系统下,long的数据位宽只有32位,64位的数据类型必须使用long long的方式定义*/
typedef unsigned long long u64;/*32位系统,实验平台OpenBox-S4为32位系统*/
2)表结构设计
数据存储结构的设计有很多方式可选,如数组、多维数组、单向链表、双向链表和树结构等。在原型系统的设计中,因为表结构定义会影响到整个代码实现,且需要考虑将来硬件卸载的便捷性,所以我们一般建议采用较为简单的表存储结构。又因为每条表项的大小是固定空间,所以采用数组的形式是较优的选择。
先定义一条表项的数据结构如下:
struct row_port_mac
{
u8 port;
u8 pad;/*为了对齐做的补充*/
u8 mac[MAC_LEN];
};
补充对齐:上述表项一条宽度为7个字节,如此按数组形式组织的话,则会让mac字段在非内存对齐位置出现,导致数据比较时需要两次对比。若是跨了CacheLine,则会导致更长的时间损耗。具体原因请网上搜索“内存对齐”深入学习。我们建议在定义数组项的时候一定按照8字节倍数对齐方式来定义,若小于8字节,则补充为8;若多于8,则再多补充直到成为8的倍数(特别说明,这是针对数组定义要求,不同数据结构根据分析会有不同的优化定义方法)。
再定义整张表的数据结构如下:
#define OBX_MAC_MAX 128/*系统最多支持128条MAC表项*/
struct table_port_mac
{
struct row_port_mac row[OBX_MAC_MAX];
};
3)表操作方法设计
表的方法主要是指对表的操作,通常包括表项的增、删、改和查四个动作。这些表动作的设计与表的结构定义和表的数据操作方法相关,可以利用对表数据的操作进行优化和精简。如在二维数据中进行任何操作,都得先把表遍历一次,找到空位才能增加,找到对应的内容项才能修改和删除。
根据二层交换的数据处理流程分析,在源MAC的学习过程中,学习到一个新MAC地址需要进行增加表项操作,若已经学习到的MAC地址发生了端口迁移,则需要更新其端口信息。在目的MAC查表过程中是一个单纯的MAC地址查找过程。MAC表项的删除一般发生在MAC表老化的时候,后面文章单独讲。
三、MAC表功能方法设计
结合前面的表方法设计和二层交换的数据处理逻辑,我们暂将MAC转发表的方法定义为两个:一是源MAC学习;二是目的MAC查找。
1)源MAC学习
源MAC学习是指将一个输入分组的源MAC地址学习并保存到MAC转发表中。若MAC转发表中不存在该源MAC地址信息,则找一个空白位置存储。若MAC转发表中已有该地址信息,则刷新(覆盖)其端口号信息。在查找源MAC地址是否存在时,同时查找空闲表项位置,这样只用遍历一次表,即可完成两件事情。另外就是查找到源MAC地址后,立即刷新其端口号,可以判断并打印显示,该MAC地址是否发生了端口转移。
2)目的MAC查找
目的MAC的查找,其目的是为了获得查找MAC对应的端口号,查表结果有两种情况,一是查找到了,返回对应的端口号信息;二是没有查找到,则不能返回正常端口数据,需要使用特殊返回值表示,如-1。
四、总结与下一步
1)查表设计
MAC转发表的方法设计为什么把二层交换的功能和表操作混在了一起?因为在二层交换中,其核心数据处理流程就是针对MAC转发表进行的一系列数据查找、存储和更新动作。按照其逻辑处理方式来设计可以让学生更好理解MAC表的操作流程与细节。
在逻辑设计的过程中,我们需要针对一些特定功能进行抽象、模块化,比如表的四操作。但在具体实现过程中,其本身的逻辑处理也就是对表的内容进行处理,以数据流程为主线进行设计比纯模块化的分层设计更容易让学生掌握交换的处理过程。模块化和分层可以放到后期优化阶段。
表操作的方法也并不一定要马上全部实现,根据逻辑的需要逐个实现,在实现过程中也会不断修改完善。
2)MAC地址学习与查表实现
MAC地址的学习与查找是二层交换的核心,特别是MAC地址学习,如何设计快速、高效的学习方法,取决于我们对系统数据处理流程的深度理解与优化迭代。下一篇文章中会给出一种具体的实现方法供大家参考。
五、结语
欢迎您和学生们加入FAST开源项目群沟通与探讨,一起体验不一样的系统设计过程。请先加微信号15116127200后邀请入群。
关注FAST开源社区
FAST一一开源、开放、高速、高效、可编程、可定义!软硬件协同并行处理。