DPDK L3fwd 源码阅读

本文详细介绍了DPDK L3fwd源码,主要内容包括L2fwd基础上的网络层路由查找,LPM(最长前缀匹配)和Exact Match的实现,三层转发及二层发包。LPM使用DPDK的LPM库,通过创建和插入条目进行路由。Exact Match则依赖于DPDK的hash库,采用cuckoo hash实现精确匹配。文章适合熟悉TCP/IP网络基础的读者阅读。
摘要由CSDN通过智能技术生成

代码部分

整个L3fwd有三千多行代码,但总体思想就是在L2fwd的基础上,增加网络层的根据 IP 地址进行路由查找的内容。

main.c 文件

int
main(int argc, char **argv)
{
        /*......*/

	/* init EAL */
	ret = rte_eal_init(argc, argv);
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n");

	/*......*/

	/* parse application arguments (after the EAL ones) */
	// 解析命令行参数
	ret = parse_args(argc, argv);
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n");

	 // 检查 lcore 配置数组的正确性
	if (check_lcore_params() < 0)
		rte_exit(EXIT_FAILURE, "check_lcore_params failed\n");
	// 检查 rx 队列数是否过多,把 param 的东西放到 conf 里
	ret = init_lcore_rx_queues();
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "init_lcore_rx_queues failed\n");

	nb_ports = rte_eth_dev_count(); // 获取以太网端口数量

	if (check_port_config() < 0) // 验证 port 掩码、 port id 的正确性
		rte_exit(EXIT_FAILURE, "check_port_config failed\n");

	nb_lcores = rte_lcore_count(); // 获取 lcore 数量

	/* Setup function pointers for lookup method. */
	setup_l3fwd_lookup_tables();// 设定是 Exact 还是 LPM 

	/* initialize all ports */
	// 初始化端口
	RTE_ETH_FOREACH_DEV(portid) {

	        /*......*/
		ret = rte_eth_dev_configure(portid, nb_rx_queue,
					(uint16_t)n_tx_queue, &local_port_conf); 
					// 配置以太网设备,rx 队列数量根据 param 数组来,tx 数量则是和 lcore 数量相同

		/* init memory */
		// 分配内存,设置 LPM 或 Hash 表
		ret = init_mem(NB_MBUF);
		if (ret < 0)
			rte_exit(EXIT_FAILURE, "init_mem failed\n");

		/* init one TX queue per couple (lcore,port) */
		// 设置 Tx queue,每个端口只设置一条
		queueid = 0;
		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
			
	                /*......*/
			ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
						     socketid, txconf);
			/*......*/
		}
		printf("\n");
	}

	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
                /*......*/
		// 配置 Rx 队列,每个端口上设置多条。
		for(queue = 0; queue < qconf->n_rx_queue; ++queue) {
			/*......*/
			rte_eth_dev_info_get(portid, &dev_info);
			/*......*/
			ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd,
					socketid,
					&rxq_conf,
					pktmbuf_pool[socketid]);
			/*......*/
		}
	}

	printf("\n");

	/* start ports */
	// 启用设备
	RTE_ETH_FOREACH_DEV(portid) {
		/*......*/
		/* Start device */
		ret = rte_eth_dev_start(portid);
		/*......*/
		if (promiscuous_on) // 设置混杂模式
			rte_eth_promiscuous_enable(portid);
	}

                /*......*/
		}
	}

	// 检查链路状态
	check_all_ports_link_status(enabled_port_mask);

	ret = 0;
	/* launch per-lcore init on every lcore */
	// 在每个lcore上执行函数,包括master lcore,根据选定的 LPM 还是 exact 执行对应的 main_loop 函数
	rte_eal_mp_remote_launch(l3fwd_lkp.main_loop, NULL, CALL_MASTER);
	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
		if (rte_eal_wait_lcore(lcore_id) < 0) {
			ret = -1;
			break;
		}
	}

	/* stop ports */
	RTE_ETH_FOREACH_DEV(portid) {
		if ((enabled_port_mask & (1 << portid)) == 0)
			continue;
		printf("Closing port %d...", portid);
		rte_eth_dev_stop(portid);
		rte_eth_dev_clo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值