議棧(四):實(shí)現(xiàn) ICMP Echo Reply,讓 ping 通起來)
目錄手寫 DPDK 協(xié)議棧四實(shí)現(xiàn) ICMP Echo Reply讓 ping 通起來1. Echo 報(bào)文結(jié)構(gòu)2. 接收并定位協(xié)議頭3. 原地改包與重算校驗(yàn)和4. 實(shí)驗(yàn)結(jié)果小結(jié)手寫 DPDK 協(xié)議棧四實(shí)現(xiàn) ICMP Echo Reply讓 ping 通起來標(biāo)簽DPDKICMPpingIPv4icmp/icmp.c將 ARP 之后的 IPv4 分流繼續(xù)推進(jìn)到 ICMP。Echo Request/Reply 是最適合驗(yàn)證三層收發(fā)正確性的協(xié)議不需要端口和連接狀態(tài)但要求正確交換地址并重算校驗(yàn)和。1. Echo 報(bào)文結(jié)構(gòu)ICMP Echo: | Type 1B | Code 1B | Checksum 2B | Identifier 2B | Sequence 2B | Data N字節(jié) | 字段 長(zhǎng)度 Request Reply 作用 type 1 字節(jié) 8 0 ICMP 消息類型。8 表示 ping 請(qǐng)求0 表示 ping 應(yīng)答。 code 1 字節(jié) 0 0 類型下的細(xì)分原因。Echo 類型里固定為 0。 checksum 2 字節(jié) 計(jì)算值 重新計(jì)算值 ICMP 校驗(yàn)和覆蓋 ICMP 頭 ICMP 數(shù)據(jù)不包含 IP 頭也沒有 UDP/TCP 那種偽首部。 identifier 2 字節(jié) 請(qǐng)求方設(shè)置 原樣返回 標(biāo)識(shí)一次 ping 會(huì)話常用于區(qū)分不同進(jìn)程或不同 ping 實(shí)例。 sequence 2 字節(jié) 請(qǐng)求方遞增 原樣返回 序列號(hào)用來判斷第幾個(gè) Echo 包也用于計(jì)算丟包和 RTT。 data N 字節(jié) 任意數(shù)據(jù) 原樣返回 ping 負(fù)載。Reply 必須把 Request 的數(shù)據(jù)原樣帶回去。請(qǐng)求type8應(yīng)答type0identifier、sequence和 payload 都應(yīng)原樣返回。ICMP 校驗(yàn)和覆蓋 ICMP 頭和數(shù)據(jù)不包含 IP 偽首部。2. 接收并定位協(xié)議頭structrte_ether_hdr*ethrte_pktmbuf_mtod(mbuf,structrte_ether_hdr*);structrte_ipv4_hdr*iprte_pktmbuf_mtod_offset(mbuf,structrte_ipv4_hdr*,sizeof(*eth));if(ip-next_proto_id!IPPROTO_ICMP)return;structrte_icmp_hdr*icmp(structrte_icmp_hdr*)(ip1);if(icmp-icmp_type!RTE_IP_ICMP_ECHO_REQUEST)return;示例假定 IPv4 頭為標(biāo)準(zhǔn) 20 字節(jié)。更通用的實(shí)現(xiàn)應(yīng)從version_ihl得到IHL * 4并對(duì) mbuf 長(zhǎng)度、IP 總長(zhǎng)度做邊界檢查。3. 原地改包與重算校驗(yàn)和icmp-icmp_typeRTE_IP_ICMP_ECHO_REPLY;icmp-icmp_code0;icmp-icmp_cksum0;icmp-icmp_cksumrte_raw_cksum(icmp,icmp_len);ip-hdr_checksum0;ip-hdr_checksumrte_ipv4_cksum(ip);/* 交換 Ethernet 和 IPv4 的源、目的地址后發(fā)送 */原地回包可減少一次分配但一定要在發(fā)送前同時(shí)交換二層和三層地址并在所有字段更新完成后重新計(jì)算校驗(yàn)和。4. 實(shí)驗(yàn)結(jié)果ping成功意味著主機(jī)已通過 ARP 找到 DPDK 網(wǎng)卡 MACDPDK 正確解析 IPv4/ICMP且回包的以太網(wǎng)頭、IP 頭與 ICMP 校驗(yàn)和全部有效。小結(jié)ICMP 是第一個(gè)“真正穿過 IPv4”的協(xié)議實(shí)驗(yàn)。它驗(yàn)證了偏移解析、網(wǎng)絡(luò)字節(jié)序、校驗(yàn)和和回包地址交換為 UDP、TCP 的組包與分發(fā)打下了同一套基礎(chǔ)。學(xué)習(xí)鏈接: https://github.com/0voice