函数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,
};