冷船 上一(yī)篇講述了bitmap的端口表示方服電法,也講了單播隻用常規方法表示的原因,故我(wǒ)(wǒ少開)們隻需要對多播的轉發表進行相應的定制和處理即可。單播他水和多播的地址區分(fēn)也已在上篇文章中上頻(zhōng)交待清楚,本篇重點講述如何處理多播數據。
&nb個愛sp;根據前篇分(fēn)析,多播表的定義隻是将其端讀麗口号字段的表述進行了重定義。故多播表的定義隻需要将習下單播表複制一(yī)份即可,隻是在處理多播妹離數據時,對端口字段的使用有些不一(yī)樣。
struct table_port_mac *ob兒鄉x_mc_mac_tbl = NULL;/*定義多播M匠器AC轉發表對象爲空指針,将在main函數中(zhōng)初始地新新址*/
/*爲多手播MAC轉發表分(fēn)配内高師存,并初始數據爲0*/
obx_mc_mac_tbl = (struct table_port_ma但是c *)malloc(sizeof(struct table_port_mac路媽));
memset(obx_mc_mac_tbl,0,sizeof做議(struct table_port_mac));
&nbs姐謝p; 本交換機原型中(zhōng),我(工刀wǒ)(wǒ)們僅支持IGMP v3版本,故隻對該版本協議進行解析處理,紅做對組播的入組與退組處理隻需要處理IGMPv3 的Repor銀件t分(fēn)組協議即可。
&nbs下件p; 解析IGMP協議我(wǒ)煙草(wǒ)們需要關心的分(fēn)組字段如下(xià):
&數生nbsp;1)IGMP的組播IP地址爲224.0.0弟員.22,多播MAC爲:01:00:5E:00:00:16
&n劇懂bsp; 2)以太網幀類型爲IPv4(0x0800)
&nb上在sp; 3)IP協議号爲IGMP(0x2)
4)IGMP協議暗來的type字段爲0x22(V3 report)
&nbs爸靜p; 相關的協議數據結構定義在以下(x錢個ià)幾個系統頭文件中(zhōng),将其添加到代碼頭部。
玩綠
#include /*ethhdr*/
#include /*iphdr*/
#include /*igmvp_report*/
&nb電畫sp; 1)多播解析
多播首先購員判斷MAC地址的第1字節的最低位,分(fēn姐志)離(lí)出多播分(fēn)組,然後再精确篩選出姐冷組播入組與退組的通告消息。
if(pkt->data[0]&0x1)//MC MAC
{
u64 igmpv3_dmac = 0x160000放秒5E0001;
if(!ether_addr_equal(車嗎pkt->data,(u8 *)&igmpv3房錢_dmac)) //IGMP
{
struct ethhdr *eth = (struct ethhd白大r *)pkt->data;
struct iphdr *ip = (struct iphdr *)(eth河舊+1);
int oft = 0;
if(eth->h_proto = htons線下(0x0800) && ip->protocol == IP月工PROTO_IGMP)
{
oft = sizeof(*eth) + ip->ihl * s不子izeof(int);
igmpv3_report(pkt->um.inpor慢事t,pkt->data+oft);
}
}
}
&nbs們店p; 2)多播學習
 長票; 精确篩選出IGMP的Report分(fē醫少n)組後,便可根據協議字段區分(fēn)是入組消息或是退組消息。該都匠步最核心的一(yī)步是要将IGMP中(zhōng)的組播I的要P地址轉換爲多播MAC,并将該MAC消息學習到多播MAC轉發表中跳鐵(zhōng)。多播MAC的轉換規則有明訊高确的定義要求,簡言之就是MAC地址由三部分(fēn)組成:高24位固定鄉你爲01:00:5E,第23位爲0,低23位爲組播IP的低23位。
