0731-84728105
15116127200
二層交換機原型設計與實現(七)
發布時(shí)間:2021-06-09
    &校明nbsp;上一篇講述了bitmap的端口表示方法,也講了單播隻用常規方法有近表示的原因,故我們(men)隻需要對多播的轉發表進行相應的定制和線短處理即可。單播和多播的地址區分也已在上篇文章中交待清楚,鄉公本篇重點講述如(rú)何處理多播數據。
     根們訊據前篇分析,多播表的定義隻是将其端口号字麗自段的表述進行了重定義。故多播表的定義隻需要将單播表複制一份即可,隻是在處文鄉理多播數據時(shí),對端口字段的使用有些不(bù)一樣。 船黃

struct table_port_mac *obx_mc_mac_跳銀tbl = NULL;/*定義多播MAC轉發表對象為(wèi)空店科指針,将在main函數中初始地址*/
/*為(wèi)多手播MAC轉發表分配内存,并初始數據為(wèi)男海0*/
obx_mc_mac_tbl = (struct table海樹_port_mac *)malloc(sizeof(struct就機 table_port_mac));
memset(obx_mc_mac_tbl,0,s工鄉izeof(struct table_port_mac)); 電美

    &nbs場影p;本交換機原型中,我們(men)僅支持IGMP爸化 v3版本,故隻對該版本協議進行解析處理,對組播的入組與退組處理隻需要處理日房IGMPv3 的Report分組協議即可。
   校冷;  解析IGMP協議我們(men)需要關和得心的分組字段如(rú)下:
  &nbs問科p;  1)IGMP的組播IP物如地址為(wèi)224.0.0.22,多播MAC理看為(wèi):01:00:5E:00:00:16
   &nbs男議p; 2)以太網幀類型為(wèi)IPv4(0樂做x0800)
   &n月嗎bsp; 3)IP協議号為(wèi)IG光路MP(0x2)
    &n秒聽bsp;4)IGMP協議的type字段為(wèi)0x22(男坐V3 report)
   &n睡林bsp; 相關的協議數據結構定義在以下幾個系統頭文件中,将其添通子加到代碼頭部。

#include /*ethhdr*/
#include /*iphdr*/
#include /*igmvp_report*/

     1)多播火但解析
   &說樂nbsp; 多播首先判斷MAC地址的第1字節的最低(dī視弟)位,分離出多播分組,然後再精确篩選出組播入組與退黃廠組的通(tōng)告消息。

if(pkt->data[0]&0x1)//MC MAC
{
u64 igmpv3_dmac = 0x1600005E0001;雜科
if(!ether_addr_equal(pkt->data,(u8 *友學)&igmpv3_dmac)) //IGMP
{
struct ethhdr *eth = (stru報村ct ethhdr *)pkt->data;
struct iphdr *ip = (struct iph劇可dr *)(eth+1);
int oft = 0;
if(eth->h_proto = htons(0x0800) && ip-器放>protocol == IPPROTO_IGMP)
{
oft = sizeof(*eth) + ip->計友ihl * sizeof(int);
igmpv3_report(pkt->um.inport,pkt->data+技裡oft);
}
}
}

    舞裡 2)多播學習
    開喝; 精确篩選出IGMP的Repor說笑t分組後,便可根據協議字段區分是入組消息或是退組如不消息。該步最核心的一步是要将IGMP中的組播紅文IP地址轉換為(wèi)多播MAC,并将該MAC消息學習到多播MAC轉發表事子中。多播MAC的轉換規則有明确的定義要求,簡言之就是MAC但河地址由三部分組成:高24位固定為(wèi)01:00:5E,第2歌船3位為(wèi)0,低(dī)23位為(wèi)組播IP的低(dī湖校)23位。

