searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

dpdk rte_flow 简介

2023-03-31 08:39:44
511
0

1 简介

Nic网卡有流分类处理功能,是指网卡在收包时,将符合某种规则的包放入指定的队列。网卡一般支持一种或多种流分类能,而且不同的网卡可能支持不同种类的filter,例如intel 82599系列网卡支持n-tuple、L2_tunnel、flow director等。即使intel 82599系列网卡和intel 700系列网卡都支持flow director,它们支持的方式也不一样。

dpdk要支持各种类型网卡,就要为所有网卡抽象出统一的属性,但是某些属性只对一种网卡有意义,比如并不是所有的网卡都关注flow_type 和is_vf,比如intel 82599系列网卡不需要flow_type及is_vf。还有那些可选或者可缺省的属性容易让用户产生疑惑。经常在某种filter类型中随意插入一些某个网卡特有的属性。其次,随着DPDK支持的网卡越来越多,DPDK需要定义的filter类型要增加,网卡filter功能升级也需要DPDK作相应修改,这样很容易导致API/ABI的破坏。

鉴于上述原因,一个generic flow API必不可少,rte_flow由此产生。

rte_flow主要是用来配置流量,主要就是match和action。match包括了报文信息(比如协议头、payload)和属性(物理端口、虚拟设备ID等);action包括了drop、转发到指定的queues或者物理设备或者虚拟设备、执行tunnel offload、添加标记等。此类API提供了一种通用的方式来配置硬件以匹配特定的 Ingress 或 Egress 流量,根据用户的任何配置规则更改其操作及查询相关计数器。所有API带有前缀 rte_flow ,在文件 rte_flow.h 中定义。

在OVS-DPDK应用场景里OVS可以通过rte_flow将部分网卡支持的flow pattern(eth+vlan+ip+tcp/udp)以及相应的action(如queue/mark/drop/rss等)下发至网卡,这样可以在网卡收包方向“部分”卸载掉OVS 解析封包,查找表以及enqueue/drop等action的执行动作,从而提升转发性能。pmd帮助在其设备上安装流程规则,如下图所示

 

 

2 RTE_FLOW流规则

rte_flow流规则是具有匹配模式的属性和动作列表的组合。 流规则构成了rte_flow API的基础。

一个流规则可以具有几个不同的动作(如在将数据重定向到特定队列之前执行计数,封装,解封装等操作), 而不是依靠几个规则来实现这些动作,应用程序操作具体的硬件实现细节来顺序执行。

rte_flowAPI提供了基于规则的不同优先级支持,例如,当报文匹配两个规则时,强制先执行特定规则。 然而,对于支持多个优先级的硬件,这一条不能保证。 当支持时,可用优先级的数量通常较低,这也是为什么还可以通过PMD 在软件中实现(如通过重新排序规则可以模拟缺失的优先级)。

为了尽可能保持与硬件无关,默认情况下所有规则都被认为具有相同的优先级,这意味着重叠规则(当数据包被多个过滤器匹配时)之间的顺序是不确定的。

流规则主要有:

  • 属性:流规则的属性,例如其方向(Ingress或Egress)和优先级。
  • 模式条目:匹配模式的一部分,匹配特定的数据包数据或流量属
    性。也可以描述模式本身属性,如反向匹配。
  • 匹配条目:查找的属性,组合任意的模式。
  • 动作:每当数据包被匹配时执行的操作(如丢弃流量/转移流量等)

2.1 属性

struct rte_flow_attr {
	uint32_t group; /**< Priority group. */
	/*流规则可以通过为其分配一个公共的组号来分组。
	 较低的值具有较高的优先级。组0具有最高优先级。
       Group 0是默认,进入匹配后可以通过JUMP action到达其他的Group。*/
	uint32_t priority; /**< Rule priority level within group. */
	/*该流规则在组内的优先级*/
	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
	uint32_t egress:1; /**< Rule applies to egress traffic. */
	/*流量方向的指定,必须至少指定一个方向,流量规则可以应用于入站和/或出站流量(Ingress/Egress)*/
	uint32_t transfer:1;
	/*将rule转移到模式中能找到的任何设备,所以可以重新路由别人的流量。*/
	uint32_t reserved:29; /**< Reserved, must be zero. */
};

2.2 模式条目

struct rte_flow_item {
	enum rte_flow_item_type type; /**< Item type. */
	/*匹配的类型*/
	const void *spec; /**< Pointer to item specification structure. */
	/*要匹配的数值(如IPv4地址)。*/
	const void *last; /**< Defines an inclusive range (spec to last). */
	/*规格中的相应字段的范围上限。*/
	const void *mask; /**< Bit-mask applied to spec and last. */
	/*应用于spec和last的位掩码(如匹配IPv4地址的前缀)*/
};