月樹
void igmpv3_report(u8 inport,答話u8 *igmp)
{
struct igmpv3_report *g3r = (struct 什討igmpv3_report *)igmp;
if(g3r->type == IGMPV3_腦近HOST_MEMBERSHIP_REPORT空子)/*IGMPv3_REPORT*/
{
u8 mc_mac[MAC_LEN] = {0x01,如那00,0x5E};
u8 *mcip = NULL;
int k = 0;
for(;kngrec);k++)
{
mcip = (u8 *)&g3r->grec[k].gre河姐c_mca;
memcpy(&mc_mac[3],&mcip[1],白有3);/*僅複制後3字節數據*/
mc_mac[3] &= 0x7F;/*将第23bit置0*/能北
join_leave_mc_mac(inport,mc_mac,g時黑3r->grec[k].grec_type);
}
}
}
多播師著MAC的學習過程封裝在join_leave_m光外c_mac函數中(zhōng),其核心操作方法與單播術計MAC的學習過程類似,隻是在對端口号的處理不同。
if(type == IGMPV3_CHA風習NGE_TO_EXCLUDE)/*入組*/
{
obx_mc_mac_tbl->row[i]外靜.port |= 1<<>
}
else/*退組*/
{
obx_mc_mac_tbl->row[i].port &=地資 ~ (1<<>
}
暗見 3)多播查表
&n店亮bsp;多播的查表與單播完全一(yī)緻,隻是相銀查表的對象換成多播表,這兩個查表過程可以代碼優化成一筆少(yī)個功能函數。
&nbs體玩p; 4)多播輸出
工我
我年 多播的輸出端口信息存儲在返回值的每個bit位上,故相小需要根據輸出端口的bit位是否爲1來作爲分(fēn)討多組輸出判斷依據。單播和多播的統一(yī)輸出函訊線數如下(xià):
void output(u8 outtype,int outport,str書子uct fast_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->u匠我m.len);
}
}
}
}
 國技; 一(yī)定要記得,底層熱金API的輸出端口号是常規表示方法,在多播輸出時的端口号應該是變量i的值。樂畫
&n笑城bsp;1)确定協議支持
&n員亮bsp;硬件适合做簡單、确定的事情,軟件适合做靈活多變的事答答情。故若在硬件中(zhōng)支持組播的加入和退出,簡單實現就是看樂支持确定性的IGMPv3協議的Report功能,硬件可以不像軟件一(yī紅謝)下(xià)逐層解析協議,可以直接将對應幾個位置熱見的數據都取出來之後一(yī)次判斷,符合要求的消息即可繼續完成後續功能。硬件不知喝如軟件靈活,對每一(yī)種确定協議的支持都需要确定的邏輯支撐,所以對于比較笑我複雜(zá)的協議交互,一(yī)般在要設備船懂中(zhōng)加入輕量級的CPU進行處理人化。一(yī)般像确定的組播協議可以放(f亮明àng)到FPGA實現,而生(shēng)成樹(shù)協議不适合吃山FPGA實現。
工飛2)MAC表的老化
&nb動你sp; 老化簡單來說就是删除長時間遠年不使用的表項,把空間留出來給新的MAC地址使用。老化是爲了解決MA年亮C地址數量大(dà)于轉發表空間容量的問題。若制好有些MAC地址使用一(yī)段時間之後,就一(哥聽yī)直不再使用或關機,則交換機無需再保留其在MAC轉發表中(zhō草請ng)。若不删除,則會導緻新的MAC表找不到存話山儲空間,導緻大(dà)量的數據轉化爲泛洪發送,對整個網絡來說校快是災難性的,不可容忍的。當然,不計成本的擴月也大(dà)存儲容量更是不可取的。故MAC表的老化是十分(fēn)必要的哥飛,下(xià)篇主要内容講述MAC表老化。
&亮能nbsp;
歡迎您和學很又生(shēng)們加入FAST開(kāi你訊)源項目群溝通與探讨,一(yī)起體(tǐ)驗不一(yī)樣的系都媽統設計過程。請先加微信号15116127200後邀請入群。
關注FAST開(kāi)源社區
FAST一(yī)一(yī)開(kāi)源、低姐開(kāi)放(fàng)、高速、高效、可編程、可定義!軟硬件協明聽同并行處理。