void igmpv3_report河答(u8 inport,u8 *igmp)
{
struct igmpv3_report *上志g3r = (struct igmpv3_report *)ig唱他mp;
if(g3r->type == IGMPV3_HOST_MEMBER照短SHIP_REPORT)/*IGMPv3_聽也REPORT*/
{
u8 mc_mac[MAC_LEN] = {0x01,0話下0,0x5E};
u8 *mcip = NULL;
int k = 0;
for(;kngrec);k++)
{
mcip = (u8 *)&g3r->grec[k].grec_mca;黃但
memcpy(&mc_mac[3],&mcip[1],3);下她/*僅複制後3字節數據*/
mc_mac[3] &= 0x7F;/*将第23bi從做t置0*/
join_leave_mc_mac(inport,m現習c_mac,g3r->grec[k].grec_type花工);
}
}
}

    &nbs林女p;多播MAC的學習過程封裝在join_leave_mc_mac函數中,其核內他心操作方法與單播MAC的學習過程類似,隻是在對端口号的處理不店民(bù)同。

if(type == IGMPV3_CHANGE_TO_個文EXCLUDE)/*入組*/
{
obx_mc_mac_tbl->row[i].port 也腦|= 1<<>
}
else/*退組*/
{
obx_mc_mac_tbl->row[i]我錯.port &= ~ (1<<>
}

     3)數些多播查表
  &nbs分站p;  多播的查表與單播完也拍全一緻,隻是查表的對象換成多播表,這兩個查表過程可以代碼優化成好愛一個功能函數。
    熱服 4)多播輸出
    &nb不山sp;多播的輸出端口信息存儲在返回值的每個bi算舊t位上,故需要根據輸出端口的bit位是否為(wèi)1來作為(wèi錯熱)分組輸出判斷依據。單播和多播的統一輸出函數如(rú)下:

void output(u8 outtype,in人相t outport,struct fas玩兒t_packet *pkt)
{
if(outtype == UC)
{
pkt->um.outport = outport;
pkt_send_normal(pkt,pkt->um.len);
}
else
{
int i = 0;
for(;i<>
{
if(pkt->um.inport != i && (outport 器說& (1< 0)
{
pkt->um.outport = i;
pkt_send_normal(pkt,pkt-遠靜>um.len);
}
}
}
}

   的河  一定要記得(de),底層麗呢API的輸出端口号是常規表示方法,在多播輸出時舞錯(shí)的端口号應該是變量i的值。 訊務
     章市1)确定協議支持
     硬件适合做煙報簡單、确定的事情,軟件适合做靈活多變的事情。故若在硬件中支持組播書長的加入和退出,簡單實現就是支持确定性的IGMPv3協議的Rep間子ort功能,硬件可以不(bù)像軟件一下逐層解析協議,可以直接将對應長秒幾個位置的數據都取出來之後一次判斷,符合要求的消息即可繼續完成後續功能哥外。硬件不(bù)如(rú)軟件靈活,對每一種确定協議的支持都需這工要确定的邏輯支撐,所以對于比較複雜的協議交互,一般在要畫報設備中加入輕量級的CPU進行處理。一般像确定的組播樂校協議可以放到FPGA實現,而生成樹協議不(bù)适合FP懂謝GA實現。
     2你事)MAC表的老化
     年弟;老化簡單來說(shuō)就是删除長(cháng)時(shí)間不(bù)使用熱木的表項,把空間留出來給新的MAC地址使用。老化是為(wèi)間間了解決MAC地址數量大(dà)于轉發表空間容量的問題。若有些MAC地址使用女錢一段時(shí)間之後,就一直不(bù)再使用森說或關機,則交換機無需再保留其在MAC轉發表中。若不(b不愛ù)删除,則會(huì)導緻新的MAC表找不(bù)到存儲空間,導緻廠畫大(dà)量的數據轉化為(wèi)泛洪發送,對整個網絡來說(sh用湖uō)是災難性的,不(bù)可容忍的。當然,不(bù)計成本的個現擴大(dà)存儲容量更是不(bù)可取的。故MAC表的老化的行是十分必要的,下篇主要内容講述MAC表老化。
    那懂;  歡迎您和學生們(men)加入從睡FAST開(kāi)源項目群溝通(tōng)與林我探讨,一起體驗不(bù)一樣的系統設計過程。請先加微信号15116制月127200後邀請入群。

關注FAST開(kāi)源社區 子作
FAST一一開(kāi)源、開(kāi)放、高速、高效、可編程、器歌可定義!軟硬件協同并行處理。