对于模式条目中的type,可以匹配的模式有两种:

  • 匹配协议头部及报文数据(ANY,RAW,ETH,VLAN,IPV4,IPV6,ICMP,UDP,TCP,SCTP,VXLAN,MPLS,GRE等等)。
  • 匹配元数据或影响模式处理(END,VOID,INVERT,PF,VF,PORT等等)。

条目规范结构用于匹配协议字段(或项目属性)中的特定值。文档描述每个条目是否与一个条目及其类型名称相关联。

可以为给定的条目最多设置三个相同类型的结构:

  • spec: 要匹配的数值(如IPv4地址)。
  • last: 规格中的相应字段的范围上限。
  • mask: 应用于spec和last的位掩码(如匹配IPv4地址的前缀)。

使用限制:

  • 没有spec 就设置 mask 或 last 是错误的。
  • 错误的last 值如0或者等于 spec 将被忽略,他们不能产生范围。不支持低于 spec 的非0值。
  • 设置spce 和可选的 last ,而不设置 mask 会导致PMD使用该条目定义的默认`` mask``(定义 为 rte_flow_item_{name}_mask 常量)。不设置他们相当于提供空掩码匹配。
  • 不设置他们相当于提供空掩码匹配。
  • 掩码是用于spec 和 last 的简单位掩码,如果不小心使用,可能会产生意想不到的结果。例如,对于IPv4地 址字段,spec提供10.1.2.3,last提供10.3.4.5,掩码为255.255.0.0,有效范围为10.1.0.0~10.3.255.255。

匹配以太网头部的条目示例:

Table 8.1 Ethernet item

Field

Subfield

Value

spec

src

00:01:02:03:04

dst

00:2a:66:00:01

type

0x22aa

last

unspecified

mask

src

00:ff:ff:ff:00

dst

00:00:00:00:ff

type

0x0000

无掩码的位可以匹配任意的值(显示为 ? ), 以太头部具有如下的属性匹配信息:

  • src: ??:01:02:03:??
  • dst: ??:??:??:??:01
  • type: 0x????

2.3 匹配模式

根据dpdk org 资料,从最低的协议开始,以END items终结。

例子如下:

 TCPv4 as L4

Index

Item

0

Ethernet

1

IPv4

2

TCP

3

END

 

TCPv6 in VXLAN

Index

Item

0

Ethernet

1

IPv4

2

UDP

3

VXLAN

4

Ethernet

5

IPv6

6

TCP

7

END

 

 TCPv4 as L4 with meta items

Index

Item

0

VOID

1

Ethernet

2

VOID

3

IPv4

4

TCP

5

VOID

6

VOID

7

END

上面的例子显示了一个元条目,如何实现不影响报文数据匹配结果,只要他们保持堆叠正确。结果匹配与 “TCPv4 as L4” 条目相同。

UDPv6 anywhere

Index

Item

0

IPv6

1

UDP

2

END

 

2.4 ITEM

END,PMD强制支持,spec、last、mask都忽略

VOID,其他同上

INVERT,反向匹配,spec、last、mask都忽略

PF,VF匹配PF和VF的流量,spec、last、mask都不能设置

VF,能被多次指定;匹配PF和VF流量;默认的mask匹配任意VF ID

PHY_PORT,默认的mask匹配任意端口号

 

item types

大多数基本上都具有bit-mask的协议头定义。必须从最低协议层到最高协议层的匹配模式。

ANY,匹配任意协议,默认的mask代表任意层

RAW,直接匹配给定长度、指定偏移的字符;不支持last字段的范围配置;默认mask所有字段精确匹配。

ETH,匹配Ethernet协议头;dst是目的MAC;src是源MAC;type是类型;默认mask只匹配源和目的地址。

VLAN,匹配VLAN协议头;tci表示tag control information;inner_type表示inner EtherType;默认的mask只匹配TCI的VID部分。

IPV4,hdr表示IPv4协议头;默认的mask只匹配源目的地址。

IPV6、ICMP、UDP、TCP、SCTP类似。

VXLAN,flags通常是0x08;rsvd0缺省,通常0x000000;vni;rsvd1缺省,通常是0x00;默认的mask只匹配vni。

PORT_ID,默认的mask匹配指定的端口号

MARK,匹配之前用MARKaction打上标记的报文,默认的mask匹配任意值

 

3  rte_flow下发流程

OVS在做partial offload时, rte_flow下发流程如下图所示(以dpdk i40e driver为例):

