[dpdk-dev,RFC,1/3] ethdev: add packet filter flow and new behavior switch to fdir

Message ID 1dabf80beb341e03923a535d0fa13f244350af34.1449747042.git.rahul.lakkireddy@chelsio.com (mailing list archive)
State RFC, archived
Headers

Commit Message

Rahul Lakkireddy Dec. 10, 2015, 2:01 p.m. UTC
  Add a new packet filter flow that allows filtering a packet based on
matching ingress port, ethertype, vlan, ip, and tcp/udp fields, i.e.
matching based on any or all fields at the same time.

Add the ability to provide masks for fields in flow to allow range of
values.

Add a new vlan flow containing inner and outer vlan to match. Add tos
and proto fields that can be matched for ipv4_flow.

Add a new behavior switch.

Add the ability to provide behavior arguments to allow insert/deletion
of matched fields in the flow.  Useful when rewriting matched fields
with new values.  Adds arguments for port, mac, vlan, and nat.
Ex: allows to provide new ip and port addresses to rewrite the fields
of packets matching a filter rule before NAT'ing.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 112 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)
  

Comments

Chilikin, Andrey Dec. 10, 2015, 3:46 p.m. UTC | #1
Hi Rahul,

If ABI for fdir is going to be changed should we then take more general approach to accommodate other NICs as well? For example,  for "rte_eth_ipv4_flow" you have "tos" and "proto" fields added, but "ttl" was left out of scope. I believe that "rte_eth_udpv6_flow" should be compatible with new IPv4 structure, so "flow label", "tc", "next header" and "hop limit" to be added as well as other NICs might have support for fdir rules for all these fields.

