0731-84728105
15116127200
二层交换机原型设计与实现(二)
发布时间:2021-05-06
     FAST架构的UA编程非常简单,有(yǒu)其固定的套路,核心部分(fēn)两块,一是在main函数中把环境初始化好,注册UA的回调函数和配置硬件默认规则;二是在回调函数中专心处理(lǐ)分(fēn)组数据,实现完整业務(wù)功能(néng)。
     二层交换的分(fēn)组接收由系统回调送入处理(lǐ)函数,后续交换相关的所有(yǒu)逻辑均在该函数里完成实现。
     1)UA示例代码
     百度网盘下载地址:https://pan.baidu.com/s/13zmKXeMnpUMsCiL5GAI7Vg
     提取码:ehd7
     目录:FAST开源社區(qū)/教學(xué)案例/连载公开课/二层交换机原型设计与实现
     2)代码文(wén)件说明
     二层交换代码目录為(wèi):/home/hnxs/l2switch/,其下共包括两个文(wén)件,其中一个為(wèi)main_ul2switch.c主要包括UA的平台性处理(lǐ)代码和空的callback函数。另一个是C的编译文(wén)件Makefile文(wén)件,主要说明如何编译生成二层交换可(kě)执行命令。
      3)编译文(wén)件说明

default:
   gcc -o ul2switch main_ul2switch.c -lua -lreg -lpthread
clean:
   rm -rf ul2switch

     二层交换机编译需要使用(yòng)到FAST的libreg、libua和系统的libpthread三个库的支持。
     4)编译, 在/home/hnxs/l2switch/目录下输入以下命令:

root@HNXS:/home/hnxs/l2switch# make

系统输出如下:

gcc -o ul2switch main_ul2switch.c -lua -lreg -lpthread

当前目录会多(duō)产生一个ul2switch文(wén)件

root@HNXS:/home/hnxs/l2switch# ls
main_ul2switch.c Makefile ul2switch

     5)执行验证,在/home/hnxs/l2switch/目录下输入以下命令:

root@HNXS:/home/hnxs/l2switch# ./ul2switch
fastU->REG Version:20180827,OpenBox HW Version:2020210329
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:3069,mid:129,Register OK!
fastU->libua version:20180827
fastU->fast_ua_recv......

显示上述结果说明系统平台代码执行正常。
     1)C程序的主函数main

/*UA模块初始化*/
ua_init(mid);
/*配置硬件默认规则,将硬件所有(yǒu)报文(wén)送到模块ID為(wèi)mid的进程处理(lǐ)*/
fast_reg_wr(FAST_ACTION_REG_ADDR|FAST_DEFAULT_RULE_ADDR,ACTION_SET_MID<<28|mid);
/*启动線(xiàn)程接收分(fēn)派给UA进程的报文(wén)*/
fast_ua_recv();
/*主进程进入暂停状态,数据处理(lǐ)主要在回调函数*/
pause();

     2)创建UA,注册callback

void ua_init(u8 mid)
{
int ret = 0;
/*向系统注册,自己进程处理(lǐ)报文(wén)模块ID為(wèi)mid的所有(yǒu)报文(wén)*/
if((ret=fast_ua_init(mid,callback)))//UA模块实例化(输入参数1:接收模块ID号,输入参数2:接收报文(wén)的回调处理(lǐ)函数)
{
perror("fast_ua_init!\n");
exit (ret);//如果初始化失败,则需要打印失败信息,并将程序结束退出!
}
}

     3)callback处理(lǐ)函数

int callback(struct fast_packet *pkt,int pkt_len)
{
return 0;
}

     1)打印接收分(fēn)组metadata信息
     FAST分(fēn)组的数据格式请参考第一篇文(wén)章《二层交换机原型设计与实现(一)》描述。在callback函数一开始,打印FAST分(fēn)组的metadata信息和以太网协议的源和目的MAC地址信息。

xprintf("inport:%d,dstmid:%d,len:%d,dmac:%02X:%02X:%02X:%02X:%02X:%02X,smac:%02X:%02X:%02X:%02X:%02X:%02X\n",
pkt->um.inport,pkt->um.dstmid,pkt_len,pkt->data[0],pkt->data[1],pkt->data[2],pkt->data[3],pkt->data[4],pkt->data[5],pkt->data[6],pkt->data[7],pkt->data[8],pkt->data[9],pkt->data[10],pkt->data[11]);

     2)调用(yòng)发送函数发送分(fēn)组
     调用(yòng)FAST的分(fēn)组发送函数,将接收到的一个分(fēn)组从指定端口发出,要特别注意metadata字段的设置。

void pkt_send_normal(struct fast_packet *pkt,int pkt_len)
{
xprintf("pkt_send_normal->%p,outport:%d,len:%d\n",pkt,pkt->um.outport,pkt_len);
pkt->um.pktsrc = 1;/*报文(wén)来源為(wèi)CPU输入,站在硬件角度*/
pkt->um.pktdst = 0;/*报文(wén)目的為(wèi)硬件输出*/
pkt->um.dstmid = 5;/*直接从硬件GOE模块输出,不走解析、查表等模块*/
fast_ua_send(pkt,pkt_len);/*调用(yòng)FAST API函数发送*/
}

     该函数调用(yòng)之前,必须将pkt->um.outport字段赋值,指定分(fēn)组的输出端口号。
     1)核心函数callback
     callback函数是整个UA的核心功能(néng)函数,是用(yòng)户业務(wù)实现的开始位置。虽然我们今天只在该函数中做了两件事情,一是打印接收到的分(fēn)组基本信息,二是将该分(fēn)组发送到指定端口。但是,我们今天已经在该平台上实现了一个最简单的分(fēn)组转发功能(néng)的原型系统了。
     2)注释和备份的重要性
     重新(xīn)性不多(duō)说,只是在此特别的特别的强调一下。
     3)实现简单交换逻辑功能(néng)
     在如此简单的一个平台上,能(néng)快速实现硬件端口的分(fēn)组接收和指定端口的分(fēn)组发送,是不是网络功能(néng)的一大部分(fēn)问题均已经解决?我们只需要关注我们具體(tǐ)业務(wù)的逻辑处理(lǐ)了,你到底是要实现交换还是路由?是普通二层交换还是SDN交换?是普通三层路由还是lisp路由或是segment路由,是不是一切均有(yǒu)可(kě)能(néng)?
     不要高兴得太早,这只是万里長(cháng)征的第一步,起点和终点的距离必须由自己的脚步来测量,一步也不能(néng)少。所以我们还是从简单的二层交换机开始,下一篇文(wén)章正式进入分(fēn)组交换的设计。
      欢迎您和學(xué)生们加入FAST开源项目群沟通与探讨,一起體(tǐ)验不一样的系统设计过程。请先加微信号15116127200后邀请入群。

关注FAST开源社區(qū)
FAST一一开源、开放、高速、高效、可(kě)编程、可(kě)定义!软硬件协同并行处理(lǐ)。
服務(wù)热線(xiàn)