0731-84728105
15116127200
二層交換機原型設計(jì)與實現(xiàn)(二)
發布時(shí)間:2021-05-06
     FAST架構的UA編程非常簡單,有其固定的套路,核心部分兩塊,一是在main函數中把環境初始化好(hǎo),注冊UA的回調函數和(hé)配置硬件默認規則;二是在回調函數中專心處理(lǐ)分組數據,實現(xiàn)完整業務功能(néng)。
     二層交換的分組接收由系統回調送入處理(lǐ)函數,後續交換相關的所有邏輯均在該函數裏完成實現(xiàn)。
     1)UA示例代碼
     百度網盤下(xià)載地址:https://pan.baidu.com/s/13zmKXeMnpUMsCiL5GAI7Vg
     提取碼:ehd7
     目錄:FAST開(kāi)源社區(qū)/教學案例/連載公開(kāi)課/二層交換機原型設計(jì)與實現(xiàn)
     2)代碼文(wén)件說明(míng)
     二層交換代碼目錄爲:/home/hnxs/l2switch/,其下(xià)共包括兩個文(wén)件,其中一個爲main_ul2switch.c主要包括UA的平台性處理(lǐ)代碼和(hé)空(kōng)的callback函數。另一個是C的編譯文(wén)件Makefile文(wén)件,主要說明(míng)如何編譯生成二層交換可執行命令。
      3)編譯文(wén)件說明(míng)

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

     二層交換機編譯需要使用(yòng)到(dào)FAST的libreg、libua和(hé)系統的libpthread三個庫的支持。
     4)編譯, 在/home/hnxs/l2switch/目錄下(xià)輸入以下(xià)命令:

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

系統輸出如下(xià):

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

當前目錄會(huì)多産生一個ul2switch文(wén)件

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

     5)執行驗證,在/home/hnxs/l2switch/目錄下(xià)輸入以下(xià)命令:

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......

顯示上(shàng)述結果說明(míng)系統平台代碼執行正常。
     1)C程序的主函數main

/*UA模塊初始化*/
ua_init(mid);
/*配置硬件默認規則,将硬件所有報(bào)文(wén)送到(dào)模塊ID爲mid的進程處理(lǐ)*/
fast_reg_wr(FAST_ACTION_REG_ADDR|FAST_DEFAULT_RULE_ADDR,ACTION_SET_MID<<28|mid);
/*啓動線程接收分派給UA進程的報(bào)文(wén)*/
fast_ua_recv();
/*主進程進入暫停狀态,數據處理(lǐ)主要在回調函數*/
pause();

     2)創建UA,注冊callback

void ua_init(u8 mid)
{
int ret = 0;
/*向系統注冊,自(zì)己進程處理(lǐ)報(bào)文(wén)模塊ID爲mid的所有報(bào)文(wén)*/
if((ret=fast_ua_init(mid,callback)))//UA模塊實例化(輸入參數1:接收模塊ID号,輸入參數2:接收報(bào)文(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)打印接收分組metadata信息
     FAST分組的數據格式請(qǐng)參考第一篇文(wén)章《二層交換機原型設計(jì)與實現(xiàn)(一)》描述。在callback函數一開(kāi)始,打印FAST分組的metadata信息和(hé)以太網協議(yì)的源和(hé)目的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)發送函數發送分組
     調用(yòng)FAST的分組發送函數,将接收到(dào)的一個分組從(cóng)指定端口發出,要特别注意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;/*報(bào)文(wén)來(lái)源爲CPU輸入,站(zhàn)在硬件角度*/
pkt->um.pktdst = 0;/*報(bào)文(wén)目的爲硬件輸出*/
pkt->um.dstmid = 5;/*直接從(cóng)硬件GOE模塊輸出,不走解析、查表等模塊*/
fast_ua_send(pkt,pkt_len);/*調用(yòng)FAST API函數發送*/
}

     該函數調用(yòng)之前,必須将pkt->um.outport字段賦值,指定分組的輸出端口号。
     1)核心函數callback
     callback函數是整個UA的核心功能(néng)函數,是用(yòng)戶業務實現(xiàn)的開(kāi)始位置。雖然我們今天隻在該函數中做了(le)兩件事(shì)情,一是打印接收到(dào)的分組基本信息,二是将該分組發送到(dào)指定端口。但(dàn)是,我們今天已經在該平台上(shàng)實現(xiàn)了(le)一個最簡單的分組轉發功能(néng)的原型系統了(le)。
     2)注釋和(hé)備份的重要性
     重新性不多說,隻是在此特别的特别的強調一下(xià)。
     3)實現(xiàn)簡單交換邏輯功能(néng)
     在如此簡單的一個平台上(shàng),能(néng)快(kuài)速實現(xiàn)硬件端口的分組接收和(hé)指定端口的分組發送,是不是網絡功能(néng)的一大(dà)部分問題均已經解決?我們隻需要關注我們具體業務的邏輯處理(lǐ)了(le),你(nǐ)到(dào)底是要實現(xiàn)交換還是路由?是普通二層交換還是SDN交換?是普通三層路由還是lisp路由或是segment路由,是不是一切均有可能(néng)?
     不要高(gāo)興得太早,這(zhè)隻是萬裏長征的第一步,起點和(hé)終點的距離必須由自(zì)己的腳步來(lái)測量,一步也(yě)不能(néng)少。所以我們還是從(cóng)簡單的二層交換機開(kāi)始,下(xià)一篇文(wén)章正式進入分組交換的設計(jì)。
      歡迎您和(hé)學生們加入FAST開(kāi)源項目群溝通與探讨,一起體驗不一樣的系統設計(jì)過程。請(qǐng)先加微信号15116127200後邀請(qǐng)入群。

關注FAST開(kāi)源社區(qū)
FAST一一開(kāi)源、開(kāi)放(fàng)、高(gāo)速、高(gāo)效、可編程、可定義!軟硬件協同并行處理(lǐ)。