Regards,
Andrey

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Rahul Lakkireddy
> Sent: Thursday, December 10, 2015 2:01 PM
> To: dev@dpdk.org
> Cc: Felix Marti; Kumar Sanghvi; Nirranjan Kirubaharan
> Subject: [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior
> switch to fdir
> 
> Add a new packet filter flow that allows filtering a packet based on matching
> ingress port, ethertype, vlan, ip, and tcp/udp fields, i.e.
> matching based on any or all fields at the same time.
> 
> Add the ability to provide masks for fields in flow to allow range of values.
> 
> Add a new vlan flow containing inner and outer vlan to match. Add tos and
> proto fields that can be matched for ipv4_flow.
> 
> Add a new behavior switch.
> 
> Add the ability to provide behavior arguments to allow insert/deletion of
> matched fields in the flow.  Useful when rewriting matched fields with new
> values.  Adds arguments for port, mac, vlan, and nat.
> Ex: allows to provide new ip and port addresses to rewrite the fields of packets
> matching a filter rule before NAT'ing.
> 
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> ---
>  lib/librte_ether/rte_eth_ctrl.h | 112
> +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 111 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
> index ce224ad..a2e770c 100644
> --- a/lib/librte_ether/rte_eth_ctrl.h
> +++ b/lib/librte_ether/rte_eth_ctrl.h
> @@ -74,7 +74,11 @@ extern "C" {
>  #define RTE_ETH_FLOW_IPV6_EX            15
>  #define RTE_ETH_FLOW_IPV6_TCP_EX        16
>  #define RTE_ETH_FLOW_IPV6_UDP_EX        17
> -#define RTE_ETH_FLOW_MAX                18
> +#define RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP 18 #define
> +RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP 19 #define
> +RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP 20 #define
> +RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP 21
> +#define RTE_ETH_FLOW_MAX                22
> 
>  /**
>   * Feature filter types
> @@ -407,6 +411,8 @@ struct rte_eth_l2_flow {  struct rte_eth_ipv4_flow {
>  	uint32_t src_ip;      /**< IPv4 source address to match. */
>  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> +	uint8_t tos;          /**< IPV4 type of service to match. */
> +	uint8_t proto;        /**< IPV4 proto to match. */
>  };
> 
>  /**
> @@ -500,6 +506,43 @@ struct rte_eth_tunnel_flow {  };
> 
>  /**
> + * A structure used to define the input for vlan flow.
> + */
> +struct rte_eth_vlan_flow {
> +	uint16_t inner_vlan;  /**< Inner vlan field to match. */
> +	uint16_t outer_vlan;  /**< Outer vlan field to match. */ };
> +
> +/**
> + * A union used to define the input for N-Tuple flow  */ union
> +rte_eth_ntuple_flow {
> +	struct rte_eth_tcpv4_flow  tcp4;
> +	struct rte_eth_udpv4_flow  udp4;
> +	struct rte_eth_tcpv6_flow  tcp6;
> +	struct rte_eth_udpv6_flow  udp6;
> +};
> +
> +/**
> + * A structure used to define the input for packet filter.
> + */
> +struct rte_eth_pkt_filter {
> +	uint8_t port_id;                     /**< Port id to match. */
> +	struct rte_eth_l2_flow    l2_flow;   /**< L2 flow fields to match. */
> +	struct rte_eth_vlan_flow  vlan_flow; /**< Vlan flow fields to match. */
> +	union rte_eth_ntuple_flow ntuple_flow;
> +	/**< N-tuple flow fields to match. */
> +};
> +
> +/**
> + * A structure used to define the input for packet filter flow.
> + */
> +struct rte_eth_pkt_filter_flow {
> +	struct rte_eth_pkt_filter pkt;      /**< Packet fields to match. */
> +	struct rte_eth_pkt_filter mask;     /**< Mask for matched fields. */
> +};
> +
> +/**
>   * An union contains the inputs for all types of flow
>   */
>  union rte_eth_fdir_flow {
> @@ -514,6 +557,7 @@ union rte_eth_fdir_flow {
>  	struct rte_eth_ipv6_flow   ipv6_flow;
>  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
>  	struct rte_eth_tunnel_flow   tunnel_flow;
> +	struct rte_eth_pkt_filter_flow pkt_filter_flow;
>  };
> 
>  /**
> @@ -545,6 +589,7 @@ enum rte_eth_fdir_behavior {
>  	RTE_ETH_FDIR_ACCEPT = 0,
>  	RTE_ETH_FDIR_REJECT,
>  	RTE_ETH_FDIR_PASSTHRU,
> +	RTE_ETH_FDIR_SWITCH,
>  };
> 
>  /**
> @@ -559,6 +604,69 @@ enum rte_eth_fdir_status {  };
> 
>  /**
> + * Behavior sub operations on fields in matched flows.
> + */
> +enum rte_eth_fdir_behavior_sub_op {
> +	RTE_FDIR_BEHAVIOR_SUB_OP_UNKNOWN = 0,
> +	RTE_FDIR_BEHAVIOR_SUB_OP_INSERT,
> +	/**< Add/rewrite fields in matched flows */
> +	RTE_FDIR_BEHAVIOR_SUB_OP_DELETE,
> +	/**< Delete/reset fields in matched flows */ };
> +
> +/**
> + * A structure used to define the input for passing port arguments for
> + * behavior taken.
> + */
> +struct rte_eth_behavior_arg_port {
> +	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
> +	uint8_t port_id;                      /**< Physical port to redirect */
> +};
> +
> +/**
> + * A structure used to define the input for passing mac arguments for
> + * behavior taken.
> + */
> +struct rte_eth_behavior_arg_mac {
> +	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
> +	struct ether_addr src_mac;    /**< SRC Ethernet Address to rewirte. */
> +	struct ether_addr dst_mac;    /**< DST Ethernet Address to rewrite. */
> +};
> +
> +/**
> + * A structure used to define the input for passing vlan arguments for
> + * behavior taken.
> + */
> +struct rte_eth_behavior_arg_vlan {
> +	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
> +	uint16_t vlan_tci;  /**< New vlan fields to rewrite matched ones */ };
> +
> +/**
> + * A structure used to define the input for passing Network Address
> + * Translation (NAT) arguments for behavior taken.
> + */
> +struct rte_eth_behavior_arg_nat {
> +	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
> +	union rte_eth_ntuple_flow nat;
> +	/**< New NAT fields to rewrite matched ones */ };
> +
> +/**
> + * Extra arguments to pass for a behavior taken.
> + */
> +struct rte_eth_fdir_behavior_arg {
> +	struct rte_eth_behavior_arg_port   port_arg;
> +	/**< Extra port arg to pass */
> +	struct rte_eth_behavior_arg_mac    mac_arg;
> +	/**< Extra mac arg to pass */
> +	struct rte_eth_behavior_arg_vlan   vlan_arg;
> +	/**< Extra vlan arg to pass */
> +	struct rte_eth_behavior_arg_nat    nat_arg;
> +	/**< Extra NAT arg to pass */
> +};
> +
> +/**
>   * A structure used to define an action when match FDIR packet filter.
>   */
>  struct rte_eth_fdir_action {
> @@ -569,6 +677,8 @@ struct rte_eth_fdir_action {
>  	/**< If report_status is RTE_ETH_FDIR_REPORT_ID_FLEX_4 or
>  	     RTE_ETH_FDIR_REPORT_FLEX_8, flex_off specifies where the
> reported
>  	     flex bytes start from in flexible payload. */
> +	struct rte_eth_fdir_behavior_arg behavior_arg;
> +	/**< Extra arguments for behavior taken */
>  };
> 
>  /**
> --
> 2.5.3
  
Rahul Lakkireddy Dec. 11, 2015, 7:08 a.m. UTC | #2
Hi Andrey,

On Thursday, December 12/10/15, 2015 at 07:46:42 -0800, Chilikin, Andrey wrote:
> Hi Rahul,
> 
> If ABI for fdir is going to be changed should we then take more general approach to accommodate other NICs as well? For example,  for "rte_eth_ipv4_flow" you have "tos" and "proto" fields added, but "ttl" was left out of scope. I believe that "rte_eth_udpv6_flow" should be compatible with new IPv4 structure, so "flow label", "tc", "next header" and "hop limit" to be added as well as other NICs might have support for fdir rules for all these fields.
> 

I agree.

I'll wait for some more review comments if there are any and then post a
v2 RFC series with above changes.

Thanks,
Rahul
  

Patch

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..a2e770c 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -74,7 +74,11 @@  extern "C" {
 #define RTE_ETH_FLOW_IPV6_EX            15
 #define RTE_ETH_FLOW_IPV6_TCP_EX        16
 #define RTE_ETH_FLOW_IPV6_UDP_EX        17
-#define RTE_ETH_FLOW_MAX                18
+#define RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP 18
+#define RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP 19
+#define RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP 20
+#define RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP 21
+#define RTE_ETH_FLOW_MAX                22
 
 /**
  * Feature filter types
@@ -407,6 +411,8 @@  struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t tos;          /**< IPV4 type of service to match. */
+	uint8_t proto;        /**< IPV4 proto to match. */
 };
 
 /**
@@ -500,6 +506,43 @@  struct rte_eth_tunnel_flow {
 };
 
 /**
+ * A structure used to define the input for vlan flow.
+ */
+struct rte_eth_vlan_flow {
+	uint16_t inner_vlan;  /**< Inner vlan field to match. */
+	uint16_t outer_vlan;  /**< Outer vlan field to match. */
+};
+
+/**
+ * A union used to define the input for N-Tuple flow
+ */
+union rte_eth_ntuple_flow {
+	struct rte_eth_tcpv4_flow  tcp4;
+	struct rte_eth_udpv4_flow  udp4;
+	struct rte_eth_tcpv6_flow  tcp6;
+	struct rte_eth_udpv6_flow  udp6;
+};
+
+/**
+ * A structure used to define the input for packet filter.
+ */
+struct rte_eth_pkt_filter {
+	uint8_t port_id;                     /**< Port id to match. */
+	struct rte_eth_l2_flow    l2_flow;   /**< L2 flow fields to match. */
+	struct rte_eth_vlan_flow  vlan_flow; /**< Vlan flow fields to match. */
+	union rte_eth_ntuple_flow ntuple_flow;
+	/**< N-tuple flow fields to match. */
+};
+
+/**
+ * A structure used to define the input for packet filter flow.
+ */
+struct rte_eth_pkt_filter_flow {
+	struct rte_eth_pkt_filter pkt;      /**< Packet fields to match. */
+	struct rte_eth_pkt_filter mask;     /**< Mask for matched fields. */
+};
+
+/**
  * An union contains the inputs for all types of flow
  */
 union rte_eth_fdir_flow {
@@ -514,6 +557,7 @@  union rte_eth_fdir_flow {
 	struct rte_eth_ipv6_flow   ipv6_flow;
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
+	struct rte_eth_pkt_filter_flow pkt_filter_flow;
 };
 
 /**
@@ -545,6 +589,7 @@  enum rte_eth_fdir_behavior {
 	RTE_ETH_FDIR_ACCEPT = 0,
 	RTE_ETH_FDIR_REJECT,
 	RTE_ETH_FDIR_PASSTHRU,
+	RTE_ETH_FDIR_SWITCH,
 };
 
 /**
@@ -559,6 +604,69 @@  enum rte_eth_fdir_status {
 };
 
 /**
+ * Behavior sub operations on fields in matched flows.
+ */
+enum rte_eth_fdir_behavior_sub_op {
+	RTE_FDIR_BEHAVIOR_SUB_OP_UNKNOWN = 0,
+	RTE_FDIR_BEHAVIOR_SUB_OP_INSERT,
+	/**< Add/rewrite fields in matched flows */
+	RTE_FDIR_BEHAVIOR_SUB_OP_DELETE,
+	/**< Delete/reset fields in matched flows */
+};
+
+/**
+ * A structure used to define the input for passing port arguments for
+ * behavior taken.
+ */
+struct rte_eth_behavior_arg_port {
+	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
+	uint8_t port_id;                      /**< Physical port to redirect */
+};
+
+/**
+ * A structure used to define the input for passing mac arguments for
+ * behavior taken.
+ */
+struct rte_eth_behavior_arg_mac {
+	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
+	struct ether_addr src_mac;    /**< SRC Ethernet Address to rewirte. */
+	struct ether_addr dst_mac;    /**< DST Ethernet Address to rewrite. */
+};
+
+/**
+ * A structure used to define the input for passing vlan arguments for
+ * behavior taken.
+ */
+struct rte_eth_behavior_arg_vlan {
+	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
+	uint16_t vlan_tci;  /**< New vlan fields to rewrite matched ones */
+};
+
+/**
+ * A structure used to define the input for passing Network Address
+ * Translation (NAT) arguments for behavior taken.
+ */
+struct rte_eth_behavior_arg_nat {
+	enum rte_eth_fdir_behavior_sub_op op; /**< Sub operation to do */
+	union rte_eth_ntuple_flow nat;
+	/**< New NAT fields to rewrite matched ones */
+};
+
+/**
+ * Extra arguments to pass for a behavior taken.
+ */
+struct rte_eth_fdir_behavior_arg {
+	struct rte_eth_behavior_arg_port   port_arg;
+	/**< Extra port arg to pass */
+	struct rte_eth_behavior_arg_mac    mac_arg;
+	/**< Extra mac arg to pass */
+	struct rte_eth_behavior_arg_vlan   vlan_arg;
+	/**< Extra vlan arg to pass */
+	struct rte_eth_behavior_arg_nat    nat_arg;
+	/**< Extra NAT arg to pass */
+};
+
+/**
  * A structure used to define an action when match FDIR packet filter.
  */
 struct rte_eth_fdir_action {
@@ -569,6 +677,8 @@  struct rte_eth_fdir_action {
 	/**< If report_status is RTE_ETH_FDIR_REPORT_ID_FLEX_4 or
 	     RTE_ETH_FDIR_REPORT_FLEX_8, flex_off specifies where the reported
 	     flex bytes start from in flexible payload. */
+	struct rte_eth_fdir_behavior_arg behavior_arg;
+	/**< Extra arguments for behavior taken */
 };
 
 /**