当前的高性能网卡通常都支持对数据流的定向和过滤功能,可通过配置将指定的数据流定向到指定的设备队列中,并且如果监听此队列的核心正是运行处理此数据流的应用所在核心,将获得一定的性能优势。另外网卡的流过滤功能还可设定丢弃指定的流,可实现在硬件层面屏蔽非法的访问等,而不需要处理器的干预。
DPDK的示例flow_filtering演示第一种流定向功能。
该示例flow_filtering用于配置网卡的流过滤规则,完成匹配数据流的设备队列定向功能。主函数是通用的初始化流程:包括EAL初始化,分配存储mbuf的内存池mempool,初始化接口init_port函数。DPDK的此示例使用一个port接口就可运行。随后调用完成流规则配置的函数generate_ipv4_flow。当然网卡的流过滤规则除了本例的队列定向功能,还有其它的功能,比如丢弃匹配的流等。
int main(int argc, char **argv)
{
ret = rte_eal_init(argc, argv);
nr_ports = rte_eth_dev_count_avail();
if (nr_ports == 0)
rte_exit(EXIT_FAILURE, ":: no Ethernet ports found\n");
port_id = 0;
if (nr_ports != 1) {
printf(":: warn: %d ports detected, but we use only one: port %u\n", nr_ports, port_id);
}
mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", 4096, 128, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if (mbuf_pool == NULL)
rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
init_port();
flow = generate_ipv4_flow(port_id, selected_queue, SRC_IP, EMPTY_MASK, DEST_IP, FULL_MASK, &error);
if (!flow) {
printf("Flow can't be created %d message: %s\n", error.type, error.message ? error.message : "(no stated reason)");
rte_exit(EXIT_FAILURE, "error in creating flow");
}
main_loop();
return 0;
}
函数generate_ipv4_flow完成流规则配置功能,其实现将设定的数据流定向到指定的设备队列中。由以下的四个宏定义可知,本例要定向的流为:源IP地址为0.0.0.0,mask为空EMPTY_MASK(0),即不区分源IP,目的IP地址为192.168.1.1,掩码为FULL_MASK(0xffffffff)。即所有目的地址为192.168.1.1的数据流,定向到设备的队列1中(selected_queue)。
static uint8_t selected_queue = 1;
#define SRC_IP ((0<<24) + (0<<16) + (0<<8) + 0) /* src ip = 0.0.0.0 */
#define DEST_IP ((192<<24) + (168<<16) + (1<<8) + 1) /* dest ip = 192.168.1.1 */
#define FULL_MASK 0xffffffff /* full mask */
#define EMPTY_MASK 0x0 /* empty mask */
1. 首先,设置流的属性rte_flow_attr为ingress,即要操作的数据流为接收方向。