[dpdk-dev] [PATCH v2 2/2] examples/ipsec-secgw: add target queues in flow actions

Anoob anoob.joseph at caviumnetworks.com
Thu Dec 7 10:47:40 CET 2017


Hi Nelio,


On 12/04/2017 07:41 PM, Nelio Laranjeiro wrote:
> Mellanox INNOVA NIC needs to have final target queue actions to perform
> inline crypto.
>
> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro at 6wind.com>
>
> ---
>
> Changes in v2:
>
>   * Test the rule by PASSTHRU/RSS/QUEUE and apply the first one validated.
> ---
>   examples/ipsec-secgw/ipsec.c | 81 ++++++++++++++++++++++++++++++++++++++++----
>   examples/ipsec-secgw/ipsec.h |  2 +-
>   2 files changed, 76 insertions(+), 7 deletions(-)
>
> diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
> index 17bd7620d..f8823fb94 100644
> --- a/examples/ipsec-secgw/ipsec.c
> +++ b/examples/ipsec-secgw/ipsec.c
> @@ -142,6 +142,7 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
>   							rte_eth_dev_get_sec_ctx(
>   							sa->portid);
>   			const struct rte_security_capability *sec_cap;
> +			int ret = 0;
>   
>   			sa->sec_session = rte_security_session_create(ctx,
>   					&sess_conf, ipsec_ctx->session_pool);
> @@ -173,6 +174,10 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
>   				return -1;
>   			}
>   
> +			sa->attr.egress = (sa->direction ==
> +					RTE_SECURITY_IPSEC_SA_DIR_EGRESS);
> +			sa->attr.ingress = (sa->direction ==
> +					RTE_SECURITY_IPSEC_SA_DIR_INGRESS);
>   			sa->ol_flags = sec_cap->ol_flags;
>   			sa->security_ctx = ctx;
>   			sa->pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
> @@ -201,15 +206,79 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
>   			sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
>   			sa->action[0].conf = sa->sec_session;
>   
> -			sa->action[1].type = RTE_FLOW_ACTION_TYPE_END;
> -
> -			sa->attr.egress = (sa->direction ==
> -					RTE_SECURITY_IPSEC_SA_DIR_EGRESS);
> -			sa->attr.ingress = (sa->direction ==
> -					RTE_SECURITY_IPSEC_SA_DIR_INGRESS);
> +			if (sa->attr.ingress) {
> +				uint8_t rss_key[40];
> +				struct rte_eth_rss_conf rss_conf = {
> +					.rss_key = rss_key,
> +					.rss_key_len = 40,
> +				};
> +				struct rte_eth_dev *eth_dev;
> +				union {
> +					struct rte_flow_action_rss rss;
> +					struct {
> +					const struct rte_eth_rss_conf *rss_conf;
> +					uint16_t num;
> +					uint16_t queue[RTE_MAX_QUEUES_PER_PORT];
> +					} local;
> +				} action_rss;
> +				unsigned int i;
> +				unsigned int j;
> +
> +				sa->action[2].type = RTE_FLOW_ACTION_TYPE_END;
> +				/*
> +				 * Try implicitly PASSTHRU, it can also be
> +				 * explicit.
> +				 */
May be we can get rid of this check. You can do the check with RSS and 
then QUEUE. That should be fine. SECURITY is terminating on Cavium 
hardware, but according to the spec it is a non-terminating meta action. 
We can stick to that. For Cavium hardware the PMD will give success to 
SECURITY+QUEUE. That should resolve the issue.
> +				sa->action[1].type = RTE_FLOW_ACTION_TYPE_END;
> +				ret = rte_flow_validate(sa->portid, &sa->attr,
> +							sa->pattern, sa->action,
> +							&err);
> +				if (!ret)
> +					goto flow_create;
> +				/* Try RSS. */
> +				sa->action[1].type = RTE_FLOW_ACTION_TYPE_RSS;
> +				sa->action[1].conf = &action_rss;
> +				eth_dev = ctx->device;
> +				rte_eth_dev_rss_hash_conf_get(sa->portid,
> +							      &rss_conf);
> +				for (i = 0, j = 0;
> +				     i < eth_dev->data->nb_rx_queues; ++i)
> +					if (eth_dev->data->rx_queues[i])
> +						action_rss.local.queue[j++] = i;
> +				action_rss.local.num = j;
> +				action_rss.local.rss_conf = &rss_conf;
> +				ret = rte_flow_validate(sa->portid, &sa->attr,
> +							sa->pattern, sa->action,
> +							&err);
> +				if (!ret)
> +					goto flow_create;
> +				/* Try Queue. */
> +				for (i = 0;
> +				     i < eth_dev->data->nb_rx_queues; ++i)
> +					if (eth_dev->data->rx_queues[i])
> +						break;
> +				if (i != eth_dev->data->nb_rx_queues)
> +					return -1;
> +				sa->action[1].type = RTE_FLOW_ACTION_TYPE_QUEUE;
> +				sa->action[1].conf =
> +					&(struct rte_flow_action_queue){
> +					.index = i,
> +				};
> +				ret = rte_flow_validate(sa->portid, &sa->attr,
> +							sa->pattern, sa->action,
> +							&err);
> +				if (ret)
> +					goto flow_create_failure;
> +			} else {
> +				sa->action[1].type =
> +					RTE_FLOW_ACTION_TYPE_PASSTHRU;
> +				sa->action[2].type = RTE_FLOW_ACTION_TYPE_END;
> +			}
> +flow_create:
>   			sa->flow = rte_flow_create(sa->portid,
>   				&sa->attr, sa->pattern, sa->action, &err);
>   			if (sa->flow == NULL) {
> +flow_create_failure:
>   				RTE_LOG(ERR, IPSEC,
>   					"Failed to create ipsec flow msg: %s\n",
>   					err.message);
> diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
> index 775b316ff..82ffc1c6d 100644
> --- a/examples/ipsec-secgw/ipsec.h
> +++ b/examples/ipsec-secgw/ipsec.h
> @@ -133,7 +133,7 @@ struct ipsec_sa {
>   	uint32_t ol_flags;
>   
>   #define MAX_RTE_FLOW_PATTERN (4)
> -#define MAX_RTE_FLOW_ACTIONS (2)
> +#define MAX_RTE_FLOW_ACTIONS (4)
>   	struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
>   	struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
>   	struct rte_flow_attr attr;



More information about the dev mailing list