1) OVS在处理数据包时会根据 key值进行datapath cache流表匹配,如果匹配成功则执行流表对应的 action;如果失败则通过upcall送入ofproto层处理,之后会将flow下发至datapath cache。

2) OVS在下发flow至datapath cache的同时,会检查下发的flow是否带mark值,如果flow带mark值,则说明是之前下发过的,flow put action会调整为modify,如果flow不带mark值,则生成新的mark值,flow put action为add。(注意mark id一般是按序递增,注意mark值是global的,即不会出现若干pmd线程下发同一条flow时产生mark值冲突问题)

3) 根据netdev类型调用对应的flow_put。(注意目前只支持dpdk类型的port做网卡收方向的flow_put)

4) 在产生rte_flow之前要先做两步检查,一是检查是否是做flow modify,如果是则要通过i40e driver把已存在的rte_flow删除。二是检查flow的有效性:这一步只是在OVS层面做检查,即检查是否有OVS自定义的封包解析栏位,如metadata等。如果包含,则意味着dpdk rte_flow无法解析,这时会直接退出。 5)检查通过,则进入dpdk_add_rte_flow_offload,构造rte_flow pattern。(attr里的ingress为1,action目前固定为mark+rss+end )

6)接下来的处理动作是在dpdk i40e driver中完成的,即dpdk i40e driver要做进一步的flow pattern检查(parse_fdir_pattern/action/attr),根据网卡具体支持的解析规则检查flow spec和flow mask是否支持,如果不支持则返回错误代码。之后调用flow_add_fdir,将flow pattern/action写入网卡。

7)在网卡收到包时,会解析包头信息,当发现有匹配则网卡会打上flow pattern对应的mark值(这个值会带在mbuf.hash.fdir.hi,同时mbuf.ol_flag对应rx_fdir_id的bit会置1)。OVS在做datapath flow cache查找时,如果发现这笔pkt带mark值,则跳过解析数据包和datapath cache查找,直接根据mark值找到对应的flow entry,提取并执行action。

4 参考资料

https://doc.dpdk.org/guides/prog_guide/rte_flow.html

https://www.sdnlab.com/23216.html

 

 

 

0条评论
0 / 1000
刘****珂
3文章数
0粉丝数
刘****珂
3 文章 | 0 粉丝
刘****珂
3文章数
0粉丝数
刘****珂
3 文章 | 0 粉丝
原创

dpdk rte_flow 简介

2023-03-31 08:39:44
511
0

1 简介

Nic网卡有流分类处理功能,是指网卡在收包时,将符合某种规则的包放入指定的队列。网卡一般支持一种或多种流分类能,而且不同的网卡可能支持不同种类的filter,例如intel 82599系列网卡支持n-tuple、L2_tunnel、flow director等。即使intel 82599系列网卡和intel 700系列网卡都支持flow director,它们支持的方式也不一样。

dpdk要支持各种类型网卡,就要为所有网卡抽象出统一的属性,但是某些属性只对一种网卡有意义,比如并不是所有的网卡都关注flow_type 和is_vf,比如intel 82599系列网卡不需要flow_type及is_vf。还有那些可选或者可缺省的属性容易让用户产生疑惑。经常在某种filter类型中随意插入一些某个网卡特有的属性。其次,随着DPDK支持的网卡越来越多,DPDK需要定义的filter类型要增加,网卡filter功能升级也需要DPDK作相应修改,这样很容易导致API/ABI的破坏。

鉴于上述原因,一个generic flow API必不可少,rte_flow由此产生。

rte_flow主要是用来配置流量,主要就是match和action。match包括了报文信息(比如协议头、payload)和属性(物理端口、虚拟设备ID等);action包括了drop、转发到指定的queues或者物理设备或者虚拟设备、执行tunnel offload、添加标记等。此类API提供了一种通用的方式来配置硬件以匹配特定的 Ingress 或 Egress 流量,根据用户的任何配置规则更改其操作及查询相关计数器。所有API带有前缀 rte_flow ,在文件 rte_flow.h 中定义。

在OVS-DPDK应用场景里OVS可以通过rte_flow将部分网卡支持的flow pattern(eth+vlan+ip+tcp/udp)以及相应的action(如queue/mark/drop/rss等)下发至网卡,这样可以在网卡收包方向“部分”卸载掉OVS 解析封包,查找表以及enqueue/drop等action的执行动作,从而提升转发性能。pmd帮助在其设备上安装流程规则,如下图所示

 

 

2 RTE_FLOW流规则

rte_flow流规则是具有匹配模式的属性和动作列表的组合。 流规则构成了rte_flow API的基础。

