函數netif_lcore_init中註冊了很多的work執行函數。
其中函數lcore_job_recv_fwd的主要代碼如下:
for (j = 0; j < lcore_conf[lcore2index[cid]].pqs[i].nrxq; j++) {
qconf = &lcore_conf[lcore2index[cid]].pqs[i].rxqs[j];
lcore_process_arp_ring(qconf, cid);
lcore_process_redirect_ring(qconf, cid);
qconf->len = netif_rx_burst(pid, qconf);
lcore_stats_burst(&lcore_stats[cid], qconf->len);
lcore_process_packets(qconf, qconf->mbufs, cid, qconf->len, 0);
kni_send2kern_loop(pid, qconf);
}
函數netif_rx_burst會從網卡的某個隊列中一次最多接收32個包。
然後交給函數lcore_process_packets來處理。此函數只做一些簡單的處理,之後對於大部分業務數據會調用函數netif_deliver_mbuf來處理:
pt = pkt_type_get(eth_type, dev);
...
mbuf->l2_len = sizeof(struct ether_hdr);
/* Remove ether_hdr at the beginning of an mbuf */
data_off = mbuf->data_off;
if (unlikely(NULL == rte_pktmbuf_adj(mbuf, sizeof(struct ether_hdr))))
return EDPVS_INVPKT;
err = pt->func(mbuf, dev);
- 查找到pkt的eth_type對應的協議處理句柄,比如ip(0x0800), ipv6(0x86dd)或者arp(0x0806),注意,這裏沒有VLAN,VLAN在上一步已經處理了。
- 如果是ARP包,且這個包不是來自於其它隊列的話,則首先在所有的隊列上泛洪。
- 調過ether hearder,然後傳遞給下一層協議處理。
ipv4的包的處理函數在文件ipv4.c中:
static struct pkt_type ip4_pkt_type = {
//.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4),
.func = ipv4_rcv,
.port = NULL,
};