dpdk flow 的简单使用

文章目录

前言

本文介绍dpdk flow api的简单使用。

dpdk flow 的使用过程和 iptables 差不多。即,数据包匹配上指定的规则后,执行对应的动作。

本文示例代码来自Basic RTE Flow Filtering Sample Application

这篇内容还是"水"了点。随手笔记吧。


基本概念

总的来说:dpdk flow 可以对数据包的协议头等进行匹配。可能执行的动作是丢弃流量,将流量转移到指定队列等。

dpdk flow 有这些基本概念:

  1. Attributes: 数据流规则的属性,如其方向(入口或出口)和优先级。(这里面还有个group属性。 group 0是默认必经过的。如果想到其他group,需要执行JUMP操作。其他group中有不同的action。这些group可能被物理设备支持,或者以虚拟的方式支持。示例代码中没有显示使用group,可以暂时不管)
  2. Pattern item: 描述匹配的样式。即,什么样的包会命中样式。
  3. Actions: 当数据包与样式匹配时,执行的操作。

示例代码说明

下面这个示例代码来自"前言"中的链接。含义是,当port_id端口进入的数据包,满足src_ip/mask -> dst_ip/mask的pattern时,将其转移到rx_q队列上。

代码还是比较简单的。我简单介绍下。

  1. Attributes 在dpdk中的结构体是rte_flow_attrattr.ingress = 1; 表示 Pattern 将应用在入站流量上。
  2. Pattern 在dpdk中的结构是rte_flow_item。代码中填充了一个src_ip/mask -> dst_ip/mask样式。
  3. Actions 在dpdk中的结构是rte_flow_action。代码中填充了一个将流量转移到指定队列的动作。
  4. 相关函数:rte_flow_create则是在指定端口上,创建一个flow rule。
c 复制代码
/**
 * create a flow rule that sends packets with matching src and dest ip
 * to selected queue.
 *
 * @param port_id
 *   The selected port.
 * @param rx_q
 *   The selected target queue.
 * @param src_ip
 *   The src ip value to match the input packet.
 * @param src_mask
 *   The mask to apply to the src ip.
 * @param dest_ip
 *   The dest ip value to match the input packet.
 * @param dest_mask
 *   The mask to apply to the dest ip.
 * @param[out] error
 *   Perform verbose error reporting if not NULL.
 *
 * @return
 *   A flow if the rule could be created else return NULL.
 */

/* Function responsible for creating the flow rule. 8< */
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) {
  /* Declaring structs being used. 8< */
  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;
  /* >8 End of declaring structs being used. */
  int res;

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

  /* Set the rule attribute, only ingress packets will be checked. 8< */
  memset(&attr, 0, sizeof(struct rte_flow_attr));
  attr.ingress = 1;
  /* >8 End of setting the rule attribute. */

  /*
   * create the action sequence.
   * one action only,  move packet to queue
   */
  action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
  action[0].conf = &queue;
  action[1].type = RTE_FLOW_ACTION_TYPE_END;

  /*
   * set the first level of the pattern (ETH).
   * since in this example we just want to get the
   * ipv4 we set this level to allow all.
   */

  /* Set this level to allow all. 8< */
  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
  /* >8 End of setting the first level of the pattern. */

  /*
   * setting the second level of the pattern (IP).
   * in this example this is the level we care about
   * so we set it according to the parameters.
   */

  /* Setting the second level of the pattern. 8< */
  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;
  /* >8 End of setting the second level of the pattern. */

  /* The final level must be always type end. 8< */
  pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
  /* >8 End of final level must be always type end. */

  /* Validate the rule and create it. 8< */
  res = rte_flow_validate(port_id, &attr, pattern, action, error);
  if (!res)
    flow = rte_flow_create(port_id, &attr, pattern, action, error);
  /* >8 End of validation the rule and create it. */

  return flow;
}
/* >8 End of function responsible for creating the flow rule. */

最后

我们现在已经了解了 dpdk flow 最简单的使用了。难度大概是 "1+1=2"。

如果想要在日常工作中使用dpdk flow, 难度大概是解二元一次方程,需要看更多的示例代码。

相关推荐
flysnow01011 天前
WSL(Ubuntu20.04)编译和安装DPDK
dpdk·1024程序员节
彭泽布衣1 个月前
解读: 火山引擎自研vSwitch技术
dpdk·火山引擎·ovs·云网络·vswitch
别NULL2 个月前
DPDK 简易应用开发之路 2:UDP数据包发送及实现
linux·网络·网络协议·udp·dpdk
别NULL2 个月前
DPDK基础入门(十):虚拟化
linux·网络·tcp/ip·dpdk
Once_day4 个月前
DPDK源码分析之(1)libmbuf模块补充
dpdk
墨染 锦年4 个月前
DPDK概述
笔记·学习·dpdk·uio·igb-uio
小勇者5 个月前
【DPDK学习路径】八、轮询
dpdk
写一封情书5 个月前
tldk之tle简单记录
dpdk·tldk·tle
范桂飓5 个月前
Intel HDSLB 高性能四层负载均衡器 — 基本原理和部署配置
运维·负载均衡·dpdk