一个流规则可以具有几个不同的动作(如在将数据重定向到特定队列之前执行计数,封装,解封装等操作), 而不是依靠几个规则来实现这些动作,应用程序操作具体的硬件实现细节来顺序执行。

rte_flowAPI提供了基于规则的不同优先级支持,例如,当报文匹配两个规则时,强制先执行特定规则。 然而,对于支持多个优先级的硬件,这一条不能保证。 当支持时,可用优先级的数量通常较低,这也是为什么还可以通过PMD 在软件中实现(如通过重新排序规则可以模拟缺失的优先级)。

为了尽可能保持与硬件无关,默认情况下所有规则都被认为具有相同的优先级,这意味着重叠规则(当数据包被多个过滤器匹配时)之间的顺序是不确定的。

流规则主要有:

  • 属性:流规则的属性,例如其方向(Ingress或Egress)和优先级。
  • 模式条目:匹配模式的一部分,匹配特定的数据包数据或流量属
    性。也可以描述模式本身属性,如反向匹配。
  • 匹配条目:查找的属性,组合任意的模式。
  • 动作:每当数据包被匹配时执行的操作(如丢弃流量/转移流量等)

2.1 属性

struct rte_flow_attr {
	uint32_t group; /**< Priority group. */
	/*流规则可以通过为其分配一个公共的组号来分组。
	 较低的值具有较高的优先级。组0具有最高优先级。
       Group 0是默认,进入匹配后可以通过JUMP action到达其他的Group。*/
	uint32_t priority; /**< Rule priority level within group. */
	/*该流规则在组内的优先级*/
	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
	uint32_t egress:1; /**< Rule applies to egress traffic. */
	/*流量方向的指定,必须至少指定一个方向,流量规则可以应用于入站和/或出站流量(Ingress/Egress)*/
	uint32_t transfer:1;
	/*将rule转移到模式中能找到的任何设备,所以可以重新路由别人的流量。*/
	uint32_t reserved:29; /**< Reserved, must be zero. */
};

2.2 模式条目

struct rte_flow_item {
	enum rte_flow_item_type type; /**< Item type. */
	/*匹配的类型*/
	const void *spec; /**< Pointer to item specification structure. */
	/*要匹配的数值(如IPv4地址)。*/
	const void *last; /**< Defines an inclusive range (spec to last). */
	/*规格中的相应字段的范围上限。*/
	const void *mask; /**< Bit-mask applied to spec and last. */
	/*应用于spec和last的位掩码(如匹配IPv4地址的前缀)*/
};

对于模式条目中的type,可以匹配的模式有两种:

  • 匹配协议头部及报文数据(ANY,RAW,ETH,VLAN,IPV4,IPV6,ICMP,UDP,TCP,SCTP,VXLAN,MPLS,GRE等等)。
  • 匹配元数据或影响模式处理(END,VOID,INVERT,PF,VF,PORT等等)。

条目规范结构用于匹配协议字段(或项目属性)中的特定值。文档描述每个条目是否与一个条目及其类型名称相关联。

可以为给定的条目最多设置三个相同类型的结构:

  • spec: 要匹配的数值(如IPv4地址)。
  • last: 规格中的相应字段的范围上限。
  • mask: 应用于spec和last的位掩码(如匹配IPv4地址的前缀)。

使用限制:

  • 没有spec 就设置 mask 或 last 是错误的。
  • 错误的last 值如0或者等于 spec 将被忽略,他们不能产生范围。不支持低于 spec 的非0值。
  • 设置spce 和可选的 last ,而不设置 mask 会导致PMD使用该条目定义的默认`` mask``(定义 为 rte_flow_item_{name}_mask 常量)。不设置他们相当于提供空掩码匹配。
  • 不设置他们相当于提供空掩码匹配。
  • 掩码是用于spec 和 last 的简单位掩码,如果不小心使用,可能会产生意想不到的结果。例如,对于IPv4地 址字段,spec提供10.1.2.3,last提供10.3.4.5,掩码为255.255.0.0,有效范围为10.1.0.0~10.3.255.255。

匹配以太网头部的条目示例:

Table 8.1 Ethernet item

Field

Subfield

Value

spec

src

00:01:02:03:04

dst

00:2a:66:00:01

type

0x22aa

last

unspecified

mask

src

00:ff:ff:ff:00

dst

00:00:00:00:ff

type

0x0000

无掩码的位可以匹配任意的值(显示为 ? ), 以太头部具有如下的属性匹配信息:

  • src: ??:01:02:03:??
  • dst: ??:??:??:??:01
  • type: 0x????

