rte_flow流规则的创建流程

本文详细介绍了如何使用DPDK的rte_flow功能,通过实例展示了如何针对特定目的IP创建规则,使报文进入指定网卡的rx队列。涉及关键步骤包括设置流规则属性、创建匹配模式和动作,以及校验和创建flow。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rte_flow的创建流程

DPDK通过rte_flow提供的流控制功能,通过dpdk example中的flow_filtering实例,可以看到rte_flow的简单应用。实例实现的功能为:针对指定目的IP的报文,进入指定的网卡rx队列。实现步骤如下:

  1. 创建struct rte_flow_attr,指定匹配报文的方向。
  2. 创建struct rte_flow_action,指定动作类型为报文通过特定rx队列接收。
  3. 创建struct rte_flow_item,指定匹配报文的IP地址。
  4. 调用rte_flow_validate校验创建flow的参数是否合理。
  5. 调用rte_flow_create创建flow,并下发配置到网卡。

源码如下:

struct rte_flow *
generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,
		uint32_t src_ip, uint32_t src_mask,
		uint32_t dest_ip, uint32_t dest_mask,
		struct rte_flow_error *error)
{
	struct rte_flow_attr attr;
	struct rte_flow_item pattern[MAX_PATTERN_NUM];
	struct rte_flow_action action[MAX_ACTION_NUM];
	struct rte_flow *flow = NULL;
	struct rte_flow_action_queue queue = { .index = rx_q };
	struct rte_flow_item_ipv4 ip_spec;
	struct rte_flow_item_ipv4 ip_mask;
	int res;

	memset(pattern, 0, sizeof(pattern));
	memset(action, 0, sizeof(action));

	memset(&attr, 0, sizeof(struct rte_flow_attr));
	attr.ingress = 1;//过滤入方向

	//rte_flow_action的type指定动作类型,conf指定动作对象
	//RTE_FLOW_ACTION_TYPE_QUEUE : 动作类型:将流发给指定队列
	//conf : 动作对象:指定的队列号
    //action数组RTE_FLOW_ACTION_TYPE_END结束
	action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
	action[0].conf = &queue;
	action[1].type = RTE_FLOW_ACTION_TYPE_END;

	//pattern[0] : eth header不做限制
	pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;

	//pattern[1] : 针对IP header,匹配指定src dst地址
	memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4));
	memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4));
	ip_spec.hdr.dst_addr = htonl(dest_ip);
	ip_mask.hdr.dst_addr = dest_mask;
	ip_spec.hdr.src_addr = htonl(src_ip);
	ip_mask.hdr.src_addr = src_mask;
	pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
	pattern[1].spec = &ip_spec;
	pattern[1].mask = &ip_mask;

	//pattern数组必须使用RTE_FLOW_ITEM_TYPE_END结束
	pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
	//flow校验
	res = rte_flow_validate(port_id, &attr, pattern, action, error);
	printf("err after rte_flow_validate : %s\n", error->message);
	//在指定的port上创建flow
	//if (!res) {
		flow = rte_flow_create(port_id, &attr, pattern, action, error);
		printf("err after rte_flow_create : %s\n", error->message);		
	//}

	return flow;
}

流规则创建相关API

rte_flow_item_ipv4

使用dpdk提供的rte_flow_item_ipv4记录IP头部信息。

struct rte_flow_item_ipv4 {
	struct ipv4_hdr hdr; /**< IPv4 header definition. */
};

rte_flow_validate

用于校验指定网口是否有能力创建指定的流规则。

int
rte_flow_validate(uint16_t port_id,
		  const struct rte_flow_attr *attr,
		  const struct rte_flow_item pattern[],
		  const struct rte_flow_action actions[],
		  struct rte_flow_error *error);
- 返回值 : 校验成功返回0,失败返回负数
- port_id : 网卡ID
- attr : 流规则属性
- pattern : 流规则模式
- actions : 流规则动作
- error : 发生错误时的错误信息,通过error->message打印

rte_flow_create

创建流规则,并将流规则下发到网卡。

struct rte_flow *
rte_flow_create(uint16_t port_id,
		const struct rte_flow_attr *attr,
		const struct rte_flow_item pattern[],
		const struct rte_flow_action actions[],
		struct rte_flow_error *error)
- 返回值 : 返回rte_flow类型实例
- port_id : 网卡ID
- attr : 流规则属性
- pattern : 流规则模式
- actions : 流规则动作
- error : 发生错误时的错误信息,通过error->message打印

rte_flow_destroy

删除指定port上的一条指定流规则。

int rte_flow_destroy(uint8_t port_id,
                     struct  rte_flow* flow,
                     struct  rte_flow_error* error);
- 返回值 : 成功返回0,失败返回负数
- port_id : 网卡ID
- flow : 待删除的流规则
- error : 发生错误时的错误信息,通过error->message打印

rte_flow_flush

清除port上的所有流规则

int
rte_flow_flush(uint16_t port_id,
	       struct rte_flow_error *error)
- 返回值 : 成功返回0,失败返回负数
- port_id : 网卡ID
- error : 发生错误时的错误信息,通过error->message打印

rte_flow_query

查询流规则是否存在

int rte_flow_query(uint8_t port_id,
                   struct rte_flow *flow,
                   enum rte_flow_action_type action,
                   void *data,
                   struct rte_flow_error *error);
- 返回值 : 成功返回0,失败返回负数
好的,我来为您介绍一下DPDK中RTE_FLOW_ACTION_TYPE_COUNT action的用法。 RTE_FLOW_ACTION_TYPE_COUNT是DPDK中用于量控制的一种动作类型,它可以将匹配的量复制到一个或多个端口或队列中。这种动作通常用于量监控、镜像或分等场景。 以下是RTE_FLOW_ACTION_TYPE_COUNT action的主要用法: 1. 基本概念: - COUNT动作可以将匹配的量复制到多个目标端口或队列。 - 原始量仍会被正常处理和转发。 - COPY动作不会修改原始数据包。 2. 主要参数: - actions: 包含一个或多个动作的数组。 - nb_actions: 动作数组中的动作数量。 3. 动作类型: - PORT: 将数据包复制到指定端口。 - QUEUE: 将数据包复制到指定队列。 4. 使用示例: ```c struct rte_flow_action_copy copy_actions[] = { { .type = RTE_FLOW_ACTION_TYPE_PORT, .conf = &port_conf, }, { .type = RTE_FLOW_ACTION_TYPE_QUEUE, .conf = &queue_conf, }, }; struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_COPY, .conf = copy_actions, }, // 其他动作... }; struct rte_flow_attr attr = {0}; struct rte_flow *flow = rte_flow_create(port_id, &attr, actions, NULL, NULL); ``` 5. 注意事项: - COPY动作通常需要与其他动作组合使用。 - 过多的COPY动作可能会影响性能。 - 某些硬件可能对COPY动作的实现方式有所不同。 6. 优点: - 灵活: 可以将量复制到多个目标。 - 性能高: 硬件加速,不会显著影响原始量处理。 - 保持原始数据完整性: 不会修改原始数据包。 使用RTE_FLOW_ACTION_TYPE_COUNT action可以有效地实现复杂的多处理需求,提高量监控和分析的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值