* [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter @ 2015-12-10 14:01 Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy ` (3 more replies) 0 siblings, 4 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-10 14:01 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan This RFC series of patches attempt to extend the flow director filter to add support for Chelsio T5 hardware filtering capabilities. Chelsio T5 supports carrying out filtering in hardware which supports 3 actions to carry out on a packet which hit a filter viz. 1. Action Pass - Packets hitting a filter rule can be directed to a particular RXQ. 2. Action Drop - Packets hitting a filter rule are dropped in h/w. 3. Action Switch - Packets hitting a filter rule can be switched in h/w from one port to another, without involvement of host. Also, the action Switch also supports rewrite of src-mac/dst-mac headers as well as rewrite of vlan headers. It also supports rewrite of IP headers and thereby, supports NAT (Network Address Translation) in h/w. Also, each filter rule can optionally support specifying a mask value i.e. it's possible to create a filter rule for an entire subnet of IP addresses or a range of tcp/udp ports, etc. Patch 1 does the following: - Adds an additional flow rte_eth_pkt_filter_flow which encapsulates ingress ports, l2 payload, vlan and ntuples. - Adds an additional mask for the flow to allow range of values to be matched. - Adds a new behavior 'switch'. - Adds behavior arguments that can be passed when a particular behavior is taken. For ex: in case of action 'switch', pass additional 4-tuple to allow rewriting src/dst ip and port addresses to support NAT'ing. Patch 2 shows testpmd command line example to support packet filter flow. Patch 3 announces ABI change for filtering support. The patch series has been compile tested on all x86 gcc targets and the current fdir filter supported drivers seem to return appropriate error codes when this new flow type and the new action are not supported and hence are not affected. Posting this series mainly for discussion on API change. Once this is agreeable then, I will post the cxgbe PMD changes to use the new API. Rahul Lakkireddy (3): ethdev: add packet filter flow and new behavior switch to fdir testpmd: add an example to show packet filter flow doc: announce ABI change for filtering support app/test-pmd/cmdline.c | 435 ++++++++++++++++++++++++++++++++++- doc/guides/rel_notes/deprecation.rst | 6 + lib/librte_ether/rte_eth_ctrl.h | 112 ++++++++- 3 files changed, 544 insertions(+), 9 deletions(-) -- 2.5.3 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir 2015-12-10 14:01 [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter Rahul Lakkireddy @ 2015-12-10 14:01 ` Rahul Lakkireddy 2015-12-10 15:46 ` Chilikin, Andrey 2015-12-10 14:01 ` [dpdk-dev] [RFC 2/3] testpmd: add an example to show packet filter flow Rahul Lakkireddy ` (2 subsequent siblings) 3 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-10 14:01 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan 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 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir 2015-12-10 14:01 ` [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy @ 2015-12-10 15:46 ` Chilikin, Andrey 2015-12-11 7:08 ` Rahul Lakkireddy 0 siblings, 1 reply; 21+ messages in thread From: Chilikin, Andrey @ 2015-12-10 15:46 UTC (permalink / raw) To: Rahul Lakkireddy, dev; +Cc: Kumar Sanghvi, Felix Marti, Nirranjan Kirubaharan 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 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir 2015-12-10 15:46 ` Chilikin, Andrey @ 2015-12-11 7:08 ` Rahul Lakkireddy 0 siblings, 0 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-11 7:08 UTC (permalink / raw) To: Chilikin, Andrey; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S 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 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC 2/3] testpmd: add an example to show packet filter flow 2015-12-10 14:01 [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy @ 2015-12-10 14:01 ` Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 3 siblings, 0 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-10 14:01 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan Extend the existing flow_director_filter to add support for packet filter flow. Also shows how to pass the extra behavior arguments to rewrite fields in matched filter rules. Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com> --- app/test-pmd/cmdline.c | 435 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 427 insertions(+), 8 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 73298c9..488eddc 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -641,7 +641,7 @@ static void cmd_help_long_parsed(void *parsed_result, " flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)" " src (src_ip_address) dst (dst_ip_address)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " (drop|fwd|switch) pf|vf(vf_id) queue (queue_id)" " fd_id (fd_id_value)\n" " Add/Del an IP type flow director filter.\n\n" @@ -650,7 +650,7 @@ static void cmd_help_long_parsed(void *parsed_result, " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " (drop|fwd|switch) pf|vf(vf_id) queue (queue_id)" " fd_id (fd_id_value)\n" " Add/Del an UDP/TCP type flow director filter.\n\n" @@ -659,16 +659,37 @@ static void cmd_help_long_parsed(void *parsed_result, " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" " tag (verification_tag) vlan (vlan_value)" - " flexbytes (flexbytes_value) (drop|fwd)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" " Add/Del a SCTP type flow director filter.\n\n" "flow_director_filter (port_id) mode IP (add|del|update)" " flow l2_payload ether (ethertype)" - " flexbytes (flexbytes_value) (drop|fwd)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" " Add/Del a l2 payload type flow director filter.\n\n" + "flow_director_filter (port_id) mode IP (add|del|update)" + " flow (ipv4-tcp-pkt-filter|ipv4-udp-pkt-filter|" + " ipv6-tcp-pkt-filter|ipv6-udp-pkt-filter)" + " ingress-port (port_id) (port_id_mask)" + " ether (ethertype) (ethertype_mask)" + " inner-vlan (inner_vlan_value) (inner_vlan_mask)" + " outer-vlan (outer_vlan_value) (outer_vlan_mask)" + " tos (tos_value) (tos_mask)" + " proto (proto_value) (proto_mask)" + " src (src_ip) (src_ip_mask) (src_port) (src_port_mask)" + " dst (dst_ip) (dst_ip_mask) (dst_port) (dst_port_mask)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" + " pf|vf(vf_id) queue (queue_id)" + " port-arg none|port-redirect (dst-port-id)" + " mac-arg none|mac-rewrite (src-mac) (dst-mac)" + " vlan-arg none|vlan-rewrite|vlan-del (vlan_value)" + " nat-arg none|nat-rewrite" + " src (src_ip) (src_port) dst (dst_ip) (dst_port)" + " fd_id (fd_id_value)\n" + " Add/Del a packet filter type flow director filter.\n\n" + "flow_director_filter (port_id) mode MAC-VLAN (add|del|update)" " mac (mac_address) vlan (vlan_value)" " flexbytes (flexbytes_value) (drop|fwd)" @@ -7973,14 +7994,34 @@ struct cmd_flow_director_result { cmdline_fixed_string_t ops; cmdline_fixed_string_t flow; cmdline_fixed_string_t flow_type; + cmdline_fixed_string_t iport; + uint8_t iport_id; + uint8_t iport_id_mask; cmdline_fixed_string_t ether; uint16_t ether_type; + uint16_t ether_type_mask; + cmdline_fixed_string_t ivlan; + uint16_t ivlan_value; + uint16_t ivlan_mask; + cmdline_fixed_string_t ovlan; + uint16_t ovlan_value; + uint16_t ovlan_mask; + cmdline_fixed_string_t tos; + uint8_t tos_value; + uint8_t tos_mask; + cmdline_fixed_string_t proto; + uint8_t proto_value; + uint8_t proto_mask; cmdline_fixed_string_t src; cmdline_ipaddr_t ip_src; + cmdline_ipaddr_t ip_src_mask; uint16_t port_src; + uint16_t port_src_mask; cmdline_fixed_string_t dst; cmdline_ipaddr_t ip_dst; + cmdline_ipaddr_t ip_dst_mask; uint16_t port_dst; + uint16_t port_dst_mask; cmdline_fixed_string_t verify_tag; uint32_t verify_tag_value; cmdline_fixed_string_t vlan; @@ -7999,6 +8040,26 @@ struct cmd_flow_director_result { cmdline_fixed_string_t tunnel_type; cmdline_fixed_string_t tunnel_id; uint32_t tunnel_id_value; + + /* Extra arguments for behavior taken */ + cmdline_fixed_string_t port_arg; + cmdline_fixed_string_t port_arg_op; + uint8_t port_arg_port_id; + cmdline_fixed_string_t mac_arg; + cmdline_fixed_string_t mac_arg_op; + struct ether_addr mac_arg_src_mac; + struct ether_addr mac_arg_dst_mac; + cmdline_fixed_string_t vlan_arg; + cmdline_fixed_string_t vlan_arg_op; + uint16_t vlan_arg_vlan; + cmdline_fixed_string_t nat_arg; + cmdline_fixed_string_t nat_arg_op; + cmdline_fixed_string_t nat_arg_src; + cmdline_ipaddr_t nat_arg_ip_src; + uint16_t nat_arg_port_src; + cmdline_fixed_string_t nat_arg_dst; + cmdline_ipaddr_t nat_arg_ip_dst; + uint16_t nat_arg_port_dst; }; static inline int @@ -8061,6 +8122,10 @@ str2flowtype(char *string) {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP}, {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER}, {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD}, + {"ipv4-tcp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP}, + {"ipv4-udp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP}, + {"ipv6-tcp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP}, + {"ipv6-udp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP}, }; for (i = 0; i < RTE_DIM(flowtype_str); i++) { @@ -8090,6 +8155,30 @@ str2fdir_tunneltype(char *string) return RTE_FDIR_TUNNEL_TYPE_UNKNOWN; } +static uint16_t +str2fdir_behavior_sub_op(char *string) +{ + uint16_t i = 0; + + static const struct { + char str[32]; + enum rte_eth_fdir_behavior_sub_op op; + } behavior_sub_op_str[] = { + {"port-redirect", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"mac-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"vlan-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"vlan-del", RTE_FDIR_BEHAVIOR_SUB_OP_DELETE}, + {"nat-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + }; + + for (i = 0; i < RTE_DIM(behavior_sub_op_str); i++) { + if (!strcmp(behavior_sub_op_str[i].str, string)) + return behavior_sub_op_str[i].op; + } + + return RTE_FDIR_BEHAVIOR_SUB_OP_UNKNOWN; +} + #define IPV4_ADDR_TO_UINT(ip_addr, ip) \ do { \ if ((ip_addr).family == AF_INET) \ @@ -8119,6 +8208,7 @@ cmd_flow_director_filter_parsed(void *parsed_result, { struct cmd_flow_director_result *res = parsed_result; struct rte_eth_fdir_filter entry; + struct rte_eth_pkt_filter_flow *pflow; uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN]; char *end; unsigned long vf_id; @@ -8218,6 +8308,89 @@ cmd_flow_director_filter_parsed(void *parsed_result, entry.input.flow.l2_flow.ether_type = rte_cpu_to_be_16(res->ether_type); break; + case RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP: + pflow = &entry.input.flow.pkt_filter_flow; + + pflow->pkt.port_id = res->iport_id; + pflow->mask.port_id = res->iport_id_mask; + + pflow->pkt.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type); + pflow->mask.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type_mask); + + pflow->pkt.vlan_flow.inner_vlan = + rte_cpu_to_be_16(res->ivlan_value); + pflow->pkt.vlan_flow.outer_vlan = res->ovlan_value; + rte_cpu_to_be_16(res->ovlan_value); + pflow->mask.vlan_flow.inner_vlan = res->ivlan_mask; + rte_cpu_to_be_16(res->ivlan_mask); + pflow->mask.vlan_flow.outer_vlan = res->ovlan_mask; + rte_cpu_to_be_16(res->ovlan_mask); + + pflow->pkt.ntuple_flow.tcp4.ip.tos = res->tos_value; + pflow->pkt.ntuple_flow.tcp4.ip.proto = res->proto_value; + pflow->mask.ntuple_flow.tcp4.ip.tos = res->tos_mask; + pflow->mask.ntuple_flow.tcp4.ip.proto = res->proto_mask; + + IPV4_ADDR_TO_UINT(res->ip_src, + pflow->pkt.ntuple_flow.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->ip_dst, + pflow->pkt.ntuple_flow.tcp4.ip.dst_ip); + IPV4_ADDR_TO_UINT(res->ip_src_mask, + pflow->mask.ntuple_flow.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->ip_dst_mask, + pflow->mask.ntuple_flow.tcp4.ip.dst_ip); + + pflow->pkt.ntuple_flow.tcp4.src_port = + rte_cpu_to_be_16(res->port_src); + pflow->pkt.ntuple_flow.tcp4.dst_port = + rte_cpu_to_be_16(res->port_dst); + pflow->mask.ntuple_flow.tcp4.src_port = + rte_cpu_to_be_16(res->port_src_mask); + pflow->mask.ntuple_flow.tcp4.dst_port = + rte_cpu_to_be_16(res->port_dst_mask); + break; + case RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP: + pflow = &entry.input.flow.pkt_filter_flow; + + pflow->pkt.port_id = res->iport_id; + pflow->mask.port_id = res->iport_id_mask; + + pflow->pkt.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type); + pflow->mask.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type_mask); + + pflow->pkt.vlan_flow.inner_vlan = + rte_cpu_to_be_16(res->ivlan_value); + pflow->pkt.vlan_flow.outer_vlan = res->ovlan_value; + rte_cpu_to_be_16(res->ovlan_value); + pflow->mask.vlan_flow.inner_vlan = res->ivlan_mask; + rte_cpu_to_be_16(res->ivlan_mask); + pflow->mask.vlan_flow.outer_vlan = res->ovlan_mask; + rte_cpu_to_be_16(res->ovlan_mask); + + IPV6_ADDR_TO_ARRAY(res->ip_src, + pflow->pkt.ntuple_flow.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->ip_dst, + pflow->pkt.ntuple_flow.tcp6.ip.dst_ip); + IPV6_ADDR_TO_ARRAY(res->ip_src_mask, + pflow->mask.ntuple_flow.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->ip_dst_mask, + pflow->mask.ntuple_flow.tcp6.ip.dst_ip); + + pflow->pkt.ntuple_flow.tcp6.src_port = + rte_cpu_to_be_16(res->port_src); + pflow->pkt.ntuple_flow.tcp6.dst_port = + rte_cpu_to_be_16(res->port_dst); + pflow->mask.ntuple_flow.tcp6.src_port = + rte_cpu_to_be_16(res->port_src_mask); + pflow->mask.ntuple_flow.tcp6.dst_port = + rte_cpu_to_be_16(res->port_dst_mask); + break; default: break; } @@ -8244,10 +8417,68 @@ cmd_flow_director_filter_parsed(void *parsed_result, entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value); entry.action.flex_off = 0; /*use 0 by default */ - if (!strcmp(res->drop, "drop")) + if (!strcmp(res->drop, "switch")) { + struct rte_eth_behavior_arg_nat *nat_arg; + + entry.action.behavior = RTE_ETH_FDIR_SWITCH; + + /* Extra port arguments */ + entry.action.behavior_arg.port_arg.op = + str2fdir_behavior_sub_op(res->port_arg_op); + entry.action.behavior_arg.port_arg.port_id = + res->port_arg_port_id; + + /* Extra mac arguments */ + entry.action.behavior_arg.mac_arg.op = + str2fdir_behavior_sub_op(res->mac_arg_op); + (void)rte_memcpy(&entry.action.behavior_arg.mac_arg.src_mac, + &res->mac_arg_src_mac, + sizeof(struct ether_addr)); + (void)rte_memcpy(&entry.action.behavior_arg.mac_arg.dst_mac, + &res->mac_arg_dst_mac, + sizeof(struct ether_addr)); + + /* Extra vlan arguments */ + entry.action.behavior_arg.vlan_arg.op = + str2fdir_behavior_sub_op(res->vlan_arg_op); + entry.action.behavior_arg.vlan_arg.vlan_tci = + rte_cpu_to_be_16(res->vlan_arg_vlan); + + /* Extra nat arguments */ + nat_arg = &entry.action.behavior_arg.nat_arg; + + nat_arg->op = str2fdir_behavior_sub_op(res->nat_arg_op); + switch (entry.input.flow_type) { + case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP: + IPV4_ADDR_TO_UINT(res->nat_arg_ip_src, + nat_arg->nat.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->nat_arg_ip_dst, + nat_arg->nat.tcp4.ip.dst_ip); + nat_arg->nat.tcp4.src_port = + rte_cpu_to_be_16(res->nat_arg_port_src); + nat_arg->nat.tcp4.dst_port = + rte_cpu_to_be_16(res->nat_arg_port_dst); + break; + case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP: + IPV6_ADDR_TO_ARRAY(res->nat_arg_ip_src, + nat_arg->nat.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->nat_arg_ip_dst, + nat_arg->nat.tcp6.ip.dst_ip); + nat_arg->nat.tcp6.src_port = + rte_cpu_to_be_16(res->nat_arg_port_src); + nat_arg->nat.tcp6.dst_port = + rte_cpu_to_be_16(res->nat_arg_port_dst); + break; + default: + break; + } + } else if (!strcmp(res->drop, "drop")) { entry.action.behavior = RTE_ETH_FDIR_REJECT; - else + } else { entry.action.behavior = RTE_ETH_FDIR_ACCEPT; + } if (!strcmp(res->pf_vf, "pf")) entry.input.flow_ext.is_vf = 0; @@ -8302,31 +8533,93 @@ cmdline_parse_token_string_t cmd_flow_director_flow = cmdline_parse_token_string_t cmd_flow_director_flow_type = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#" - "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload"); + "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#" + "ipv4-tcp-pkt-filter#ipv4-udp-pkt-filter#ipv6-tcp-pkt-filter#" + "ipv6-udp-pkt-filter"); +cmdline_parse_token_string_t cmd_flow_director_iport = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + iport, "ingress-port"); +cmdline_parse_token_num_t cmd_flow_director_iport_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + iport_id, UINT8); +cmdline_parse_token_num_t cmd_flow_director_iport_id_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + iport_id_mask, UINT8); cmdline_parse_token_string_t cmd_flow_director_ether = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, ether, "ether"); cmdline_parse_token_num_t cmd_flow_director_ether_type = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, ether_type, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ether_type_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ether_type_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_ivlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + ivlan, "inner-vlan"); +cmdline_parse_token_num_t cmd_flow_director_ivlan_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ivlan_value, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ivlan_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ivlan_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_ovlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + ovlan, "outer-vlan"); +cmdline_parse_token_num_t cmd_flow_director_ovlan_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ovlan_value, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ovlan_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ovlan_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_tos = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + tos, "tos"); +cmdline_parse_token_num_t cmd_flow_director_tos_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + tos_value, UINT8); +cmdline_parse_token_num_t cmd_flow_director_tos_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + tos_mask, UINT8); +cmdline_parse_token_string_t cmd_flow_director_proto = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + proto, "proto"); +cmdline_parse_token_num_t cmd_flow_director_proto_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + proto_value, UINT8); +cmdline_parse_token_num_t cmd_flow_director_proto_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + proto_mask, UINT8); cmdline_parse_token_string_t cmd_flow_director_src = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, src, "src"); cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src = TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, ip_src); +cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src_mask = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + ip_src_mask); cmdline_parse_token_num_t cmd_flow_director_port_src = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, port_src, UINT16); +cmdline_parse_token_num_t cmd_flow_director_port_src_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_src_mask, UINT16); cmdline_parse_token_string_t cmd_flow_director_dst = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, dst, "dst"); cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst = TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, ip_dst); +cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst_mask = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + ip_dst_mask); cmdline_parse_token_num_t cmd_flow_director_port_dst = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, port_dst, UINT16); +cmdline_parse_token_num_t cmd_flow_director_port_dst_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_dst_mask, UINT16); cmdline_parse_token_string_t cmd_flow_director_verify_tag = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, verify_tag, "verify_tag"); @@ -8347,7 +8640,7 @@ cmdline_parse_token_string_t cmd_flow_director_flexbytes_value = flexbytes_value, NULL); cmdline_parse_token_string_t cmd_flow_director_drop = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, - drop, "drop#fwd"); + drop, "drop#fwd#switch"); cmdline_parse_token_string_t cmd_flow_director_pf_vf = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, pf_vf, NULL); @@ -8395,6 +8688,61 @@ cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, tunnel_id_value, UINT32); +cmdline_parse_token_string_t cmd_flow_director_port_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + port_arg, "port-arg"); +cmdline_parse_token_string_t cmd_flow_director_port_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + port_arg_op, "none#port-redirect"); +cmdline_parse_token_num_t cmd_flow_director_port_arg_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_arg_port_id, UINT8); +cmdline_parse_token_string_t cmd_flow_director_mac_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mac_arg, "mac-arg"); +cmdline_parse_token_string_t cmd_flow_director_mac_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mac_arg_op, "none#mac-rewrite"); +cmdline_parse_token_etheraddr_t cmd_flow_director_mac_arg_src_mac = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result, + mac_arg_src_mac); +cmdline_parse_token_etheraddr_t cmd_flow_director_mac_arg_dst_mac = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result, + mac_arg_dst_mac); +cmdline_parse_token_string_t cmd_flow_director_vlan_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + vlan_arg, "vlan-arg"); +cmdline_parse_token_string_t cmd_flow_director_vlan_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + vlan_arg_op, "none#vlan-rewrite#vlan-del"); +cmdline_parse_token_num_t cmd_flow_director_vlan_arg_vlan = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + vlan_arg_vlan, UINT16); +cmdline_parse_token_string_t cmd_flow_director_nat_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg, "nat-arg"); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_op, "none#nat-rewrite"); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_src = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_src, "src"); +cmdline_parse_token_ipaddr_t cmd_flow_director_nat_arg_ip_src = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + nat_arg_ip_src); +cmdline_parse_token_num_t cmd_flow_director_nat_arg_port_src = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + nat_arg_port_src, UINT16); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_dst = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_dst, "dst"); +cmdline_parse_token_ipaddr_t cmd_flow_director_nat_arg_ip_dst = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + nat_arg_ip_dst); +cmdline_parse_token_num_t cmd_flow_director_nat_arg_port_dst = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + nat_arg_port_dst, UINT16); + cmdline_parse_inst_t cmd_add_del_ip_flow_director = { .f = cmd_flow_director_filter_parsed, .data = NULL, @@ -8517,6 +8865,76 @@ cmdline_parse_inst_t cmd_add_del_l2_flow_director = { }, }; +cmdline_parse_inst_t cmd_add_del_pkt_filter_flow_director = { + .f = cmd_flow_director_filter_parsed, + .data = NULL, + .help_str = "add or delete a packet filter flow director entry on NIC", + .tokens = { + (void *)&cmd_flow_director_filter, + (void *)&cmd_flow_director_port_id, + (void *)&cmd_flow_director_mode, + (void *)&cmd_flow_director_mode_ip, + (void *)&cmd_flow_director_ops, + (void *)&cmd_flow_director_flow, + (void *)&cmd_flow_director_flow_type, + (void *)&cmd_flow_director_iport, + (void *)&cmd_flow_director_iport_id, + (void *)&cmd_flow_director_iport_id_mask, + (void *)&cmd_flow_director_ether, + (void *)&cmd_flow_director_ether_type, + (void *)&cmd_flow_director_ether_type_mask, + (void *)&cmd_flow_director_ivlan, + (void *)&cmd_flow_director_ivlan_value, + (void *)&cmd_flow_director_ivlan_mask, + (void *)&cmd_flow_director_ovlan, + (void *)&cmd_flow_director_ovlan_value, + (void *)&cmd_flow_director_ovlan_mask, + (void *)&cmd_flow_director_tos, + (void *)&cmd_flow_director_tos_value, + (void *)&cmd_flow_director_tos_mask, + (void *)&cmd_flow_director_proto, + (void *)&cmd_flow_director_proto_value, + (void *)&cmd_flow_director_proto_mask, + (void *)&cmd_flow_director_src, + (void *)&cmd_flow_director_ip_src, + (void *)&cmd_flow_director_ip_src_mask, + (void *)&cmd_flow_director_port_src, + (void *)&cmd_flow_director_port_src_mask, + (void *)&cmd_flow_director_dst, + (void *)&cmd_flow_director_ip_dst, + (void *)&cmd_flow_director_ip_dst_mask, + (void *)&cmd_flow_director_port_dst, + (void *)&cmd_flow_director_port_dst_mask, + (void *)&cmd_flow_director_flexbytes, + (void *)&cmd_flow_director_flexbytes_value, + (void *)&cmd_flow_director_drop, + (void *)&cmd_flow_director_pf_vf, + (void *)&cmd_flow_director_queue, + (void *)&cmd_flow_director_queue_id, + (void *)&cmd_flow_director_port_arg, + (void *)&cmd_flow_director_port_arg_op, + (void *)&cmd_flow_director_port_arg_port_id, + (void *)&cmd_flow_director_mac_arg, + (void *)&cmd_flow_director_mac_arg_op, + (void *)&cmd_flow_director_mac_arg_src_mac, + (void *)&cmd_flow_director_mac_arg_dst_mac, + (void *)&cmd_flow_director_vlan_arg, + (void *)&cmd_flow_director_vlan_arg_op, + (void *)&cmd_flow_director_vlan_arg_vlan, + (void *)&cmd_flow_director_nat_arg, + (void *)&cmd_flow_director_nat_arg_op, + (void *)&cmd_flow_director_nat_arg_src, + (void *)&cmd_flow_director_nat_arg_ip_src, + (void *)&cmd_flow_director_nat_arg_port_src, + (void *)&cmd_flow_director_nat_arg_dst, + (void *)&cmd_flow_director_nat_arg_ip_dst, + (void *)&cmd_flow_director_nat_arg_port_dst, + (void *)&cmd_flow_director_fd_id, + (void *)&cmd_flow_director_fd_id_value, + NULL, + }, +}; + cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = { .f = cmd_flow_director_filter_parsed, .data = NULL, @@ -9756,6 +10174,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director, + (cmdline_parse_inst_t *)&cmd_add_del_pkt_filter_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director, (cmdline_parse_inst_t *)&cmd_flush_flow_director, -- 2.5.3 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support 2015-12-10 14:01 [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 2/3] testpmd: add an example to show packet filter flow Rahul Lakkireddy @ 2015-12-10 14:01 ` Rahul Lakkireddy 2015-12-15 8:40 ` Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 3 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-10 14:01 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan Current filtering support will be enhanced to accommodate support for Chelsio T5 hardware filtering support. Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com> --- doc/guides/rel_notes/deprecation.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 1c7ab01..ca43b16 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -19,3 +19,9 @@ Deprecation Notices and table action handlers will be updated: the pipeline parameter will be added, the packets mask parameter will be either removed (for input port action handler) or made input-only. + +* The filtering support will be changed to add a new packet filter + flow, add a new behavior 'switch', add an ability to add mask + for fields in each filter rule, and add an ability to pass extra + arguments for the behavior taken to allow rewriting matched fields + in filter rule. -- 2.5.3 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support 2015-12-10 14:01 ` [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support Rahul Lakkireddy @ 2015-12-15 8:40 ` Rahul Lakkireddy 2015-12-15 8:55 ` Thomas Monjalon 0 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-15 8:40 UTC (permalink / raw) To: dev, Thomas Monjalon; +Cc: Kumar Sanghvi, Felix Marti, Nirranjan Kirubaharan Hi Thomas, I am preparing a v2 of this series where I will be accomodating some more fields to be considered for filtering. However, if the overall approach seems ok to everyone then, should I submit a separate patch for this ABI change announcement ? Thanks, Rahul. On Thursday, December 12/10/15, 2015 at 19:31:04 +0530, Rahul Lakkireddy wrote: > Current filtering support will be enhanced to accommodate support > for Chelsio T5 hardware filtering support. > > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> > Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com> > --- > doc/guides/rel_notes/deprecation.rst | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst > index 1c7ab01..ca43b16 100644 > --- a/doc/guides/rel_notes/deprecation.rst > +++ b/doc/guides/rel_notes/deprecation.rst > @@ -19,3 +19,9 @@ Deprecation Notices > and table action handlers will be updated: > the pipeline parameter will be added, the packets mask parameter will be > either removed (for input port action handler) or made input-only. > + > +* The filtering support will be changed to add a new packet filter > + flow, add a new behavior 'switch', add an ability to add mask > + for fields in each filter rule, and add an ability to pass extra > + arguments for the behavior taken to allow rewriting matched fields > + in filter rule. > -- > 2.5.3 > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support 2015-12-15 8:40 ` Rahul Lakkireddy @ 2015-12-15 8:55 ` Thomas Monjalon 2015-12-15 13:51 ` Rahul Lakkireddy 0 siblings, 1 reply; 21+ messages in thread From: Thomas Monjalon @ 2015-12-15 8:55 UTC (permalink / raw) To: Rahul Lakkireddy; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar Sanghvi 2015-12-15 14:10, Rahul Lakkireddy: > Hi Thomas, > > I am preparing a v2 of this series where I will be accomodating some > more fields to be considered for filtering. However, if the overall > approach seems ok to everyone then, should I submit a separate patch > for this ABI change announcement ? Yes, if this announce is not enough: http://dpdk.org/browse/dpdk/commit/?id=648e6b3815a35 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support 2015-12-15 8:55 ` Thomas Monjalon @ 2015-12-15 13:51 ` Rahul Lakkireddy 2015-12-15 13:57 ` Thomas Monjalon 0 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-15 13:51 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi Thomas, On Tuesday, December 12/15/15, 2015 at 00:55:20 -0800, Thomas Monjalon wrote: > 2015-12-15 14:10, Rahul Lakkireddy: > > Hi Thomas, > > > > I am preparing a v2 of this series where I will be accomodating some > > more fields to be considered for filtering. However, if the overall > > approach seems ok to everyone then, should I submit a separate patch > > for this ABI change announcement ? > > Yes, if this announce is not enough: > http://dpdk.org/browse/dpdk/commit/?id=648e6b3815a35 > Apart from rte_eth_fdir_flow ABI change mentioned in above link, new fields will be added to rte_eth_ipv4_flow and rte_eth_ipv6_flow, which break their ABI. Also, 4 new flow types will be added, which increases RTE_ETH_FLOW_MAX from 18 to 22 and breaks the ABI. Should I send a separate ABI change announce patch for each of them? Thanks, Rahul ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support 2015-12-15 13:51 ` Rahul Lakkireddy @ 2015-12-15 13:57 ` Thomas Monjalon 0 siblings, 0 replies; 21+ messages in thread From: Thomas Monjalon @ 2015-12-15 13:57 UTC (permalink / raw) To: Rahul Lakkireddy; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S 2015-12-15 19:21, Rahul Lakkireddy: > Hi Thomas, > > On Tuesday, December 12/15/15, 2015 at 00:55:20 -0800, Thomas Monjalon wrote: > > 2015-12-15 14:10, Rahul Lakkireddy: > > > Hi Thomas, > > > > > > I am preparing a v2 of this series where I will be accomodating some > > > more fields to be considered for filtering. However, if the overall > > > approach seems ok to everyone then, should I submit a separate patch > > > for this ABI change announcement ? > > > > Yes, if this announce is not enough: > > http://dpdk.org/browse/dpdk/commit/?id=648e6b3815a35 > > > > Apart from rte_eth_fdir_flow ABI change mentioned in above link, new > fields will be added to rte_eth_ipv4_flow and rte_eth_ipv6_flow, > which break their ABI. > > Also, 4 new flow types will be added, which increases RTE_ETH_FLOW_MAX > from 18 to 22 and breaks the ABI. > > Should I send a separate ABI change announce patch for each of them? Yes please send a patch (1 is enough). You have less than 30 minutes :) ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter 2015-12-10 14:01 [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter Rahul Lakkireddy ` (2 preceding siblings ...) 2015-12-10 14:01 ` [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support Rahul Lakkireddy @ 2015-12-23 12:41 ` Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy ` (2 more replies) 3 siblings, 3 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-23 12:41 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan This RFC series of patches attempt to extend the flow director filter to add support for Chelsio T5 hardware filtering capabilities. Chelsio T5 supports carrying out filtering in hardware which supports 3 actions to carry out on a packet which hit a filter viz. 1. Action Pass - Packets hitting a filter rule can be directed to a particular RXQ. 2. Action Drop - Packets hitting a filter rule are dropped in h/w. 3. Action Switch - Packets hitting a filter rule can be switched in h/w from one port to another, without involvement of host. Also, the action Switch also supports rewrite of src-mac/dst-mac headers as well as rewrite of vlan headers. It also supports rewrite of IP headers and thereby, supports NAT (Network Address Translation) in h/w. Also, each filter rule can optionally support specifying a mask value i.e. it's possible to create a filter rule for an entire subnet of IP addresses or a range of tcp/udp ports, etc. Patch 1 does the following: - Adds an additional flow rte_eth_pkt_filter_flow which encapsulates ingress ports, l2 payload, vlan and ntuples. - Adds an additional mask for the flow to allow range of values to be matched. - Adds an ability to set both filters with masks (Maskfull) and without masks (Maskless). Also allow prioritizing one of these filter types over the other when a packet matches several types. - Adds a new behavior 'switch'. - Adds behavior arguments that can be passed when a particular behavior is taken. For ex: in case of action 'switch', pass additional 4-tuple to allow rewriting src/dst ip and port addresses to support NAT'ing. Patch 2 shows testpmd command line example to support packet filter flow. The patch series has been compile tested on all x86 gcc targets and the current fdir filter supported drivers seem to return appropriate error codes when this new flow type and the new action are not supported and hence are not affected. Posting this series mainly for discussion on API change. Once this is agreeable then, I will post the cxgbe PMD changes to use the new API. --- v2: 1. Added ttl to rte_eth_ipv4_flow and tc, flow_label, next_header, and hop_limit to rte_eth_ipv6_flow. 2. Added new field type to rte_eth_pkt_filter_flow to differentiate between maskfull and maskless filter types. 3. Added new field prio to rte_eth_pkt_filter_flow to allow setting priority over maskfull or maskless when packet matches multiple filter types. 4. Added new behavior sub op RTE_FDIR_BEHAVIOR_SUB_OP_SWAP to allow swapping fields in matched flows. For ex, useful when swapping mac addresses in hardware before switching. 5. Updated the testpmd example to reflect the above new changes. 6. Dropped Patch 3 since the ABI announcement has already been merged. Rahul Lakkireddy (2): ethdev: add packet filter flow and new behavior switch to fdir testpmd: add an example to show packet filter flow app/test-pmd/cmdline.c | 528 +++++++++++++++++++++++++++++++++++++++- lib/librte_ether/rte_eth_ctrl.h | 127 +++++++++- 2 files changed, 646 insertions(+), 9 deletions(-) -- 2.5.3 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy @ 2015-12-23 12:41 ` Rahul Lakkireddy 2016-01-13 1:12 ` Wu, Jingjing 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 2/2] testpmd: add an example to show packet filter flow Rahul Lakkireddy 2016-01-11 13:50 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-23 12:41 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan 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. Allow selection of maskfull vs maskless filter types. Provide mechanism to set priority to maskfull vs maskless filter types when packet matches several filter types. Add a new vlan flow containing inner and outer vlan to match. Add tos, proto, and ttl fields that can be matched for ipv4 flow. Add tc, flow_label, next_header, and hop_limit fields that can be matched for ipv6 flow. Add a new behavior switch. Add the ability to provide behavior arguments to allow insert/deletion/ swapping 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> --- v2: 1. Added ttl to rte_eth_ipv4_flow and tc, flow_label, next_header, and hop_limit to rte_eth_ipv6_flow. 2. Added new field type to rte_eth_pkt_filter_flow to differentiate between maskfull and maskless filter types. 3. Added new field prio to rte_eth_pkt_filter_flow to allow setting priority over maskfull or maskless when packet matches multiple filter types. 4. Added new behavior sub op RTE_FDIR_BEHAVIOR_SUB_OP_SWAP to allow swapping fields in matched flows. Useful when swapping mac addresses in hardware before switching. lib/librte_ether/rte_eth_ctrl.h | 127 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h index ce224ad..5cc22a0 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,9 @@ 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. */ + uint8_t ttl; /**< IPV4 time to live to match. */ }; /** @@ -443,6 +450,10 @@ struct rte_eth_sctpv4_flow { struct rte_eth_ipv6_flow { uint32_t src_ip[4]; /**< IPv6 source address to match. */ uint32_t dst_ip[4]; /**< IPv6 destination address to match. */ + uint8_t tc; /**< IPv6 traffic class to match. */ + uint32_t flow_label; /**< IPv6 flow label to match. */ + uint8_t next_header; /**< IPv6 next header to match. */ + uint8_t hop_limit; /**< IPv6 hop limits to match. */ }; /** @@ -500,6 +511,51 @@ 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. + */ +enum rte_eth_pkt_filter_type { + RTE_ETH_PKT_FILTER_TYPE_MASKLESS = 0, /**< Ignore masks in the flow */ + RTE_ETH_PKT_FILTER_TYPE_MASKFULL, /**< Consider masks in the flow */ +}; + +struct rte_eth_pkt_filter_flow { + enum rte_eth_pkt_filter_type type; /**< Type of filter */ + enum rte_eth_pkt_filter_type prio; + /**< Prioritize the filter type when a packet matches several types */ + 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 +570,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 +602,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 +617,71 @@ 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 */ + RTE_FDIR_BEHAVIOR_SUB_OP_SWAP, + /**< Swap 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 rewrite. */ + 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 +692,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 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy @ 2016-01-13 1:12 ` Wu, Jingjing 2016-01-13 8:49 ` Rahul Lakkireddy 0 siblings, 1 reply; 21+ messages in thread From: Wu, Jingjing @ 2016-01-13 1:12 UTC (permalink / raw) To: Rahul Lakkireddy, dev; +Cc: Kumar Sanghvi, Felix Marti, Nirranjan Kirubaharan > > diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h > index ce224ad..5cc22a0 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 > How to distinguish RTE_ETH_FLOW_PKT_FILTER_IPV4_XX with RTE_ETH_FLOW_NONFRAG_IPV4_XX, what is the difference? > /** > * Feature filter types > @@ -407,6 +411,9 @@ 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. */ > + uint8_t ttl; /**< IPV4 time to live to match. */ > }; > > /** > @@ -443,6 +450,10 @@ struct rte_eth_sctpv4_flow { struct > rte_eth_ipv6_flow { > uint32_t src_ip[4]; /**< IPv6 source address to match. */ > uint32_t dst_ip[4]; /**< IPv6 destination address to match. */ > + uint8_t tc; /**< IPv6 traffic class to match. */ > + uint32_t flow_label; /**< IPv6 flow label to match. */ > + uint8_t next_header; /**< IPv6 next header to match. */ > + uint8_t hop_limit; /**< IPv6 hop limits to match. */ > }; > There is also a patch http://dpdk.org/dev/patchwork/patch/9661/ which added these fields. Maybe we can merge them together. > +struct rte_eth_pkt_filter_flow { > + enum rte_eth_pkt_filter_type type; /**< Type of filter */ > + enum rte_eth_pkt_filter_type prio; > + /**< Prioritize the filter type when a packet matches several types */ > + 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 +570,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; > }; Why not use rte_eth_XX_flow directly but add a new one? Is it because of the mask? If so, how about to add a field in rte_eth_fdir_input like: struct rte_eth_fdir_input { uint16_t flow_type; union rte_eth_fdir_flow flow; /**< Flow fields to match, dependent on flow_type */ union rte_eth_fdir_flow flow_mask; struct rte_eth_fdir_flow_ext flow_ext; /**< Additional fields to match */ }; Thanks Jingjing ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-13 1:12 ` Wu, Jingjing @ 2016-01-13 8:49 ` Rahul Lakkireddy 2016-01-13 13:16 ` Wu, Jingjing 0 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2016-01-13 8:49 UTC (permalink / raw) To: Wu, Jingjing; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi Jingjing, On Tuesday, January 01/12/16, 2016 at 17:12:47 -0800, Wu, Jingjing wrote: > > > > diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h > > index ce224ad..5cc22a0 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 > > > How to distinguish RTE_ETH_FLOW_PKT_FILTER_IPV4_XX with RTE_ETH_FLOW_NONFRAG_IPV4_XX, what is the difference? The packet filter flow is basically a superset containing Ethernet, vlan, ipv4/ipv6 and tcp/udp flows whose fields can all be matched at the same time, unlike in case of the current flow director which seems to match only one of the flows at any given time. Additionally, it also allows specifying masks. I separated the two to make this meaning explicit. If this is not necessary, then I will merge them. > > /** > > * Feature filter types > > @@ -407,6 +411,9 @@ 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. */ > > + uint8_t ttl; /**< IPV4 time to live to match. */ > > }; > > > > /** > > @@ -443,6 +450,10 @@ struct rte_eth_sctpv4_flow { struct > > rte_eth_ipv6_flow { > > uint32_t src_ip[4]; /**< IPv6 source address to match. */ > > uint32_t dst_ip[4]; /**< IPv6 destination address to match. */ > > + uint8_t tc; /**< IPv6 traffic class to match. */ > > + uint32_t flow_label; /**< IPv6 flow label to match. */ > > + uint8_t next_header; /**< IPv6 next header to match. */ > > + uint8_t hop_limit; /**< IPv6 hop limits to match. */ > > }; > > > There is also a patch http://dpdk.org/dev/patchwork/patch/9661/ which added these fields. Maybe we can merge them together. Yes, we can merge them. Would you like me to merge your patch here? > > +struct rte_eth_pkt_filter_flow { > > + enum rte_eth_pkt_filter_type type; /**< Type of filter */ > > + enum rte_eth_pkt_filter_type prio; > > + /**< Prioritize the filter type when a packet matches several types */ > > + 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 +570,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; > > }; > Why not use rte_eth_XX_flow directly but add a new one? Is it because of the mask? If so, how about to add a field in rte_eth_fdir_input like: > struct rte_eth_fdir_input { > uint16_t flow_type; > union rte_eth_fdir_flow flow; > /**< Flow fields to match, dependent on flow_type */ > union rte_eth_fdir_flow flow_mask; > struct rte_eth_fdir_flow_ext flow_ext; > /**< Additional fields to match */ > }; > > Thanks > Jingjing The current rte_eth_XX_flow only allow matching _one_ of the flows because of the union. In contrast, rte_eth_pkt_filter_flow can match several flows at the same time; i.e. it can match ethernet, vlan, ip, and tcp/udp all at the same time. rte_eth_pkt_filter_flow is basically a superset containing several flows that can be matched at the same time. In our Chelsio T5 hardware, it's possible to have several flows that can be matched in a single rule. This is why I've created a superset that can match several flows in the same rule. Thanks, Rahul ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-13 8:49 ` Rahul Lakkireddy @ 2016-01-13 13:16 ` Wu, Jingjing 2016-01-14 8:48 ` Wu, Jingjing 0 siblings, 1 reply; 21+ messages in thread From: Wu, Jingjing @ 2016-01-13 13:16 UTC (permalink / raw) To: Rahul Lakkireddy; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi, Rahul > -----Original Message----- > From: Rahul Lakkireddy [mailto:rahul.lakkireddy@chelsio.com] > Sent: Wednesday, January 13, 2016 4:49 PM > To: Wu, Jingjing > Cc: dev@dpdk.org; Felix Marti; Kumar A S; Nirranjan Kirubaharan > Subject: Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior > switch to fdir > > Hi Jingjing, > > On Tuesday, January 01/12/16, 2016 at 17:12:47 -0800, Wu, Jingjing wrote: > > > > > > diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h > > > index ce224ad..5cc22a0 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 > > > > > How to distinguish RTE_ETH_FLOW_PKT_FILTER_IPV4_XX with > RTE_ETH_FLOW_NONFRAG_IPV4_XX, what is the difference? > > The packet filter flow is basically a superset containing Ethernet, > vlan, ipv4/ipv6 and tcp/udp flows whose fields can all be matched at > the same time, unlike in case of the current flow director which seems > to match only one of the flows at any given time. Additionally, it also > allows specifying masks. I separated the two to make this meaning > explicit. If this is not necessary, then I will merge them. Thanks for clarification, now I understand. How about just define one to indicate using pkt_filter? And move the IPV4_XX info to the structure rte_eth_pkt_filter? > > There is also a patch http://dpdk.org/dev/patchwork/patch/9661/ which added these > fields. Maybe we can merge them together. > > Yes, we can merge them. Would you like me to merge your patch here? The i40e driver implementation is done based on the change. If you'd like to merge, maybe other patches in the patch set also need to be merged. Anyway, I think maintainer can deal with it. > > The current rte_eth_XX_flow only allow matching _one_ of the flows > because of the union. In contrast, rte_eth_pkt_filter_flow can match > several flows at the same time; i.e. it can match ethernet, vlan, ip, > and tcp/udp all at the same time. rte_eth_pkt_filter_flow is basically > a superset containing several flows that can be matched at the same > time. > > In our Chelsio T5 hardware, it's possible to have several flows that can > be matched in a single rule. This is why I've created a superset that > can match several flows in the same rule. > > Thanks, > Rahul Thanks for clarification, it's clear. And it's great to have this feature. Even it is a superset containing several flows, we still can use the existing structs like struct rte_eth_ipv4_flow { struct rte_eth_l2_flow ether; struct rte_eth_vlan_flow vlan; uint32_t src_ip; uint32_t dst_ip; }; What do you think? Thanks Jingjing ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-13 13:16 ` Wu, Jingjing @ 2016-01-14 8:48 ` Wu, Jingjing 2016-01-14 13:17 ` Rahul Lakkireddy 0 siblings, 1 reply; 21+ messages in thread From: Wu, Jingjing @ 2016-01-14 8:48 UTC (permalink / raw) To: 'Rahul Lakkireddy', Chilikin, Andrey Cc: 'dev@dpdk.org', 'Felix Marti', 'Nirranjan Kirubaharan', 'Kumar A S' Hi, Rahul Just another thought, please consider about it: Add a new flow type like #define RTE_ETH_FLOW_IPV6_UDP_EX 17 +#define RTE_ETH_FLOW_RAW_PKT 18 Then add a new item in rte_eth_fdir_flow union rte_eth_fdir_flow { struct rte_eth_l2_flow l2_flow; struct rte_eth_udpv4_flow udp4_flow; struct rte_eth_tcpv4_flow tcp4_flow; struct rte_eth_sctpv4_flow sctp4_flow; struct rte_eth_ipv4_flow ip4_flow; struct rte_eth_udpv6_flow udp6_flow; struct rte_eth_tcpv6_flow tcp6_flow; struct rte_eth_sctpv6_flow sctp6_flow; struct rte_eth_ipv6_flow ipv6_flow; struct rte_eth_mac_vlan_flow mac_vlan_flow; struct rte_eth_tunnel_flow tunnel_flow; + uint8_t raw_pkt[80]; }; Then add mask item in rte_eth_fdir_input: struct rte_eth_fdir_input { uint16_t flow_type; union rte_eth_fdir_flow flow; + union rte_eth_fdir_flow flow_mask; /**< Flow fields to match, dependent on flow_type */ struct rte_eth_fdir_flow_ext flow_ext; /**< Additional fields to match */ }; Then the filter can be added just in a format of raw packet, it looks generic, and even other NIC can use this too. Thanks Jingjing > -----Original Message----- > From: Wu, Jingjing > Sent: Wednesday, January 13, 2016 9:17 PM > To: Rahul Lakkireddy > Cc: dev@dpdk.org; Felix Marti; Kumar A S; Nirranjan Kirubaharan > Subject: RE: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new > behavior switch to fdir > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-14 8:48 ` Wu, Jingjing @ 2016-01-14 13:17 ` Rahul Lakkireddy 2016-01-15 1:30 ` Wu, Jingjing 0 siblings, 1 reply; 21+ messages in thread From: Rahul Lakkireddy @ 2016-01-14 13:17 UTC (permalink / raw) To: Wu, Jingjing Cc: 'dev@dpdk.org', Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi Jingjing, On Thursday, January 01/14/16, 2016 at 00:48:17 -0800, Wu, Jingjing wrote: > Hi, Rahul > > Just another thought, please consider about it: > > Add a new flow type like > > #define RTE_ETH_FLOW_IPV6_UDP_EX 17 > +#define RTE_ETH_FLOW_RAW_PKT 18 > > Then add a new item in rte_eth_fdir_flow > union rte_eth_fdir_flow { > struct rte_eth_l2_flow l2_flow; > struct rte_eth_udpv4_flow udp4_flow; > struct rte_eth_tcpv4_flow tcp4_flow; > struct rte_eth_sctpv4_flow sctp4_flow; > struct rte_eth_ipv4_flow ip4_flow; > struct rte_eth_udpv6_flow udp6_flow; > struct rte_eth_tcpv6_flow tcp6_flow; > struct rte_eth_sctpv6_flow sctp6_flow; > struct rte_eth_ipv6_flow ipv6_flow; > struct rte_eth_mac_vlan_flow mac_vlan_flow; > struct rte_eth_tunnel_flow tunnel_flow; > + uint8_t raw_pkt[80]; > }; > > Then add mask item in rte_eth_fdir_input: > > struct rte_eth_fdir_input { > uint16_t flow_type; > union rte_eth_fdir_flow flow; > + union rte_eth_fdir_flow flow_mask; > /**< Flow fields to match, dependent on flow_type */ > struct rte_eth_fdir_flow_ext flow_ext; > /**< Additional fields to match */ > }; > > Then the filter can be added just in a format of raw packet, it looks generic, and even other NIC can use this too. > > Thanks > Jingjing This approach seems generic enough to allow any vendor specific data to be passed in filter as well. However, 80 seems to be too low for multiple flow types that can be combined in the same filter rule. I think size of 256 seems reasonable. Could the same thing be done for action arguments as well? Can we add the same generic info to rte_eth_fdir_action too? struct rte_eth_fdir_action { uint16_t rx_queue; enum rte_eth_fdir_behavior behavior; enum rte_eth_fdir_status report_status; uint8_t flex_off; + uint8_t behavior_arg[256]; }; This way, we can pass vendor specific action arguments too. What do you think? Also, now if we take this approach then, I am wondering, that all vendors would need to document their own vendor-specific format of taking filter match and filter action arguments, right? And probably, even come up with their own example application showing how to apply filters via dpdk on their card? Thanks, Rahul ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-14 13:17 ` Rahul Lakkireddy @ 2016-01-15 1:30 ` Wu, Jingjing 2016-01-15 7:11 ` Rahul Lakkireddy 0 siblings, 1 reply; 21+ messages in thread From: Wu, Jingjing @ 2016-01-15 1:30 UTC (permalink / raw) To: Rahul Lakkireddy Cc: 'dev@dpdk.org', Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi, Rahul > This approach seems generic enough to allow any vendor specific data > to be passed in filter as well. However, 80 seems to be too low for > multiple flow types that can be combined in the same filter rule. > I think size of 256 seems reasonable. > Yes, 80 is just an example. > Could the same thing be done for action arguments as well? Can we add > the same generic info to rte_eth_fdir_action too? > > struct rte_eth_fdir_action { > uint16_t rx_queue; > enum rte_eth_fdir_behavior behavior; > enum rte_eth_fdir_status report_status; > uint8_t flex_off; > + uint8_t behavior_arg[256]; > }; > > This way, we can pass vendor specific action arguments too. What do > you think? Yes, it also makes sense. > Also, now if we take this approach then, I am wondering, that all > vendors would need to document their own vendor-specific format of > taking filter match and filter action arguments, right? > > And probably, even come up with their own example application showing > how to apply filters via dpdk on their card? Yes, I guess it will be better to doc it or example it. Even currently, different kinds of NIC may need different configuration. Or you can add description (how to configure) in your driver's comment log? Not sure about the others' opinion? Thanks Jingjing ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir 2016-01-15 1:30 ` Wu, Jingjing @ 2016-01-15 7:11 ` Rahul Lakkireddy 0 siblings, 0 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2016-01-15 7:11 UTC (permalink / raw) To: Wu, Jingjing; +Cc: dev, Felix Marti, Nirranjan Kirubaharan, Kumar A S Hi Jingjing, On Thursday, January 01/14/16, 2016 at 17:30:53 -0800, Wu, Jingjing wrote: > Hi, Rahul > > > This approach seems generic enough to allow any vendor specific data > > to be passed in filter as well. However, 80 seems to be too low for > > multiple flow types that can be combined in the same filter rule. > > I think size of 256 seems reasonable. > > > Yes, 80 is just an example. > > Could the same thing be done for action arguments as well? Can we add > > the same generic info to rte_eth_fdir_action too? > > > > struct rte_eth_fdir_action { > > uint16_t rx_queue; > > enum rte_eth_fdir_behavior behavior; > > enum rte_eth_fdir_status report_status; > > uint8_t flex_off; > > + uint8_t behavior_arg[256]; > > }; > > > > This way, we can pass vendor specific action arguments too. What do > > you think? > Yes, it also makes sense. > > Also, now if we take this approach then, I am wondering, that all > > vendors would need to document their own vendor-specific format of > > taking filter match and filter action arguments, right? > > > > And probably, even come up with their own example application showing > > how to apply filters via dpdk on their card? > Yes, I guess it will be better to doc it or example it. Even currently, different kinds of NIC may need different configuration. > Or you can add description (how to configure) in your driver's comment log? > Not sure about the others' opinion? > > Thanks > Jingjing Ok. We will wait for a couple of days to get more opinions from others. If the above generic approach is agreeable to everyone, then I will post the patch series using this new approach. Thanks, Rahul ^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [RFC v2 2/2] testpmd: add an example to show packet filter flow 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy @ 2015-12-23 12:41 ` Rahul Lakkireddy 2016-01-11 13:50 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2 siblings, 0 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2015-12-23 12:41 UTC (permalink / raw) To: dev; +Cc: Felix Marti, Kumar Sanghvi, Nirranjan Kirubaharan Extend the existing flow_director_filter to add support for packet filter flow. Also shows how to pass the extra behavior arguments to rewrite fields in matched filter rules. Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com> --- v2: 1. Added new field filter-type to allow specifying maskfull vs maskless filter types. 2. Added new field filter-prio to allow specifying the priority between maskfull and maskless filters i.e. if we have a maskfull and a maskless filter both of which can match a single traffic pattern then, which one takes the priority is determined by filter-prio. 3. Added new field flow-label to be matched for ipv6. 4. Added new mac-swap behavior argument. app/test-pmd/cmdline.c | 528 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 520 insertions(+), 8 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 73298c9..3402f2c 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -641,7 +641,7 @@ static void cmd_help_long_parsed(void *parsed_result, " flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)" " src (src_ip_address) dst (dst_ip_address)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " (drop|fwd|switch) pf|vf(vf_id) queue (queue_id)" " fd_id (fd_id_value)\n" " Add/Del an IP type flow director filter.\n\n" @@ -650,7 +650,7 @@ static void cmd_help_long_parsed(void *parsed_result, " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " (drop|fwd|switch) pf|vf(vf_id) queue (queue_id)" " fd_id (fd_id_value)\n" " Add/Del an UDP/TCP type flow director filter.\n\n" @@ -659,16 +659,41 @@ static void cmd_help_long_parsed(void *parsed_result, " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" " tag (verification_tag) vlan (vlan_value)" - " flexbytes (flexbytes_value) (drop|fwd)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" " Add/Del a SCTP type flow director filter.\n\n" "flow_director_filter (port_id) mode IP (add|del|update)" " flow l2_payload ether (ethertype)" - " flexbytes (flexbytes_value) (drop|fwd)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" " Add/Del a l2 payload type flow director filter.\n\n" + "flow_director_filter (port_id) mode IP (add|del|update)" + " flow (ipv4-tcp-pkt-filter|ipv4-udp-pkt-filter" + " ipv6-tcp-pkt-filter|ipv6-udp-pkt-filter)" + " filter-type maskfull|maskless" + " filter-prio default|maskfull|maskless" + " ingress-port (port_id) (port_id_mask)" + " ether (ethertype) (ethertype_mask)" + " inner-vlan (inner_vlan_value) (inner_vlan_mask)" + " outer-vlan (outer_vlan_value) (outer_vlan_mask)" + " tos (tos_value) (tos_mask)" + " flow-label (flow_label_value) (flow_label_mask)" + " proto (proto_value) (proto_mask)" + " ttl (ttl_value) (ttl_mask)" + " src (src_ip) (src_ip_mask) (src_port) (src_port_mask)" + " dst (dst_ip) (dst_ip_mask) (dst_port) (dst_port_mask)" + " flexbytes (flexbytes_value) (drop|fwd|switch)" + " pf|vf(vf_id) queue (queue_id)" + " port-arg none|port-redirect (dst-port-id)" + " mac-arg none|mac-rewrite|mac-swap (src-mac) (dst-mac)" + " vlan-arg none|vlan-rewrite|vlan-del (vlan_value)" + " nat-arg none|nat-rewrite" + " src (src_ip) (src_port) dst (dst_ip) (dst_port)" + " fd_id (fd_id_value)\n" + " Add/Del a packet filter type flow director filter.\n\n" + "flow_director_filter (port_id) mode MAC-VLAN (add|del|update)" " mac (mac_address) vlan (vlan_value)" " flexbytes (flexbytes_value) (drop|fwd)" @@ -7973,14 +7998,44 @@ struct cmd_flow_director_result { cmdline_fixed_string_t ops; cmdline_fixed_string_t flow; cmdline_fixed_string_t flow_type; + cmdline_fixed_string_t filter_type; + cmdline_fixed_string_t filter_type_value; + cmdline_fixed_string_t filter_prio; + cmdline_fixed_string_t filter_prio_value; + cmdline_fixed_string_t iport; + uint8_t iport_id; + uint8_t iport_id_mask; cmdline_fixed_string_t ether; uint16_t ether_type; + uint16_t ether_type_mask; + cmdline_fixed_string_t ivlan; + uint16_t ivlan_value; + uint16_t ivlan_mask; + cmdline_fixed_string_t ovlan; + uint16_t ovlan_value; + uint16_t ovlan_mask; + cmdline_fixed_string_t tos; + uint8_t tos_value; + uint8_t tos_mask; + cmdline_fixed_string_t proto; + uint8_t proto_value; + uint8_t proto_mask; + cmdline_fixed_string_t ttl; + uint8_t ttl_value; + uint8_t ttl_mask; + cmdline_fixed_string_t flow_label; + uint32_t flow_label_value; + uint32_t flow_label_mask; cmdline_fixed_string_t src; cmdline_ipaddr_t ip_src; + cmdline_ipaddr_t ip_src_mask; uint16_t port_src; + uint16_t port_src_mask; cmdline_fixed_string_t dst; cmdline_ipaddr_t ip_dst; + cmdline_ipaddr_t ip_dst_mask; uint16_t port_dst; + uint16_t port_dst_mask; cmdline_fixed_string_t verify_tag; uint32_t verify_tag_value; cmdline_fixed_string_t vlan; @@ -7999,6 +8054,26 @@ struct cmd_flow_director_result { cmdline_fixed_string_t tunnel_type; cmdline_fixed_string_t tunnel_id; uint32_t tunnel_id_value; + + /* Extra arguments for behavior taken */ + cmdline_fixed_string_t port_arg; + cmdline_fixed_string_t port_arg_op; + uint8_t port_arg_port_id; + cmdline_fixed_string_t mac_arg; + cmdline_fixed_string_t mac_arg_op; + struct ether_addr mac_arg_src_mac; + struct ether_addr mac_arg_dst_mac; + cmdline_fixed_string_t vlan_arg; + cmdline_fixed_string_t vlan_arg_op; + uint16_t vlan_arg_vlan; + cmdline_fixed_string_t nat_arg; + cmdline_fixed_string_t nat_arg_op; + cmdline_fixed_string_t nat_arg_src; + cmdline_ipaddr_t nat_arg_ip_src; + uint16_t nat_arg_port_src; + cmdline_fixed_string_t nat_arg_dst; + cmdline_ipaddr_t nat_arg_ip_dst; + uint16_t nat_arg_port_dst; }; static inline int @@ -8061,6 +8136,10 @@ str2flowtype(char *string) {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP}, {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER}, {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD}, + {"ipv4-tcp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP}, + {"ipv4-udp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP}, + {"ipv6-tcp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP}, + {"ipv6-udp-pkt-filter", RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP}, }; for (i = 0; i < RTE_DIM(flowtype_str); i++) { @@ -8090,6 +8169,31 @@ str2fdir_tunneltype(char *string) return RTE_FDIR_TUNNEL_TYPE_UNKNOWN; } +static uint16_t +str2fdir_behavior_sub_op(char *string) +{ + uint16_t i = 0; + + static const struct { + char str[32]; + enum rte_eth_fdir_behavior_sub_op op; + } behavior_sub_op_str[] = { + {"port-redirect", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"mac-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"mac-swap", RTE_FDIR_BEHAVIOR_SUB_OP_SWAP}, + {"vlan-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + {"vlan-del", RTE_FDIR_BEHAVIOR_SUB_OP_DELETE}, + {"nat-rewrite", RTE_FDIR_BEHAVIOR_SUB_OP_INSERT}, + }; + + for (i = 0; i < RTE_DIM(behavior_sub_op_str); i++) { + if (!strcmp(behavior_sub_op_str[i].str, string)) + return behavior_sub_op_str[i].op; + } + + return RTE_FDIR_BEHAVIOR_SUB_OP_UNKNOWN; +} + #define IPV4_ADDR_TO_UINT(ip_addr, ip) \ do { \ if ((ip_addr).family == AF_INET) \ @@ -8119,6 +8223,7 @@ cmd_flow_director_filter_parsed(void *parsed_result, { struct cmd_flow_director_result *res = parsed_result; struct rte_eth_fdir_filter entry; + struct rte_eth_pkt_filter_flow *pflow; uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN]; char *end; unsigned long vf_id; @@ -8218,6 +8323,126 @@ cmd_flow_director_filter_parsed(void *parsed_result, entry.input.flow.l2_flow.ether_type = rte_cpu_to_be_16(res->ether_type); break; + case RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV4_UDP: + pflow = &entry.input.flow.pkt_filter_flow; + + if (!strcmp(res->filter_type_value, "maskless")) + pflow->type = RTE_ETH_PKT_FILTER_TYPE_MASKLESS; + else + pflow->type = RTE_ETH_PKT_FILTER_TYPE_MASKFULL; + + if (!strcmp(res->filter_prio_value, "default")) + pflow->prio = pflow->type; + else if (!strcmp(res->filter_prio_value, "maskless")) + pflow->prio = RTE_ETH_PKT_FILTER_TYPE_MASKLESS; + else + pflow->prio = RTE_ETH_PKT_FILTER_TYPE_MASKFULL; + + pflow->pkt.port_id = res->iport_id; + pflow->mask.port_id = res->iport_id_mask; + + pflow->pkt.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type); + pflow->mask.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type_mask); + + pflow->pkt.vlan_flow.inner_vlan = + rte_cpu_to_be_16(res->ivlan_value); + pflow->pkt.vlan_flow.outer_vlan = res->ovlan_value; + rte_cpu_to_be_16(res->ovlan_value); + pflow->mask.vlan_flow.inner_vlan = res->ivlan_mask; + rte_cpu_to_be_16(res->ivlan_mask); + pflow->mask.vlan_flow.outer_vlan = res->ovlan_mask; + rte_cpu_to_be_16(res->ovlan_mask); + + pflow->pkt.ntuple_flow.tcp4.ip.tos = res->tos_value; + pflow->pkt.ntuple_flow.tcp4.ip.proto = res->proto_value; + pflow->pkt.ntuple_flow.tcp4.ip.ttl = res->ttl_value; + pflow->mask.ntuple_flow.tcp4.ip.tos = res->tos_mask; + pflow->mask.ntuple_flow.tcp4.ip.proto = res->proto_mask; + pflow->mask.ntuple_flow.tcp4.ip.ttl = res->ttl_mask; + + IPV4_ADDR_TO_UINT(res->ip_src, + pflow->pkt.ntuple_flow.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->ip_dst, + pflow->pkt.ntuple_flow.tcp4.ip.dst_ip); + IPV4_ADDR_TO_UINT(res->ip_src_mask, + pflow->mask.ntuple_flow.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->ip_dst_mask, + pflow->mask.ntuple_flow.tcp4.ip.dst_ip); + + pflow->pkt.ntuple_flow.tcp4.src_port = + rte_cpu_to_be_16(res->port_src); + pflow->pkt.ntuple_flow.tcp4.dst_port = + rte_cpu_to_be_16(res->port_dst); + pflow->mask.ntuple_flow.tcp4.src_port = + rte_cpu_to_be_16(res->port_src_mask); + pflow->mask.ntuple_flow.tcp4.dst_port = + rte_cpu_to_be_16(res->port_dst_mask); + break; + case RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV6_UDP: + pflow = &entry.input.flow.pkt_filter_flow; + + if (!strcmp(res->filter_type_value, "maskless")) + pflow->type = RTE_ETH_PKT_FILTER_TYPE_MASKLESS; + else + pflow->type = RTE_ETH_PKT_FILTER_TYPE_MASKFULL; + + if (!strcmp(res->filter_prio_value, "default")) + pflow->prio = pflow->type; + else if (!strcmp(res->filter_prio_value, "maskless")) + pflow->prio = RTE_ETH_PKT_FILTER_TYPE_MASKLESS; + else + pflow->prio = RTE_ETH_PKT_FILTER_TYPE_MASKFULL; + + pflow->pkt.port_id = res->iport_id; + pflow->mask.port_id = res->iport_id_mask; + + pflow->pkt.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type); + pflow->mask.l2_flow.ether_type = + rte_cpu_to_be_16(res->ether_type_mask); + + pflow->pkt.vlan_flow.inner_vlan = + rte_cpu_to_be_16(res->ivlan_value); + pflow->pkt.vlan_flow.outer_vlan = res->ovlan_value; + rte_cpu_to_be_16(res->ovlan_value); + pflow->mask.vlan_flow.inner_vlan = res->ivlan_mask; + rte_cpu_to_be_16(res->ivlan_mask); + pflow->mask.vlan_flow.outer_vlan = res->ovlan_mask; + rte_cpu_to_be_16(res->ovlan_mask); + + pflow->pkt.ntuple_flow.tcp6.ip.tc = res->tos_value; + pflow->pkt.ntuple_flow.tcp6.ip.flow_label = + rte_cpu_to_be_32(res->flow_label_value); + pflow->pkt.ntuple_flow.tcp6.ip.next_header = res->proto_value; + pflow->pkt.ntuple_flow.tcp6.ip.hop_limit = res->ttl_value; + pflow->mask.ntuple_flow.tcp6.ip.tc = res->tos_mask; + pflow->mask.ntuple_flow.tcp6.ip.flow_label = + rte_cpu_to_be_32(res->flow_label_mask); + pflow->mask.ntuple_flow.tcp6.ip.next_header = res->proto_mask; + pflow->mask.ntuple_flow.tcp6.ip.hop_limit = res->ttl_mask; + + IPV6_ADDR_TO_ARRAY(res->ip_src, + pflow->pkt.ntuple_flow.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->ip_dst, + pflow->pkt.ntuple_flow.tcp6.ip.dst_ip); + IPV6_ADDR_TO_ARRAY(res->ip_src_mask, + pflow->mask.ntuple_flow.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->ip_dst_mask, + pflow->mask.ntuple_flow.tcp6.ip.dst_ip); + + pflow->pkt.ntuple_flow.tcp6.src_port = + rte_cpu_to_be_16(res->port_src); + pflow->pkt.ntuple_flow.tcp6.dst_port = + rte_cpu_to_be_16(res->port_dst); + pflow->mask.ntuple_flow.tcp6.src_port = + rte_cpu_to_be_16(res->port_src_mask); + pflow->mask.ntuple_flow.tcp6.dst_port = + rte_cpu_to_be_16(res->port_dst_mask); + break; default: break; } @@ -8244,10 +8469,68 @@ cmd_flow_director_filter_parsed(void *parsed_result, entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value); entry.action.flex_off = 0; /*use 0 by default */ - if (!strcmp(res->drop, "drop")) + if (!strcmp(res->drop, "switch")) { + struct rte_eth_behavior_arg_nat *nat_arg; + + entry.action.behavior = RTE_ETH_FDIR_SWITCH; + + /* Extra port arguments */ + entry.action.behavior_arg.port_arg.op = + str2fdir_behavior_sub_op(res->port_arg_op); + entry.action.behavior_arg.port_arg.port_id = + res->port_arg_port_id; + + /* Extra mac arguments */ + entry.action.behavior_arg.mac_arg.op = + str2fdir_behavior_sub_op(res->mac_arg_op); + (void)rte_memcpy(&entry.action.behavior_arg.mac_arg.src_mac, + &res->mac_arg_src_mac, + sizeof(struct ether_addr)); + (void)rte_memcpy(&entry.action.behavior_arg.mac_arg.dst_mac, + &res->mac_arg_dst_mac, + sizeof(struct ether_addr)); + + /* Extra vlan arguments */ + entry.action.behavior_arg.vlan_arg.op = + str2fdir_behavior_sub_op(res->vlan_arg_op); + entry.action.behavior_arg.vlan_arg.vlan_tci = + rte_cpu_to_be_16(res->vlan_arg_vlan); + + /* Extra nat arguments */ + nat_arg = &entry.action.behavior_arg.nat_arg; + + nat_arg->op = str2fdir_behavior_sub_op(res->nat_arg_op); + switch (entry.input.flow_type) { + case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV4_TCP: + IPV4_ADDR_TO_UINT(res->nat_arg_ip_src, + nat_arg->nat.tcp4.ip.src_ip); + IPV4_ADDR_TO_UINT(res->nat_arg_ip_dst, + nat_arg->nat.tcp4.ip.dst_ip); + nat_arg->nat.tcp4.src_port = + rte_cpu_to_be_16(res->nat_arg_port_src); + nat_arg->nat.tcp4.dst_port = + rte_cpu_to_be_16(res->nat_arg_port_dst); + break; + case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: + case RTE_ETH_FLOW_PKT_FILTER_IPV6_TCP: + IPV6_ADDR_TO_ARRAY(res->nat_arg_ip_src, + nat_arg->nat.tcp6.ip.src_ip); + IPV6_ADDR_TO_ARRAY(res->nat_arg_ip_dst, + nat_arg->nat.tcp6.ip.dst_ip); + nat_arg->nat.tcp6.src_port = + rte_cpu_to_be_16(res->nat_arg_port_src); + nat_arg->nat.tcp6.dst_port = + rte_cpu_to_be_16(res->nat_arg_port_dst); + break; + default: + break; + } + } else if (!strcmp(res->drop, "drop")) { entry.action.behavior = RTE_ETH_FDIR_REJECT; - else + } else { entry.action.behavior = RTE_ETH_FDIR_ACCEPT; + } if (!strcmp(res->pf_vf, "pf")) entry.input.flow_ext.is_vf = 0; @@ -8302,31 +8585,124 @@ cmdline_parse_token_string_t cmd_flow_director_flow = cmdline_parse_token_string_t cmd_flow_director_flow_type = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#" - "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload"); + "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#" + "ipv4-tcp-pkt-filter#ipv4-udp-pkt-filter#ipv6-tcp-pkt-filter#" + "ipv6-udp-pkt-filter"); +cmdline_parse_token_string_t cmd_flow_director_filter_type = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + filter_type, "filter-type"); +cmdline_parse_token_string_t cmd_flow_director_filter_type_value = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + filter_type_value, "maskfull#maskless"); +cmdline_parse_token_string_t cmd_flow_director_filter_prio = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + filter_prio, "filter-prio"); +cmdline_parse_token_string_t cmd_flow_director_filter_prio_value = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + filter_prio_value, "default#maskfull#" + "maskless"); +cmdline_parse_token_string_t cmd_flow_director_iport = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + iport, "ingress-port"); +cmdline_parse_token_num_t cmd_flow_director_iport_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + iport_id, UINT8); +cmdline_parse_token_num_t cmd_flow_director_iport_id_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + iport_id_mask, UINT8); cmdline_parse_token_string_t cmd_flow_director_ether = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, ether, "ether"); cmdline_parse_token_num_t cmd_flow_director_ether_type = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, ether_type, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ether_type_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ether_type_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_ivlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + ivlan, "inner-vlan"); +cmdline_parse_token_num_t cmd_flow_director_ivlan_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ivlan_value, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ivlan_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ivlan_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_ovlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + ovlan, "outer-vlan"); +cmdline_parse_token_num_t cmd_flow_director_ovlan_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ovlan_value, UINT16); +cmdline_parse_token_num_t cmd_flow_director_ovlan_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ovlan_mask, UINT16); +cmdline_parse_token_string_t cmd_flow_director_tos = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + tos, "tos"); +cmdline_parse_token_num_t cmd_flow_director_tos_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + tos_value, UINT8); +cmdline_parse_token_num_t cmd_flow_director_tos_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + tos_mask, UINT8); +cmdline_parse_token_string_t cmd_flow_director_flow_label = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + flow_label, "flow-label"); +cmdline_parse_token_num_t cmd_flow_director_flow_label_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + flow_label_value, UINT32); +cmdline_parse_token_num_t cmd_flow_director_flow_label_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + flow_label_mask, UINT32); +cmdline_parse_token_string_t cmd_flow_director_proto = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + proto, "proto"); +cmdline_parse_token_num_t cmd_flow_director_proto_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + proto_value, UINT8); +cmdline_parse_token_num_t cmd_flow_director_proto_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + proto_mask, UINT8); +cmdline_parse_token_string_t cmd_flow_director_ttl = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + ttl, "ttl"); +cmdline_parse_token_num_t cmd_flow_director_ttl_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ttl_value, UINT8); +cmdline_parse_token_num_t cmd_flow_director_ttl_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + ttl_mask, UINT8); cmdline_parse_token_string_t cmd_flow_director_src = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, src, "src"); cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src = TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, ip_src); +cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src_mask = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + ip_src_mask); cmdline_parse_token_num_t cmd_flow_director_port_src = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, port_src, UINT16); +cmdline_parse_token_num_t cmd_flow_director_port_src_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_src_mask, UINT16); cmdline_parse_token_string_t cmd_flow_director_dst = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, dst, "dst"); cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst = TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, ip_dst); +cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst_mask = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + ip_dst_mask); cmdline_parse_token_num_t cmd_flow_director_port_dst = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, port_dst, UINT16); +cmdline_parse_token_num_t cmd_flow_director_port_dst_mask = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_dst_mask, UINT16); cmdline_parse_token_string_t cmd_flow_director_verify_tag = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, verify_tag, "verify_tag"); @@ -8347,7 +8723,7 @@ cmdline_parse_token_string_t cmd_flow_director_flexbytes_value = flexbytes_value, NULL); cmdline_parse_token_string_t cmd_flow_director_drop = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, - drop, "drop#fwd"); + drop, "drop#fwd#switch"); cmdline_parse_token_string_t cmd_flow_director_pf_vf = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, pf_vf, NULL); @@ -8395,6 +8771,61 @@ cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, tunnel_id_value, UINT32); +cmdline_parse_token_string_t cmd_flow_director_port_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + port_arg, "port-arg"); +cmdline_parse_token_string_t cmd_flow_director_port_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + port_arg_op, "none#port-redirect"); +cmdline_parse_token_num_t cmd_flow_director_port_arg_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + port_arg_port_id, UINT8); +cmdline_parse_token_string_t cmd_flow_director_mac_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mac_arg, "mac-arg"); +cmdline_parse_token_string_t cmd_flow_director_mac_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mac_arg_op, "none#mac-rewrite#mac-swap"); +cmdline_parse_token_etheraddr_t cmd_flow_director_mac_arg_src_mac = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result, + mac_arg_src_mac); +cmdline_parse_token_etheraddr_t cmd_flow_director_mac_arg_dst_mac = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result, + mac_arg_dst_mac); +cmdline_parse_token_string_t cmd_flow_director_vlan_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + vlan_arg, "vlan-arg"); +cmdline_parse_token_string_t cmd_flow_director_vlan_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + vlan_arg_op, "none#vlan-rewrite#vlan-del"); +cmdline_parse_token_num_t cmd_flow_director_vlan_arg_vlan = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + vlan_arg_vlan, UINT16); +cmdline_parse_token_string_t cmd_flow_director_nat_arg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg, "nat-arg"); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_op = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_op, "none#nat-rewrite"); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_src = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_src, "src"); +cmdline_parse_token_ipaddr_t cmd_flow_director_nat_arg_ip_src = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + nat_arg_ip_src); +cmdline_parse_token_num_t cmd_flow_director_nat_arg_port_src = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + nat_arg_port_src, UINT16); +cmdline_parse_token_string_t cmd_flow_director_nat_arg_dst = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + nat_arg_dst, "dst"); +cmdline_parse_token_ipaddr_t cmd_flow_director_nat_arg_ip_dst = + TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result, + nat_arg_ip_dst); +cmdline_parse_token_num_t cmd_flow_director_nat_arg_port_dst = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + nat_arg_port_dst, UINT16); + cmdline_parse_inst_t cmd_add_del_ip_flow_director = { .f = cmd_flow_director_filter_parsed, .data = NULL, @@ -8517,6 +8948,86 @@ cmdline_parse_inst_t cmd_add_del_l2_flow_director = { }, }; +cmdline_parse_inst_t cmd_add_del_pkt_filter_flow_director = { + .f = cmd_flow_director_filter_parsed, + .data = NULL, + .help_str = "add or delete a packet filter flow director entry on NIC", + .tokens = { + (void *)&cmd_flow_director_filter, + (void *)&cmd_flow_director_port_id, + (void *)&cmd_flow_director_mode, + (void *)&cmd_flow_director_mode_ip, + (void *)&cmd_flow_director_ops, + (void *)&cmd_flow_director_flow, + (void *)&cmd_flow_director_flow_type, + (void *)&cmd_flow_director_filter_type, + (void *)&cmd_flow_director_filter_type_value, + (void *)&cmd_flow_director_filter_prio, + (void *)&cmd_flow_director_filter_prio_value, + (void *)&cmd_flow_director_iport, + (void *)&cmd_flow_director_iport_id, + (void *)&cmd_flow_director_iport_id_mask, + (void *)&cmd_flow_director_ether, + (void *)&cmd_flow_director_ether_type, + (void *)&cmd_flow_director_ether_type_mask, + (void *)&cmd_flow_director_ivlan, + (void *)&cmd_flow_director_ivlan_value, + (void *)&cmd_flow_director_ivlan_mask, + (void *)&cmd_flow_director_ovlan, + (void *)&cmd_flow_director_ovlan_value, + (void *)&cmd_flow_director_ovlan_mask, + (void *)&cmd_flow_director_tos, + (void *)&cmd_flow_director_tos_value, + (void *)&cmd_flow_director_tos_mask, + (void *)&cmd_flow_director_flow_label, + (void *)&cmd_flow_director_flow_label_value, + (void *)&cmd_flow_director_flow_label_mask, + (void *)&cmd_flow_director_proto, + (void *)&cmd_flow_director_proto_value, + (void *)&cmd_flow_director_proto_mask, + (void *)&cmd_flow_director_ttl, + (void *)&cmd_flow_director_ttl_value, + (void *)&cmd_flow_director_ttl_mask, + (void *)&cmd_flow_director_src, + (void *)&cmd_flow_director_ip_src, + (void *)&cmd_flow_director_ip_src_mask, + (void *)&cmd_flow_director_port_src, + (void *)&cmd_flow_director_port_src_mask, + (void *)&cmd_flow_director_dst, + (void *)&cmd_flow_director_ip_dst, + (void *)&cmd_flow_director_ip_dst_mask, + (void *)&cmd_flow_director_port_dst, + (void *)&cmd_flow_director_port_dst_mask, + (void *)&cmd_flow_director_flexbytes, + (void *)&cmd_flow_director_flexbytes_value, + (void *)&cmd_flow_director_drop, + (void *)&cmd_flow_director_pf_vf, + (void *)&cmd_flow_director_queue, + (void *)&cmd_flow_director_queue_id, + (void *)&cmd_flow_director_port_arg, + (void *)&cmd_flow_director_port_arg_op, + (void *)&cmd_flow_director_port_arg_port_id, + (void *)&cmd_flow_director_mac_arg, + (void *)&cmd_flow_director_mac_arg_op, + (void *)&cmd_flow_director_mac_arg_src_mac, + (void *)&cmd_flow_director_mac_arg_dst_mac, + (void *)&cmd_flow_director_vlan_arg, + (void *)&cmd_flow_director_vlan_arg_op, + (void *)&cmd_flow_director_vlan_arg_vlan, + (void *)&cmd_flow_director_nat_arg, + (void *)&cmd_flow_director_nat_arg_op, + (void *)&cmd_flow_director_nat_arg_src, + (void *)&cmd_flow_director_nat_arg_ip_src, + (void *)&cmd_flow_director_nat_arg_port_src, + (void *)&cmd_flow_director_nat_arg_dst, + (void *)&cmd_flow_director_nat_arg_ip_dst, + (void *)&cmd_flow_director_nat_arg_port_dst, + (void *)&cmd_flow_director_fd_id, + (void *)&cmd_flow_director_fd_id_value, + NULL, + }, +}; + cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = { .f = cmd_flow_director_filter_parsed, .data = NULL, @@ -9756,6 +10267,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director, + (cmdline_parse_inst_t *)&cmd_add_del_pkt_filter_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director, (cmdline_parse_inst_t *)&cmd_flush_flow_director, -- 2.5.3 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 2/2] testpmd: add an example to show packet filter flow Rahul Lakkireddy @ 2016-01-11 13:50 ` Rahul Lakkireddy 2 siblings, 0 replies; 21+ messages in thread From: Rahul Lakkireddy @ 2016-01-11 13:50 UTC (permalink / raw) To: dev; +Cc: Kumar Sanghvi, Felix Marti, Nirranjan Kirubaharan Hi All, On Wednesday, December 12/23/15, 2015 at 18:11:19 +0530, Rahul Lakkireddy wrote: > This RFC series of patches attempt to extend the flow director filter to > add support for Chelsio T5 hardware filtering capabilities. > > Chelsio T5 supports carrying out filtering in hardware which supports 3 > actions to carry out on a packet which hit a filter viz. > > 1. Action Pass - Packets hitting a filter rule can be directed to a > particular RXQ. > > 2. Action Drop - Packets hitting a filter rule are dropped in h/w. > > 3. Action Switch - Packets hitting a filter rule can be switched in h/w > from one port to another, without involvement of host. Also, the > action Switch also supports rewrite of src-mac/dst-mac headers as > well as rewrite of vlan headers. It also supports rewrite of IP > headers and thereby, supports NAT (Network Address Translation) > in h/w. > > Also, each filter rule can optionally support specifying a mask value > i.e. it's possible to create a filter rule for an entire subnet of IP > addresses or a range of tcp/udp ports, etc. > > Patch 1 does the following: > - Adds an additional flow rte_eth_pkt_filter_flow which encapsulates > ingress ports, l2 payload, vlan and ntuples. > - Adds an additional mask for the flow to allow range of values to be > matched. > - Adds an ability to set both filters with masks (Maskfull) and > without masks (Maskless). Also allow prioritizing one of these > filter types over the other when a packet matches several types. > - Adds a new behavior 'switch'. > - Adds behavior arguments that can be passed when a particular behavior > is taken. For ex: in case of action 'switch', pass additional 4-tuple > to allow rewriting src/dst ip and port addresses to support NAT'ing. > > Patch 2 shows testpmd command line example to support packet filter > flow. > > The patch series has been compile tested on all x86 gcc targets and the > current fdir filter supported drivers seem to return appropriate error > codes when this new flow type and the new action are not supported and > hence are not affected. > > Posting this series mainly for discussion on API change. Once this is > agreeable then, I will post the cxgbe PMD changes to use the new API. > > --- > v2: > 1. Added ttl to rte_eth_ipv4_flow and tc, flow_label, next_header, > and hop_limit to rte_eth_ipv6_flow. > > 2. Added new field type to rte_eth_pkt_filter_flow to differentiate > between maskfull and maskless filter types. > > 3. Added new field prio to rte_eth_pkt_filter_flow to allow setting > priority over maskfull or maskless when packet matches multiple > filter types. > > 4. Added new behavior sub op RTE_FDIR_BEHAVIOR_SUB_OP_SWAP to allow > swapping fields in matched flows. For ex, useful when swapping mac > addresses in hardware before switching. > > 5. Updated the testpmd example to reflect the above new changes. > > 6. Dropped Patch 3 since the ABI announcement has already been merged. > > Rahul Lakkireddy (2): > ethdev: add packet filter flow and new behavior switch to fdir > testpmd: add an example to show packet filter flow > > app/test-pmd/cmdline.c | 528 +++++++++++++++++++++++++++++++++++++++- > lib/librte_ether/rte_eth_ctrl.h | 127 +++++++++- > 2 files changed, 646 insertions(+), 9 deletions(-) > > -- > 2.5.3 > Any comments on this RFC series? If the overall approach is fine then, I'll re-submit it as a PATCH series along with the CXGBE PMD driver changes. Thanks, Rahul ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2016-01-15 7:12 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-12-10 14:01 [dpdk-dev] [RFC 0/3] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 1/3] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy 2015-12-10 15:46 ` Chilikin, Andrey 2015-12-11 7:08 ` Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 2/3] testpmd: add an example to show packet filter flow Rahul Lakkireddy 2015-12-10 14:01 ` [dpdk-dev] [RFC 3/3] doc: announce ABI change for filtering support Rahul Lakkireddy 2015-12-15 8:40 ` Rahul Lakkireddy 2015-12-15 8:55 ` Thomas Monjalon 2015-12-15 13:51 ` Rahul Lakkireddy 2015-12-15 13:57 ` Thomas Monjalon 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 1/2] ethdev: add packet filter flow and new behavior switch to fdir Rahul Lakkireddy 2016-01-13 1:12 ` Wu, Jingjing 2016-01-13 8:49 ` Rahul Lakkireddy 2016-01-13 13:16 ` Wu, Jingjing 2016-01-14 8:48 ` Wu, Jingjing 2016-01-14 13:17 ` Rahul Lakkireddy 2016-01-15 1:30 ` Wu, Jingjing 2016-01-15 7:11 ` Rahul Lakkireddy 2015-12-23 12:41 ` [dpdk-dev] [RFC v2 2/2] testpmd: add an example to show packet filter flow Rahul Lakkireddy 2016-01-11 13:50 ` [dpdk-dev] [RFC v2 0/2] ethdev: Enhancements to flow director filter Rahul Lakkireddy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).