2.3 匹配模式

根据dpdk org 资料,从最低的协议开始,以END items终结。

例子如下:

 TCPv4 as L4

Index

Item

0

Ethernet

1

IPv4

2

TCP

3

END

 

TCPv6 in VXLAN

Index

Item

0

Ethernet

1

IPv4

2

UDP

3

VXLAN

4

Ethernet

5

IPv6

6

TCP

7

END

 

 TCPv4 as L4 with meta items

Index

Item

0

VOID

1

Ethernet

2

VOID

3

IPv4

4

TCP

5

VOID

6

VOID

7

END

上面的例子显示了一个元条目,如何实现不影响报文数据匹配结果,只要他们保持堆叠正确。结果匹配与 “TCPv4 as L4” 条目相同。

UDPv6 anywhere

Index

Item

0

IPv6

1

UDP

2

END

 

2.4 ITEM

END,PMD强制支持,spec、last、mask都忽略

VOID,其他同上

INVERT,反向匹配,spec、last、mask都忽略

PF,VF匹配PF和VF的流量,spec、last、mask都不能设置

VF,能被多次指定;匹配PF和VF流量;默认的mask匹配任意VF ID

PHY_PORT,默认的mask匹配任意端口号

 

item types

大多数基本上都具有bit-mask的协议头定义。必须从最低协议层到最高协议层的匹配模式。

ANY,匹配任意协议,默认的mask代表任意层

RAW,直接匹配给定长度、指定偏移的字符;不支持last字段的范围配置;默认mask所有字段精确匹配。

ETH,匹配Ethernet协议头;dst是目的MAC;src是源MAC;type是类型;默认mask只匹配源和目的地址。

VLAN,匹配VLAN协议头;tci表示tag control information;inner_type表示inner EtherType;默认的mask只匹配TCI的VID部分。

IPV4,hdr表示IPv4协议头;默认的mask只匹配源目的地址。

IPV6、ICMP、UDP、TCP、SCTP类似。

VXLAN,flags通常是0x08;rsvd0缺省,通常0x000000;vni;rsvd1缺省,通常是0x00;默认的mask只匹配vni。

PORT_ID,默认的mask匹配指定的端口号

MARK,匹配之前用MARKaction打上标记的报文,默认的mask匹配任意值

 

3  rte_flow下发流程

OVS在做partial offload时, rte_flow下发流程如下图所示(以dpdk i40e driver为例):

1) OVS在处理数据包时会根据 key值进行datapath cache流表匹配,如果匹配成功则执行流表对应的 action;如果失败则通过upcall送入ofproto层处理,之后会将flow下发至datapath cache。

2) OVS在下发flow至datapath cache的同时,会检查下发的flow是否带mark值,如果flow带mark值,则说明是之前下发过的,flow put action会调整为modify,如果flow不带mark值,则生成新的mark值,flow put action为add。(注意mark id一般是按序递增,注意mark值是global的,即不会出现若干pmd线程下发同一条flow时产生mark值冲突问题)

3) 根据netdev类型调用对应的flow_put。(注意目前只支持dpdk类型的port做网卡收方向的flow_put)

4) 在产生rte_flow之前要先做两步检查,一是检查是否是做flow modify,如果是则要通过i40e driver把已存在的rte_flow删除。二是检查flow的有效性:这一步只是在OVS层面做检查,即检查是否有OVS自定义的封包解析栏位,如metadata等。如果包含,则意味着dpdk rte_flow无法解析,这时会直接退出。 5)检查通过,则进入dpdk_add_rte_flow_offload,构造rte_flow pattern。(attr里的ingress为1,action目前固定为mark+rss+end )

6)接下来的处理动作是在dpdk i40e driver中完成的,即dpdk i40e driver要做进一步的flow pattern检查(parse_fdir_pattern/action/attr),根据网卡具体支持的解析规则检查flow spec和flow mask是否支持,如果不支持则返回错误代码。之后调用flow_add_fdir,将flow pattern/action写入网卡。

7)在网卡收到包时,会解析包头信息,当发现有匹配则网卡会打上flow pattern对应的mark值(这个值会带在mbuf.hash.fdir.hi,同时mbuf.ol_flag对应rx_fdir_id的bit会置1)。OVS在做datapath flow cache查找时,如果发现这笔pkt带mark值,则跳过解析数据包和datapath cache查找,直接根据mark值找到对应的flow entry,提取并执行action。

4 参考资料

https://doc.dpdk.org/guides/prog_guide/rte_flow.html

https://www.sdnlab.com/23216.html

 

 

 

文章来自个人专栏
DPU网络
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0