DPDK的l2fwd实例分析

l2fwd应用程序为RX_PORT上接收的每个数据包执行二层转发。 目标端口是启用的端口掩码的相邻端口,即,如果启用前四个端口(端口掩码0xf,每个端口用一个比特位表示,启动4个就是4个比特位置1),端口1和2相互转发,端口3和4相互转发。 此外,如果启用了MAC地址更新,则MAC地址按照如下方式更新:

数据包的源mac会变成发送端口的mac地址

数据包的目的mac会变成02:00:00:00:00:发送端口的ID

也就是说在不开启mac地址更新的情况下,仅仅对数据包进行紧邻端口的转发不对数据包的mac地址进行修改,如果开启的话,会对需要转发的数据包的mac地址按照如上的规则进行更新。

参照官网给出的图,转发的模式如下

也就是说端口0和端口1是相邻的两个端口,2和3是相邻的两个端口,0口进的数据包会从1口发出,1口进的数据包会从0口发出,同理2和3两个端口的转发逻辑也是一样的。

现在对源码做一下跟读,从main函数开始

1. 命令行参数解析

命令行函数由两部分构成:EAL参数和应用程序参数分别由rte_eal_init函数和l2fwd_parse_args函数来解析

//1. 解析命令行参数
	/* init EAL */
	ret = rte_eal_init(argc, argv); // 解析命令行EAL参数 环境初始化
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
	argc -= ret;
	argv += ret;// 跳过EAL参数 参数的数量减小 同时指针后移

	force_quit = false; // 终止main loop中while循环的变量
	signal(SIGINT, signal_handler); // 利用signal函数来处理接收到的信号
	signal(SIGTERM, signal_handler);

	/* parse application arguments (after the EAL ones) */
	ret = l2fwd_parse_args(argc, argv); // 解析应用参数
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");

rte_eal_init不仅有解析命令行参数的作用还会进行复杂的环境初始化,l2fwd_parse_args函数则主要是用来解析应用程序的参数,这个函数的主体是一个switch,这个switch有三个case,也就是对命令行里输入的-p,-q,-T的解析

		switch (opt) {
		/* portmask */
		case 'p': // 解析-p参数 要配置的端口的掩码
			l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg);
			if (l2fwd_enabled_port_mask == 0) {
				printf("invalid portmask\n");
				l2fwd_usage(prgname);
				return -1;
			}
			break;
		/* nqueue */
		case 'q': // 每一个逻辑核处理多少个端口
			l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg);
			if (l2fwd_rx_queue_per_lcore == 0) {
				printf("invalid queue number\n");
				l2fwd_usage(prgname);
				return -1;
			}
			break;
		/* timer period */
		case 'T': // 设置打印端口数据的周期
			timer_secs = l2fwd_parse_timer_period(optarg);
			if (timer_secs < 0) {
				printf("invalid timer period\n");
				l2fwd_usage(prgname);
				return -1;
			}
			timer_period = timer_secs;
			break;
		/* long options */
		case 0:
			break;
		default:
			l2fwd_usage(prgname);
			return -1;
		}

可以看的出来-p会对l2fwd_enabled_port_mask变量赋值,这个值表示的就是端口掩码,也就是一个比特位表示一个端口,如果这个端口开启,就把对应的比特位置1,-q会对l2fwd_rx_queue_per_lcore变量赋值,表示的是每个逻辑核处理多少个端口。-T会对timer_period变量赋值,也就是打印端口数据的周期

 

2. 创建mbuf池

命令行参数解析完以后,会创建mbuf池,mbuf pool里边包含很多mbuf对象,mbuf对象用来存储网络数据包

//2. 创建mnuf池
	/* create the mbuf pool */
	l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, // 从已分配的大页中创建内存池
		MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
		rte_socket_id());
	if (l2fwd_pktmbuf_pool == NULL)
		rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
	nb_ports = rte_eth_dev_count(); // 获取全部开启的端口的数量
	if (nb_ports == 0)
		rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");

其中l2fwd_pktmbuf_pool是rte_mempool结构体,他是用于处理对象池的通用结构,这里创建的mbuf的数量是NB_MBUF,各mbuf的大小是RTE_MBUF_DEFAULT_BUF_SIZE。

 

  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值