* Re: [PATCH v2 12/17] net/i40e: destroy ethertype filter
From: Xing, Beilei @ 2016-12-28 6:57 UTC (permalink / raw)
To: Bie, Tiwei; +Cc: Wu, Jingjing, Zhang, Helin, dev@dpdk.org
In-Reply-To: <20161228045616.GA28245@dpdk19>
> -----Original Message-----
> From: Bie, Tiwei
> Sent: Wednesday, December 28, 2016 12:56 PM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 12/17] net/i40e: destroy ethertype filter
>
> On Tue, Dec 27, 2016 at 02:26:19PM +0800, Beilei Xing wrote:
> > This patch adds i40e_dev_destroy_ethertype_filter function to destroy
> > a ethertype filter for users.
> >
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
> > drivers/net/i40e/i40e_ethdev.c | 10 ++-------
> > drivers/net/i40e/i40e_ethdev.h | 5 +++++
> > drivers/net/i40e/i40e_flow.c | 51
> ++++++++++++++++++++++++++++++++++++++++--
> > 3 files changed, 56 insertions(+), 10 deletions(-)
> >
> [...]
> > diff --git a/drivers/net/i40e/i40e_flow.c
> > b/drivers/net/i40e/i40e_flow.c index 2a61c4f..732c411 100644
> > --- a/drivers/net/i40e/i40e_flow.c
> > +++ b/drivers/net/i40e/i40e_flow.c
> [...]
> > @@ -1492,11 +1495,16 @@ i40e_flow_destroy(__rte_unused struct
> > rte_eth_dev *dev,
>
> The `__rte_unused' qualifier should be removed.
Yes :)
>
> > struct rte_flow *flow,
> > struct rte_flow_error *error)
> > {
> > + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> > struct i40e_flow *pmd_flow = (struct i40e_flow *)flow;
> > enum rte_filter_type filter_type = pmd_flow->filter_type;
> > int ret;
> >
> > switch (filter_type) {
> > + case RTE_ETH_FILTER_ETHERTYPE:
> > + ret = i40e_dev_destroy_ethertype_filter(pf,
> > + (struct i40e_ethertype_filter *)pmd_flow-
> >rule);
> > + break;
> > default:
> > PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> > filter_type);
> > @@ -1504,10 +1512,49 @@ i40e_flow_destroy(__rte_unused struct
> rte_eth_dev *dev,
> > break;
> > }
> >
> > - if (ret)
> > + if (!ret) {
> > + TAILQ_REMOVE(&pf->flow_list, pmd_flow, node);
> > + free(pmd_flow);
> > + } else {
> > rte_flow_error_set(error, EINVAL,
> > RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> > "Failed to destroy flow.");
> > + }
>
> Probably you should introduce the pf related code when introducing
> i40e_flow_destroy() in the below patch:
>
> [PATCH v2 11/17] net/i40e: add flow destroy function
Good point, thanks.
>
> > +
> > + return ret;
> > +}
> > +
> > +static int
> > +i40e_dev_destroy_ethertype_filter(struct i40e_pf *pf,
> > + struct i40e_ethertype_filter *filter) {
> > + struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> > + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> > + struct i40e_ethertype_filter *node;
> > + struct i40e_control_filter_stats stats;
> > + uint16_t flags = 0;
> > + int ret = 0;
> > +
> > + if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
> > + flags |=
> I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
> > + if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
> > + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
> > + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
> > +
> > + memset(&stats, 0, sizeof(stats));
> > + ret = i40e_aq_add_rem_control_packet_filter(hw,
> > + filter->input.mac_addr.addr_bytes,
> > + filter->input.ether_type,
> > + flags, pf->main_vsi->seid,
> > + filter->queue, 0, &stats, NULL);
> > + if (ret < 0)
> > + return ret;
> > +
> > + node = i40e_sw_ethertype_filter_lookup(ethertype_rule, &filter-
> >input);
> > + if (node)
> > + ret = i40e_sw_ethertype_filter_del(pf, node);
> > + else
> > + return -EINVAL;
>
> It would be more readable to check whether node equals NULL and return
> when it's true, and call i40e_sw_ethertype_filter_del(pf, node) outside the
> `if' statement:
>
> node = i40e_sw_ethertype_filter_lookup(ethertype_rule, &filter-
> >input);
> if (node == NULL)
> return -EINVAL;
>
> ret = i40e_sw_ethertype_filter_del(pf, node);
Make sense, got it:)
>
> Best regards,
> Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 15/17] net/i40e: add flow flush function
From: Xing, Beilei @ 2016-12-28 6:48 UTC (permalink / raw)
To: Bie, Tiwei; +Cc: Wu, Jingjing, Zhang, Helin, dev@dpdk.org
In-Reply-To: <20161228053556.GB28245@dpdk19>
> -----Original Message-----
> From: Bie, Tiwei
> Sent: Wednesday, December 28, 2016 1:36 PM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 15/17] net/i40e: add flow flush function
>
> On Tue, Dec 27, 2016 at 02:26:22PM +0800, Beilei Xing wrote:
> > This patch adds i40e_flow_flush function to flush all filters for
> > users. And flow director flush function is involved first.
> >
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
> > drivers/net/i40e/i40e_ethdev.h | 3 +++
> > drivers/net/i40e/i40e_fdir.c | 8 ++------
> > drivers/net/i40e/i40e_flow.c | 46
> ++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 51 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/net/i40e/i40e_ethdev.h
> > b/drivers/net/i40e/i40e_ethdev.h index b8c7d41..0b736d5 100644
> > --- a/drivers/net/i40e/i40e_ethdev.h
> > +++ b/drivers/net/i40e/i40e_ethdev.h
> > @@ -786,6 +786,9 @@ i40e_sw_tunnel_filter_lookup(struct
> i40e_tunnel_rule *tunnel_rule,
> > const struct i40e_tunnel_filter_input *input); int
> > i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
> > struct i40e_tunnel_filter *tunnel_filter);
> > +int i40e_sw_fdir_filter_del(struct i40e_pf *pf,
> > + struct i40e_fdir_filter *filter); int
> i40e_fdir_flush(struct
> > +rte_eth_dev *dev);
> >
>
> Why don't declare them as the global functions at the beginning?
When I implement the store/restore function, I plan this function is only used in i40e_ethdev.c.
I change them to the global functions since I add i40e_flow.c to rework all the flow ops.
>
> > /* I40E_DEV_PRIVATE_TO */
> > #define I40E_DEV_PRIVATE_TO_PF(adapter) \ diff --git
> > a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index
> > 6c1bb18..f10aeee 100644
> > --- a/drivers/net/i40e/i40e_fdir.c
> > +++ b/drivers/net/i40e/i40e_fdir.c
> > @@ -119,8 +119,6 @@ static int i40e_fdir_filter_programming(struct
> i40e_pf *pf,
> > enum i40e_filter_pctype pctype,
> > const struct rte_eth_fdir_filter *filter,
> > bool add);
> > -static int i40e_fdir_flush(struct rte_eth_dev *dev);
> > -
> > static int i40e_fdir_filter_convert(const struct rte_eth_fdir_filter *input,
> > struct i40e_fdir_filter *filter); static struct
> i40e_fdir_filter
> > * @@ -128,8 +126,6 @@ i40e_sw_fdir_filter_lookup(struct i40e_fdir_info
> > *fdir_info,
> > const struct rte_eth_fdir_input *input); static int
> > i40e_sw_fdir_filter_insert(struct i40e_pf *pf,
> > struct i40e_fdir_filter *filter); -static int
> > i40e_sw_fdir_filter_del(struct i40e_pf *pf,
> > - struct i40e_fdir_filter *filter);
> >
> > static int
> > i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq) @@ -1070,7 +1066,7
> > @@ i40e_sw_fdir_filter_insert(struct i40e_pf *pf, struct
> > i40e_fdir_filter *filter) }
> >
> > /* Delete a flow director filter from the SW list */ -static int
> > +int
> > i40e_sw_fdir_filter_del(struct i40e_pf *pf, struct i40e_fdir_filter
> > *filter) {
> > struct i40e_fdir_info *fdir_info = &pf->fdir; @@ -1318,7 +1314,7 @@
> > i40e_fdir_filter_programming(struct i40e_pf *pf,
> > * i40e_fdir_flush - clear all filters of Flow Director table
> > * @pf: board private structure
> > */
> > -static int
> > +int
> > i40e_fdir_flush(struct rte_eth_dev *dev) {
> > struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> > diff --git a/drivers/net/i40e/i40e_flow.c
> > b/drivers/net/i40e/i40e_flow.c index 4c7856c..1d9f603 100644
> > --- a/drivers/net/i40e/i40e_flow.c
> > +++ b/drivers/net/i40e/i40e_flow.c
> > @@ -68,6 +68,8 @@ static struct rte_flow *i40e_flow_create(struct
> rte_eth_dev *dev,
> > const struct rte_flow_item pattern[],
> > const struct rte_flow_action
> actions[],
> > struct rte_flow_error *error);
> > +static int i40e_flow_flush(struct rte_eth_dev *dev,
> > + struct rte_flow_error *error);
> > static int i40e_flow_destroy(struct rte_eth_dev *dev,
> > struct rte_flow *flow,
> > struct rte_flow_error *error); @@ -95,11 +97,13
> @@ static int
> > i40e_dev_destroy_ethertype_filter(struct i40e_pf *pf,
> > struct i40e_ethertype_filter *filter); static
> int
> > i40e_dev_destroy_tunnel_filter(struct i40e_pf *pf,
> > struct i40e_tunnel_filter *filter);
> > +static int i40e_fdir_filter_flush(struct i40e_pf *pf);
> >
> > const struct rte_flow_ops i40e_flow_ops = {
> > .validate = i40e_flow_validate,
> > .create = i40e_flow_create,
> > .destroy = i40e_flow_destroy,
> > + .flush = i40e_flow_flush,
> > };
> >
> > enum rte_filter_type cons_filter_type = RTE_ETH_FILTER_NONE; @@
> > -1603,3 +1607,45 @@ i40e_dev_destroy_tunnel_filter(struct i40e_pf *pf,
> >
> > return ret;
> > }
> > +
> > +static int
> > +i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error
> > +*error) {
> > + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> > + int ret = 0;
> > +
>
> Meaningless initialization.
Yes, you're right, will change in next version. Thanks.
>
> > + ret = i40e_fdir_filter_flush(pf);
> > + if (!ret)
> > + rte_flow_error_set(error, EINVAL,
> > + RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> > + "Failed to flush FDIR flows.");
>
> Just curious. What's the relationship between `ret' and the code (EINVAL)
> passed to rte_flow_error_set()? Is `-ret' acceptable as the parameter?
> Because the `-ret' which is actually returned by i40e_fdir_flush() is also some
> standard UNIX errno. When error occurs, user should use which one to figure
> out the failure reason? `-ret' or `rte_errno'?
rte_errno. I need to rework all rte_flow_error_set() according to Adrien's comments.
>
> > +
> > + return ret;
> > +}
> > +
> > +static int
> > +i40e_fdir_filter_flush(struct i40e_pf *pf) {
> > + struct rte_eth_dev *dev = pf->adapter->eth_dev;
> > + struct i40e_fdir_info *fdir_info = &pf->fdir;
> > + struct i40e_fdir_filter *fdir_filter;
> > + struct i40e_flow *flow;
> > + int ret = 0;
> > +
>
> Meaningless initialization.
>
> > + ret = i40e_fdir_flush(dev);
> > + if (!ret) {
> > + /* Delete FDIR filters in FDIR list. */
> > + while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list)))
> > + i40e_sw_fdir_filter_del(pf, fdir_filter);
> > +
>
> The i40e_sw_fdir_filter_del() may fail, in which case fdir_filter won't be
> removed from fdir_info->fdir_list. Will it lead to an infinite loop?
> Should you check the retval of i40e_sw_fdir_filter_del() and break the loop
> when it fails?
Yes, thanks for catching this.
>
> Best regards,
> Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 15/17] net/i40e: add flow flush function
From: Tiwei Bie @ 2016-12-28 5:35 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-16-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:22PM +0800, Beilei Xing wrote:
> This patch adds i40e_flow_flush function to flush all
> filters for users. And flow director flush function
> is involved first.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.h | 3 +++
> drivers/net/i40e/i40e_fdir.c | 8 ++------
> drivers/net/i40e/i40e_flow.c | 46 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 51 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
> index b8c7d41..0b736d5 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -786,6 +786,9 @@ i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule,
> const struct i40e_tunnel_filter_input *input);
> int i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
> struct i40e_tunnel_filter *tunnel_filter);
> +int i40e_sw_fdir_filter_del(struct i40e_pf *pf,
> + struct i40e_fdir_filter *filter);
> +int i40e_fdir_flush(struct rte_eth_dev *dev);
>
Why don't declare them as the global functions at the beginning?
> /* I40E_DEV_PRIVATE_TO */
> #define I40E_DEV_PRIVATE_TO_PF(adapter) \
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
> index 6c1bb18..f10aeee 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -119,8 +119,6 @@ static int i40e_fdir_filter_programming(struct i40e_pf *pf,
> enum i40e_filter_pctype pctype,
> const struct rte_eth_fdir_filter *filter,
> bool add);
> -static int i40e_fdir_flush(struct rte_eth_dev *dev);
> -
> static int i40e_fdir_filter_convert(const struct rte_eth_fdir_filter *input,
> struct i40e_fdir_filter *filter);
> static struct i40e_fdir_filter *
> @@ -128,8 +126,6 @@ i40e_sw_fdir_filter_lookup(struct i40e_fdir_info *fdir_info,
> const struct rte_eth_fdir_input *input);
> static int i40e_sw_fdir_filter_insert(struct i40e_pf *pf,
> struct i40e_fdir_filter *filter);
> -static int i40e_sw_fdir_filter_del(struct i40e_pf *pf,
> - struct i40e_fdir_filter *filter);
>
> static int
> i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq)
> @@ -1070,7 +1066,7 @@ i40e_sw_fdir_filter_insert(struct i40e_pf *pf, struct i40e_fdir_filter *filter)
> }
>
> /* Delete a flow director filter from the SW list */
> -static int
> +int
> i40e_sw_fdir_filter_del(struct i40e_pf *pf, struct i40e_fdir_filter *filter)
> {
> struct i40e_fdir_info *fdir_info = &pf->fdir;
> @@ -1318,7 +1314,7 @@ i40e_fdir_filter_programming(struct i40e_pf *pf,
> * i40e_fdir_flush - clear all filters of Flow Director table
> * @pf: board private structure
> */
> -static int
> +int
> i40e_fdir_flush(struct rte_eth_dev *dev)
> {
> struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index 4c7856c..1d9f603 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -68,6 +68,8 @@ static struct rte_flow *i40e_flow_create(struct rte_eth_dev *dev,
> const struct rte_flow_item pattern[],
> const struct rte_flow_action actions[],
> struct rte_flow_error *error);
> +static int i40e_flow_flush(struct rte_eth_dev *dev,
> + struct rte_flow_error *error);
> static int i40e_flow_destroy(struct rte_eth_dev *dev,
> struct rte_flow *flow,
> struct rte_flow_error *error);
> @@ -95,11 +97,13 @@ static int i40e_dev_destroy_ethertype_filter(struct i40e_pf *pf,
> struct i40e_ethertype_filter *filter);
> static int i40e_dev_destroy_tunnel_filter(struct i40e_pf *pf,
> struct i40e_tunnel_filter *filter);
> +static int i40e_fdir_filter_flush(struct i40e_pf *pf);
>
> const struct rte_flow_ops i40e_flow_ops = {
> .validate = i40e_flow_validate,
> .create = i40e_flow_create,
> .destroy = i40e_flow_destroy,
> + .flush = i40e_flow_flush,
> };
>
> enum rte_filter_type cons_filter_type = RTE_ETH_FILTER_NONE;
> @@ -1603,3 +1607,45 @@ i40e_dev_destroy_tunnel_filter(struct i40e_pf *pf,
>
> return ret;
> }
> +
> +static int
> +i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
> +{
> + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> + int ret = 0;
> +
Meaningless initialization.
> + ret = i40e_fdir_filter_flush(pf);
> + if (!ret)
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> + "Failed to flush FDIR flows.");
Just curious. What's the relationship between `ret' and the code (EINVAL)
passed to rte_flow_error_set()? Is `-ret' acceptable as the parameter?
Because the `-ret' which is actually returned by i40e_fdir_flush() is also
some standard UNIX errno. When error occurs, user should use which one to
figure out the failure reason? `-ret' or `rte_errno'?
> +
> + return ret;
> +}
> +
> +static int
> +i40e_fdir_filter_flush(struct i40e_pf *pf)
> +{
> + struct rte_eth_dev *dev = pf->adapter->eth_dev;
> + struct i40e_fdir_info *fdir_info = &pf->fdir;
> + struct i40e_fdir_filter *fdir_filter;
> + struct i40e_flow *flow;
> + int ret = 0;
> +
Meaningless initialization.
> + ret = i40e_fdir_flush(dev);
> + if (!ret) {
> + /* Delete FDIR filters in FDIR list. */
> + while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list)))
> + i40e_sw_fdir_filter_del(pf, fdir_filter);
> +
The i40e_sw_fdir_filter_del() may fail, in which case fdir_filter won't
be removed from fdir_info->fdir_list. Will it lead to an infinite loop?
Should you check the retval of i40e_sw_fdir_filter_del() and break the
loop when it fails?
Best regards,
Tiwei Bie
^ permalink raw reply
* Fw: Packet is not being sent
From: April Teodoro @ 2016-12-28 5:38 UTC (permalink / raw)
To: dev@dpdk.org
In-Reply-To: <PS1PR02MB1595E82AB0B37EF1AEDB316ABF680@PS1PR02MB1595.apcprd02.prod.outlook.com>
________________________________
From: April Teodoro <ateodoro@hotmail.ph>
Sent: Wednesday, December 28, 2016 1:36 PM
To: dev@dpdk.org
Subject: Packet is not being sent
i, I am wondering what is causing the packet to be dropped. Please help me.
The mempool was created and retrieved via lookup
The port and queues have been verified to be correct.
However, according to stats, no packet is transmitted, although rte_eth_tx_burst returns 1. I also do not receive anything on the connected machine.
532 if(mem == NULL)
533 {
534 LOG <<"No mem";
535 }
536 else{
537 LOG << "has mem";
538 }
539
540 rte_mbuf *mbufs = rte_pktmbuf_alloc(mem);
541 if(NULL == mbufs)
542 {
543 LOG << "ALLOCATION failed";
544 }
545 else
546 {
547 LOG << "ALLOCATION successful";
548 }
549
550 uint8_t* messageToSend = NULL;
551 LOG << "SENDRAW 2";
552 ether_addr addr;
553 rte_eth_macaddr_get(port, &addr);
554 LOG << "start port 2: " << rte_eth_dev_start(2);
569 ether_addr_copy(&addr, &hdr->s_addr);
570 hdr->ether_type = rte_cpu_to_be_16(0x9998);
571 mbufs->pkt_len = mbufs->data_len = 8;
572
573 messageToSend = (uint8_t*)&hdr[2];
574
575 for(auto i=0u; i < sendmsg.header.msgSize; ++i) {
576 messageToSend[i] = sendmsg.data[i];
577 }
578
579 LOG << "SENDRAW " << sendmsg.header.msgSize;
580 mbufs->pkt_len = sendmsg.header.msgSize;
581 LOG << "SENDRAW 5";
582 LOG << "SENDRAW 6";
583 rte_mbuf *mbufArray[] = {mbufs};
584 rte_pktmbuf_refcnt_update(mbufs, 1);
585 LOG << "SENDRAW 7";
586 //uint16_t nbPk = rte_eth_tx_burst(2, 0, mbufArray, 1);
587 uint32_t sent = 0;
588 struct rte_eth_dev_info dev_info;
589 struct rte_eth_stats stats;
590 LOG << "stats successful? " << rte_eth_stats_get(2, &stats);
591 rte_eth_dev_info_get(2, &dev_info);
592 LOG << "dev info: " << (dev_info.pci_dev->addr.bus);
593 while (1) {
594 sent = rte_eth_tx_burst(2, 0, mbufArray, 1);
595 if (sent > 0) {
596 LOG << "opackets: " << stats.opackets;
597 LOG << "obytes: " << stats.obytes;
598 LOG << "oerrors: " << stats.oerrors;
599 LOG << "packets transmitted " << sent;
600 return;
601 }
602 }
603
604
605 }
^ permalink raw reply
* Packet is not being sent
From: April Teodoro @ 2016-12-28 5:36 UTC (permalink / raw)
To: dev@dpdk.org
i, I am wondering what is causing the packet to be dropped. Please help me.
The mempool was created and retrieved via lookup
The port and queues have been verified to be correct.
However, according to stats, no packet is transmitted, although rte_eth_tx_burst returns 1. I also do not receive anything on the connected machine.
532 if(mem == NULL)
533 {
534 LOG <<"No mem";
535 }
536 else{
537 LOG << "has mem";
538 }
539
540 rte_mbuf *mbufs = rte_pktmbuf_alloc(mem);
541 if(NULL == mbufs)
542 {
543 LOG << "ALLOCATION failed";
544 }
545 else
546 {
547 LOG << "ALLOCATION successful";
548 }
549
550 uint8_t* messageToSend = NULL;
551 LOG << "SENDRAW 2";
552 ether_addr addr;
553 rte_eth_macaddr_get(port, &addr);
554 LOG << "start port 2: " << rte_eth_dev_start(2);
569 ether_addr_copy(&addr, &hdr->s_addr);
570 hdr->ether_type = rte_cpu_to_be_16(0x9998);
571 mbufs->pkt_len = mbufs->data_len = 8;
572
573 messageToSend = (uint8_t*)&hdr[2];
574
575 for(auto i=0u; i < sendmsg.header.msgSize; ++i) {
576 messageToSend[i] = sendmsg.data[i];
577 }
578
579 LOG << "SENDRAW " << sendmsg.header.msgSize;
580 mbufs->pkt_len = sendmsg.header.msgSize;
581 LOG << "SENDRAW 5";
582 LOG << "SENDRAW 6";
583 rte_mbuf *mbufArray[] = {mbufs};
584 rte_pktmbuf_refcnt_update(mbufs, 1);
585 LOG << "SENDRAW 7";
586 //uint16_t nbPk = rte_eth_tx_burst(2, 0, mbufArray, 1);
587 uint32_t sent = 0;
588 struct rte_eth_dev_info dev_info;
589 struct rte_eth_stats stats;
590 LOG << "stats successful? " << rte_eth_stats_get(2, &stats);
591 rte_eth_dev_info_get(2, &dev_info);
592 LOG << "dev info: " << (dev_info.pci_dev->addr.bus);
593 while (1) {
594 sent = rte_eth_tx_burst(2, 0, mbufArray, 1);
595 if (sent > 0) {
596 LOG << "opackets: " << stats.opackets;
597 LOG << "obytes: " << stats.obytes;
598 LOG << "oerrors: " << stats.oerrors;
599 LOG << "packets transmitted " << sent;
600 return;
601 }
602 }
603
604
605 }
^ permalink raw reply
* Re: [PATCH v2 12/17] net/i40e: destroy ethertype filter
From: Tiwei Bie @ 2016-12-28 4:56 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-13-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:19PM +0800, Beilei Xing wrote:
> This patch adds i40e_dev_destroy_ethertype_filter function
> to destroy a ethertype filter for users.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.c | 10 ++-------
> drivers/net/i40e/i40e_ethdev.h | 5 +++++
> drivers/net/i40e/i40e_flow.c | 51 ++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 56 insertions(+), 10 deletions(-)
>
[...]
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index 2a61c4f..732c411 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
[...]
> @@ -1492,11 +1495,16 @@ i40e_flow_destroy(__rte_unused struct rte_eth_dev *dev,
The `__rte_unused' qualifier should be removed.
> struct rte_flow *flow,
> struct rte_flow_error *error)
> {
> + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> struct i40e_flow *pmd_flow = (struct i40e_flow *)flow;
> enum rte_filter_type filter_type = pmd_flow->filter_type;
> int ret;
>
> switch (filter_type) {
> + case RTE_ETH_FILTER_ETHERTYPE:
> + ret = i40e_dev_destroy_ethertype_filter(pf,
> + (struct i40e_ethertype_filter *)pmd_flow->rule);
> + break;
> default:
> PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> filter_type);
> @@ -1504,10 +1512,49 @@ i40e_flow_destroy(__rte_unused struct rte_eth_dev *dev,
> break;
> }
>
> - if (ret)
> + if (!ret) {
> + TAILQ_REMOVE(&pf->flow_list, pmd_flow, node);
> + free(pmd_flow);
> + } else {
> rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> "Failed to destroy flow.");
> + }
Probably you should introduce the pf related code when introducing
i40e_flow_destroy() in the below patch:
[PATCH v2 11/17] net/i40e: add flow destroy function
> +
> + return ret;
> +}
> +
> +static int
> +i40e_dev_destroy_ethertype_filter(struct i40e_pf *pf,
> + struct i40e_ethertype_filter *filter)
> +{
> + struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + struct i40e_ethertype_filter *node;
> + struct i40e_control_filter_stats stats;
> + uint16_t flags = 0;
> + int ret = 0;
> +
> + if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
> + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
> + if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
> + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
> + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
> +
> + memset(&stats, 0, sizeof(stats));
> + ret = i40e_aq_add_rem_control_packet_filter(hw,
> + filter->input.mac_addr.addr_bytes,
> + filter->input.ether_type,
> + flags, pf->main_vsi->seid,
> + filter->queue, 0, &stats, NULL);
> + if (ret < 0)
> + return ret;
> +
> + node = i40e_sw_ethertype_filter_lookup(ethertype_rule, &filter->input);
> + if (node)
> + ret = i40e_sw_ethertype_filter_del(pf, node);
> + else
> + return -EINVAL;
It would be more readable to check whether node equals NULL and return
when it's true, and call i40e_sw_ethertype_filter_del(pf, node) outside
the `if' statement:
node = i40e_sw_ethertype_filter_lookup(ethertype_rule, &filter->input);
if (node == NULL)
return -EINVAL;
ret = i40e_sw_ethertype_filter_del(pf, node);
Best regards,
Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 07/17] net/i40e: add flow validate function
From: Tiwei Bie @ 2016-12-28 4:08 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-8-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:14PM +0800, Beilei Xing wrote:
> This patch adds i40e_flow_validation function to check if
> a flow is valid according to the flow pattern.
> i40e_parse_ethertype_filter is added first, it also gets
> the ethertype info.
> i40e_flow.c is added to handle all generic filter events.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/Makefile | 1 +
> drivers/net/i40e/i40e_ethdev.c | 5 +
> drivers/net/i40e/i40e_ethdev.h | 20 ++
> drivers/net/i40e/i40e_flow.c | 431 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 457 insertions(+)
> create mode 100644 drivers/net/i40e/i40e_flow.c
>
> diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
> index 11175c4..89bd85a 100644
> --- a/drivers/net/i40e/Makefile
> +++ b/drivers/net/i40e/Makefile
> @@ -105,6 +105,7 @@ endif
> SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c
> SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c
> SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
> +SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_flow.c
>
> # vector PMD driver needs SSE4.1 support
> ifeq ($(findstring RTE_MACHINE_CPUFLAG_SSE4_1,$(CFLAGS)),)
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 7f98b79..80024ed 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -8452,6 +8452,11 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
> case RTE_ETH_FILTER_FDIR:
> ret = i40e_fdir_ctrl_func(dev, filter_op, arg);
> break;
> + case RTE_ETH_FILTER_GENERIC:
> + if (filter_op != RTE_ETH_FILTER_GET)
> + return -EINVAL;
> + *(const void **)arg = &i40e_flow_ops;
> + break;
> default:
> PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> filter_type);
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
> index 6089895..bbe52f0 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -38,6 +38,7 @@
> #include <rte_time.h>
> #include <rte_kvargs.h>
> #include <rte_hash.h>
> +#include <rte_flow_driver.h>
>
> #define I40E_VLAN_TAG_SIZE 4
>
> @@ -629,6 +630,23 @@ struct i40e_adapter {
> struct rte_timecounter tx_tstamp_tc;
> };
>
> +union i40e_filter_t {
> + struct rte_eth_ethertype_filter ethertype_filter;
> + struct rte_eth_fdir_filter fdir_filter;
> + struct rte_eth_tunnel_filter_conf tunnel_filter;
> +} cons_filter;
> +
Are you sure that you want to define a variable in i40e_ethdev.h?
> +typedef int (*parse_filter_t)(struct rte_eth_dev *dev,
> + const struct rte_flow_attr *attr,
> + const struct rte_flow_item pattern[],
> + const struct rte_flow_action actions[],
> + struct rte_flow_error *error,
> + union i40e_filter_t *filter);
> +struct i40e_valid_pattern {
> + enum rte_flow_item_type *items;
> + parse_filter_t parse_filter;
> +};
> +
> int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
> int i40e_vsi_release(struct i40e_vsi *vsi);
> struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
> @@ -823,4 +841,6 @@ i40e_calc_itr_interval(int16_t interval)
> ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_SR) || \
> ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_LR))
>
> +const struct rte_flow_ops i40e_flow_ops;
> +
Same here. Are you sure that you want to define a variable in i40e_ethdev.h?
Maybe you should add the `extern' qualifier.
Best regards,
Tiwei Bie
^ permalink raw reply
* Re: [PATCH 13/13] i40e: improve message grepability
From: Wu, Jingjing @ 2016-12-28 3:51 UTC (permalink / raw)
To: Michal Miroslaw, dev@dpdk.org, Yigit, Ferruh, Richardson, Bruce
In-Reply-To: <39ceb2bf1e5aa61e3957a8d8f9e5b2df28d6d2ad.1481590851.git.mirq-linux@rere.qmqm.pl>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Michal Miroslaw
> Sent: Tuesday, December 13, 2016 9:08 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH 13/13] i40e: improve message grepability
>
> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> ---
> drivers/net/i40e/i40e_ethdev.c | 198 +++++++++++++++--------------------------
> 1 file changed, 73 insertions(+), 125 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 39fbcfe..4d73aca 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -763,8 +763,7 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf
> *pf)
> pf->main_vsi_seid, 0,
> TRUE, NULL, NULL);
> if (ret)
> - PMD_INIT_LOG(ERR, "Failed to add filter to drop flow control "
> - " frames from VSIs.");
> + PMD_INIT_LOG(ERR, "Failed to add filter to drop flow control
> frames
> +from VSIs.");
> }
You are right, it makes grep easily. But it will break the coding style "Line length is recommended to be not more than 80 characters, including comments."
Any comments from committers?
Thanks
Jingjing
^ permalink raw reply
* Re: [PATCH 12/13] i40e: return -errno when intr setup fails
From: Wu, Jingjing @ 2016-12-28 3:47 UTC (permalink / raw)
To: Michal Miroslaw, dev@dpdk.org
In-Reply-To: <7f9c82cc9331585b82fcf680ffe873700808408f.1481590851.git.mirq-linux@rere.qmqm.pl>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Michal Miroslaw
> Sent: Tuesday, December 13, 2016 9:08 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH 12/13] i40e: return -errno when intr setup fails
>
> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> ---
> drivers/net/i40e/i40e_ethdev.c | 5 +++--
> lib/librte_eal/linuxapp/eal/eal_interrupts.c | 2 +-
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 67778ba..39fbcfe 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1692,8 +1692,9 @@ i40e_dev_start(struct rte_eth_dev *dev)
> !RTE_ETH_DEV_SRIOV(dev).active) &&
> dev->data->dev_conf.intr_conf.rxq != 0) {
> intr_vector = dev->data->nb_rx_queues;
> - if (rte_intr_efd_enable(intr_handle, intr_vector))
> - return -1;
> + ret = rte_intr_efd_enable(intr_handle, intr_vector);
> + if (ret)
> + return ret;
> }
>
> if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { diff --git
> a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> index 47a3b20..f7a8ce3 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> @@ -1157,7 +1157,7 @@ rte_intr_efd_enable(struct rte_intr_handle
> *intr_handle, uint32_t nb_efd)
> RTE_LOG(ERR, EAL,
> "can't setup eventfd, error %i (%s)\n",
> errno, strerror(errno));
> - return -1;
> + return -errno;
> }
> intr_handle->efds[i] = fd;
> }
> --
Reviewed-by: Jingjing Wu <jingjing.wu@intel.com>
^ permalink raw reply
* Re: [PATCH v2 03/17] net/i40e: store flow director filter
From: Tiwei Bie @ 2016-12-28 3:38 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-4-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:10PM +0800, Beilei Xing wrote:
> Currently there's no flow director filter stored in SW. This
> patch stores flow director filters in SW with cuckoo hash,
> also adds protection if a flow director filter has been added.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.c | 48 +++++++++++++++++++++
> drivers/net/i40e/i40e_ethdev.h | 12 ++++++
> drivers/net/i40e/i40e_fdir.c | 98 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 158 insertions(+)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index c012d5d..427ebdc 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
[...]
> @@ -1342,6 +1379,17 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> rte_free(p_tunnel);
> }
>
> + /* Remove all flow director rules and hash */
> + if (fdir_info->hash_map)
> + rte_free(fdir_info->hash_map);
> + if (fdir_info->hash_table)
> + rte_hash_free(fdir_info->hash_table);
> +
> + while ((p_fdir = TAILQ_FIRST(&fdir_info->fdir_list))) {
There is a redundant pair of parentheses, or you should compare with
NULL.
> + TAILQ_REMOVE(&fdir_info->fdir_list, p_fdir, rules);
> + rte_free(p_fdir);
> + }
> +
> dev->dev_ops = NULL;
> dev->rx_pkt_burst = NULL;
> dev->tx_pkt_burst = NULL;
[...]
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
> index 335bf15..faa2495 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
[...]
> +/* Check if there exists the flow director filter */
> +static struct i40e_fdir_filter *
> +i40e_sw_fdir_filter_lookup(struct i40e_fdir_info *fdir_info,
> + const struct rte_eth_fdir_input *input)
> +{
> + int ret = 0;
> +
The initialization is meaningless, as it will be written by the below
assignment unconditionally.
> + ret = rte_hash_lookup(fdir_info->hash_table, (const void *)input);
> + if (ret < 0)
> + return NULL;
> +
> + return fdir_info->hash_map[ret];
> +}
> +
> +/* Add a flow director filter into the SW list */
> +static int
> +i40e_sw_fdir_filter_insert(struct i40e_pf *pf, struct i40e_fdir_filter *filter)
> +{
> + struct i40e_fdir_info *fdir_info = &pf->fdir;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_add_key(fdir_info->hash_table,
> + &filter->fdir.input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to insert fdir filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + fdir_info->hash_map[ret] = filter;
> +
> + TAILQ_INSERT_TAIL(&fdir_info->fdir_list, filter, rules);
> +
> + return 0;
> +}
> +
> +/* Delete a flow director filter from the SW list */
> +static int
> +i40e_sw_fdir_filter_del(struct i40e_pf *pf, struct i40e_fdir_filter *filter)
> +{
> + struct i40e_fdir_info *fdir_info = &pf->fdir;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_del_key(fdir_info->hash_table,
> + &filter->fdir.input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to delete fdir filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + fdir_info->hash_map[ret] = NULL;
> +
> + TAILQ_REMOVE(&fdir_info->fdir_list, filter, rules);
> + rte_free(filter);
> +
> + return 0;
> +}
> +
> /*
> * i40e_add_del_fdir_filter - add or remove a flow director filter.
> * @pf: board private structure
> @@ -1032,6 +1105,8 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
> struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
> enum i40e_filter_pctype pctype;
> + struct i40e_fdir_info *fdir_info = &pf->fdir;
> + struct i40e_fdir_filter *fdir_filter, *node;
> int ret = 0;
>
> if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
> @@ -1054,6 +1129,21 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
> return -EINVAL;
> }
>
> + fdir_filter = rte_zmalloc("fdir_filter", sizeof(*fdir_filter), 0);
> + i40e_fdir_filter_convert(filter, fdir_filter);
> + node = i40e_sw_fdir_filter_lookup(fdir_info, &fdir_filter->fdir.input);
> + if (add && node) {
> + PMD_DRV_LOG(ERR,
> + "Conflict with existing flow director rules!");
> + rte_free(fdir_filter);
> + return -EINVAL;
> + } else if (!add && !node) {
When `if (add && node)' is true, function will return. There is no need
to use `else' here.
Best regards,
Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 02/17] net/i40e: store tunnel filter
From: Tiwei Bie @ 2016-12-28 3:27 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-3-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:09PM +0800, Beilei Xing wrote:
> Currently there's no tunnel filter stored in SW.
> This patch stores tunnel filter in SW with cuckoo
> hash, also adds protection if a tunnel filter has
> been added.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.c | 167 ++++++++++++++++++++++++++++++++++++++++-
> drivers/net/i40e/i40e_ethdev.h | 27 +++++++
> 2 files changed, 191 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 80dd8d7..c012d5d 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
[...]
> @@ -1267,6 +1314,7 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> pci_dev = dev->pci_dev;
> ethertype_rule = &pf->ethertype;
> + tunnel_rule = &pf->tunnel;
>
> if (hw->adapter_stopped == 0)
> i40e_dev_close(dev);
> @@ -1283,6 +1331,17 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> rte_free(p_ethertype);
> }
>
> + /* Remove all tunnel director rules and hash */
> + if (tunnel_rule->hash_map)
> + rte_free(tunnel_rule->hash_map);
> + if (tunnel_rule->hash_table)
> + rte_hash_free(tunnel_rule->hash_table);
> +
> + while ((p_tunnel = TAILQ_FIRST(&tunnel_rule->tunnel_list))) {
There is a redundant pair of parentheses, or you should compare with
NULL.
> + TAILQ_REMOVE(&tunnel_rule->tunnel_list, p_tunnel, rules);
> + rte_free(p_tunnel);
> + }
> +
> dev->dev_ops = NULL;
> dev->rx_pkt_burst = NULL;
> dev->tx_pkt_burst = NULL;
> @@ -6482,6 +6541,81 @@ i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag)
> return 0;
> }
>
> +/* Convert tunnel filter structure */
> +static int
> +i40e_tunnel_filter_convert(struct i40e_aqc_add_remove_cloud_filters_element_data
> + *cld_filter,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + ether_addr_copy((struct ether_addr *)&cld_filter->outer_mac,
> + (struct ether_addr *)&tunnel_filter->input.outer_mac);
> + ether_addr_copy((struct ether_addr *)&cld_filter->inner_mac,
> + (struct ether_addr *)&tunnel_filter->input.inner_mac);
> + tunnel_filter->input.inner_vlan = cld_filter->inner_vlan;
> + tunnel_filter->input.flags = cld_filter->flags;
> + tunnel_filter->input.tenant_id = cld_filter->tenant_id;
> + tunnel_filter->queue = cld_filter->queue_number;
> +
> + return 0;
> +}
> +
> +/* Check if there exists the tunnel filter */
> +static struct i40e_tunnel_filter *
> +i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule,
> + const struct i40e_tunnel_filter_input *input)
> +{
> + int ret = 0;
> +
The initialization is meaningless, as it will be written by the below
assignment unconditionally.
> + ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input);
> + if (ret < 0)
> + return NULL;
> +
> + return tunnel_rule->hash_map[ret];
> +}
> +
> +/* Add a tunnel filter into the SW list */
> +static int
> +i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_add_key(tunnel_rule->hash_table,
> + &tunnel_filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to insert tunnel filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + tunnel_rule->hash_map[ret] = tunnel_filter;
> +
> + TAILQ_INSERT_TAIL(&tunnel_rule->tunnel_list, tunnel_filter, rules);
> +
> + return 0;
> +}
> +
> +/* Delete a tunnel filter from the SW list */
> +static int
> +i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_del_key(tunnel_rule->hash_table,
> + &tunnel_filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to delete tunnel filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + tunnel_rule->hash_map[ret] = NULL;
> +
> + TAILQ_REMOVE(&tunnel_rule->tunnel_list, tunnel_filter, rules);
> + rte_free(tunnel_filter);
> +
> + return 0;
> +}
> +
> static int
> i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> struct rte_eth_tunnel_filter_conf *tunnel_filter,
> @@ -6497,6 +6631,8 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> struct i40e_vsi *vsi = pf->main_vsi;
> struct i40e_aqc_add_remove_cloud_filters_element_data *cld_filter;
> struct i40e_aqc_add_remove_cloud_filters_element_data *pfilter;
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + struct i40e_tunnel_filter *tunnel, *node;
>
> cld_filter = rte_zmalloc("tunnel_filter",
> sizeof(struct i40e_aqc_add_remove_cloud_filters_element_data),
> @@ -6559,11 +6695,36 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> pfilter->tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id);
> pfilter->queue_number = rte_cpu_to_le_16(tunnel_filter->queue_id);
>
> - if (add)
> + tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
> + i40e_tunnel_filter_convert(cld_filter, tunnel);
> + node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &tunnel->input);
> + if (add && node) {
> + PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
> + rte_free(tunnel);
> + return -EINVAL;
> + } else if (!add && !node) {
When `if (add && node)' is true, function will return. There is no need
to use `else' here.
Best regards,
Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 12/17] net/i40e: destroy ethertype filter
From: Wu, Jingjing @ 2016-12-28 3:30 UTC (permalink / raw)
To: Xing, Beilei, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1482819984-14120-13-git-send-email-beilei.xing@intel.com>
>
> const struct rte_flow_ops i40e_flow_ops = {
> .validate = i40e_flow_validate,
> @@ -1492,11 +1495,16 @@ i40e_flow_destroy(__rte_unused struct
> rte_eth_dev *dev,
> struct rte_flow *flow,
> struct rte_flow_error *error)
> {
> + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> struct i40e_flow *pmd_flow = (struct i40e_flow *)flow;
> enum rte_filter_type filter_type = pmd_flow->filter_type;
> int ret;
>
> switch (filter_type) {
> + case RTE_ETH_FILTER_ETHERTYPE:
> + ret = i40e_dev_destroy_ethertype_filter(pf,
> + (struct i40e_ethertype_filter *)pmd_flow->rule);
> + break;
> default:
> PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> filter_type);
> @@ -1504,10 +1512,49 @@ i40e_flow_destroy(__rte_unused struct
> rte_eth_dev *dev,
> break;
> }
>
> - if (ret)
> + if (!ret) {
> + TAILQ_REMOVE(&pf->flow_list, pmd_flow, node);
> + free(pmd_flow);
Should it be freed inside the function? Is the API definition like that?
^ permalink raw reply
* Re: [PATCH v2 01/17] net/i40e: store ethertype filter
From: Tiwei Bie @ 2016-12-28 3:22 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-2-git-send-email-beilei.xing@intel.com>
On Tue, Dec 27, 2016 at 02:26:08PM +0800, Beilei Xing wrote:
> Currently there's no ethertype filter stored in SW.
> This patch stores ethertype filter with cuckoo hash
> in SW, also adds protection if an ethertype filter
> has been added.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/Makefile | 1 +
> drivers/net/i40e/i40e_ethdev.c | 164 ++++++++++++++++++++++++++++++++++++++++-
> drivers/net/i40e/i40e_ethdev.h | 26 +++++++
> 3 files changed, 190 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
> index 66997b6..11175c4 100644
> --- a/drivers/net/i40e/Makefile
> +++ b/drivers/net/i40e/Makefile
> @@ -117,5 +117,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether
> DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_mempool lib/librte_mbuf
> DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_net
> DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_kvargs
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_hash
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index f42f4ba..80dd8d7 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
[...]
> @@ -1203,23 +1249,40 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
> static int
> eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> {
> + struct i40e_pf *pf;
> struct rte_pci_device *pci_dev;
> struct i40e_hw *hw;
> struct i40e_filter_control_settings settings;
> + struct i40e_ethertype_filter *p_ethertype;
> int ret;
> uint8_t aq_fail = 0;
> + struct i40e_ethertype_rule *ethertype_rule;
>
> PMD_INIT_FUNC_TRACE();
>
> if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> return 0;
>
> + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> pci_dev = dev->pci_dev;
> + ethertype_rule = &pf->ethertype;
>
> if (hw->adapter_stopped == 0)
> i40e_dev_close(dev);
>
> + /* Remove all ethertype director rules and hash */
> + if (ethertype_rule->hash_map)
> + rte_free(ethertype_rule->hash_map);
> + if (ethertype_rule->hash_table)
> + rte_hash_free(ethertype_rule->hash_table);
> +
> + while ((p_ethertype = TAILQ_FIRST(ðertype_rule->ethertype_list))) {
There is a redundant pair of parentheses, or you should compare with
NULL.
> + TAILQ_REMOVE(ðertype_rule->ethertype_list,
> + p_ethertype, rules);
> + rte_free(p_ethertype);
> + }
> +
> dev->dev_ops = NULL;
> dev->rx_pkt_burst = NULL;
> dev->tx_pkt_burst = NULL;
> @@ -7954,6 +8017,78 @@ i40e_hash_filter_ctrl(struct rte_eth_dev *dev,
> return ret;
> }
>
> +/* Convert ethertype filter structure */
> +static int
> +i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input,
> + struct i40e_ethertype_filter *filter)
> +{
> + rte_memcpy(&filter->input.mac_addr, &input->mac_addr, ETHER_ADDR_LEN);
> + filter->input.ether_type = input->ether_type;
> + filter->flags = input->flags;
> + filter->queue = input->queue;
> +
> + return 0;
> +}
> +
> +/* Check if there exists the ehtertype filter */
> +static struct i40e_ethertype_filter *
> +i40e_sw_ethertype_filter_lookup(struct i40e_ethertype_rule *ethertype_rule,
> + const struct i40e_ethertype_filter_input *input)
> +{
> + int ret = 0;
> +
The initialization is meaningless, as it will be written by the below
assignment unconditionally.
> + ret = rte_hash_lookup(ethertype_rule->hash_table, (const void *)input);
> + if (ret < 0)
> + return NULL;
> +
> + return ethertype_rule->hash_map[ret];
> +}
> +
> +/* Add ethertype filter in SW list */
> +static int
> +i40e_sw_ethertype_filter_insert(struct i40e_pf *pf,
> + struct i40e_ethertype_filter *filter)
> +{
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_add_key(ethertype_rule->hash_table,
> + &filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to insert ethertype filter"
> + " to hash table %d!",
> + ret);
Function should return when ret < 0.
> + ethertype_rule->hash_map[ret] = filter;
> +
> + TAILQ_INSERT_TAIL(ðertype_rule->ethertype_list, filter, rules);
> +
> + return 0;
> +}
> +
> +/* Delete ethertype filter in SW list */
> +static int
> +i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
> + struct i40e_ethertype_filter *filter)
> +{
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_del_key(ethertype_rule->hash_table,
> + &filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to delete ethertype filter"
> + " to hash table %d!",
> + ret);
Function should return when ret < 0.
> + ethertype_rule->hash_map[ret] = NULL;
> +
> + TAILQ_REMOVE(ðertype_rule->ethertype_list, filter, rules);
> + rte_free(filter);
> +
> + return 0;
> +}
> +
> /*
> * Configure ethertype filter, which can director packet by filtering
> * with mac address and ether_type or only ether_type
> @@ -7964,6 +8099,8 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> bool add)
> {
> struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + struct i40e_ethertype_filter *ethertype_filter, *node;
> struct i40e_control_filter_stats stats;
> uint16_t flags = 0;
> int ret;
> @@ -7982,6 +8119,22 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag is"
> " not supported.");
>
> + /* Check if there is the filter in SW list */
> + ethertype_filter = rte_zmalloc("ethertype_filter",
> + sizeof(*ethertype_filter), 0);
> + i40e_ethertype_filter_convert(filter, ethertype_filter);
> + node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
> + ðertype_filter->input);
> + if (add && node) {
> + PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
> + rte_free(ethertype_filter);
> + return -EINVAL;
> + } else if (!add && !node) {
When `if (add && node)' is true, function will return. There is no need
to use `else' here.
Best regards,
Tiwei Bie
^ permalink raw reply
* Re: [PATCH v2 07/17] net/i40e: add flow validate function
From: Wu, Jingjing @ 2016-12-28 2:52 UTC (permalink / raw)
To: Xing, Beilei, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1482819984-14120-8-git-send-email-beilei.xing@intel.com>
>
> +union i40e_filter_t {
> + struct rte_eth_ethertype_filter ethertype_filter;
> + struct rte_eth_fdir_filter fdir_filter;
> + struct rte_eth_tunnel_filter_conf tunnel_filter; } cons_filter;
> +
> +typedef int (*parse_filter_t)(struct rte_eth_dev *dev,
> + const struct rte_flow_attr *attr,
> + const struct rte_flow_item pattern[],
> + const struct rte_flow_action actions[],
> + struct rte_flow_error *error,
> + union i40e_filter_t *filter);
You can use void* instead of define union i40e_filter_t.
> +struct i40e_valid_pattern {
> + enum rte_flow_item_type *items;
What the item points to? Add few comments
> +
> + ret = parse_filter(dev, attr, items, actions, error, &cons_filter);
Will you use cons_filter later? If not, it looks like we don't need the argument at all.
> +
> + rte_free(items);
> +
> + return ret;
> +}
> --
> 2.5.5
^ permalink raw reply
* Re: [PATCH v2 04/17] net/i40e: restore ethertype filter
From: Wu, Jingjing @ 2016-12-28 2:25 UTC (permalink / raw)
To: Xing, Beilei, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1482819984-14120-5-git-send-email-beilei.xing@intel.com>
> -----Original Message-----
> From: Xing, Beilei
> Sent: Tuesday, December 27, 2016 2:26 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
> Cc: dev@dpdk.org
> Subject: [PATCH v2 04/17] net/i40e: restore ethertype filter
>
> Add support of restoring ethertype filter in case filter dropped accidentally, as all
> filters need to be added and removed by user obviously for generic filter API.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.c | 39
> +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 427ebdc..cd7c309 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -484,6 +484,9 @@ static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
> static int i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
> struct i40e_tunnel_filter *tunnel_filter);
>
> +static void i40e_ethertype_filter_restore(struct i40e_pf *pf); static
> +void i40e_filter_restore(struct i40e_pf *pf);
> +
> static const struct rte_pci_id pci_id_i40e_map[] = {
> { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710) },
> { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QEMU) },
> @@ -1964,6 +1967,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
> /* enable uio intr after callback register */
> rte_intr_enable(intr_handle);
>
> + i40e_filter_restore(pf);
> +
> return I40E_SUCCESS;
>
> err_up:
> @@ -10066,3 +10071,37 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev,
> uint16_t mtu)
>
> return ret;
> }
> +
> +/* Restore ethertype filter */
> +static void
> +i40e_ethertype_filter_restore(struct i40e_pf *pf) {
> + struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> + struct i40e_ethertype_filter_list
> + *ethertype_list = &pf->ethertype.ethertype_list;
> + struct i40e_ethertype_filter *f;
> + struct i40e_control_filter_stats stats;
> + uint16_t flags;
> +
> + TAILQ_FOREACH(f, ethertype_list, rules) {
> + flags = 0;
> + if (!(f->flags & RTE_ETHTYPE_FLAGS_MAC))
> + flags |=
> I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
> + if (f->flags & RTE_ETHTYPE_FLAGS_DROP)
> + flags |=
> I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
> + flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
> +
> + memset(&stats, 0, sizeof(stats));
> + i40e_aq_add_rem_control_packet_filter(hw,
> + f->input.mac_addr.addr_bytes,
> + f->input.ether_type,
> + flags, pf->main_vsi->seid,
> + f->queue, 1, &stats, NULL);
> + }
How about to lig the stats to show how many filters are restored?
Thanks
Jingjing
^ permalink raw reply
* Re: [PATCH v2 01/17] net/i40e: store ethertype filter
From: Wu, Jingjing @ 2016-12-28 2:22 UTC (permalink / raw)
To: Xing, Beilei, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1482819984-14120-2-git-send-email-beilei.xing@intel.com>
> +
> +/* Delete ethertype filter in SW list */ static int
> +i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
> + struct i40e_ethertype_filter *filter) {
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + int ret = 0;
> +
> + ret = rte_hash_del_key(ethertype_rule->hash_table,
> + &filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to delete ethertype filter"
> + " to hash table %d!",
> + ret);
> + ethertype_rule->hash_map[ret] = NULL;
> +
> + TAILQ_REMOVE(ðertype_rule->ethertype_list, filter, rules);
> + rte_free(filter);
It's better to free filter out of del function because the filter is also the input argument.
Or you can define this function to use key as argument but not filter.
> /*
> * Configure ethertype filter, which can director packet by filtering
> * with mac address and ether_type or only ether_type @@ -7964,6 +8099,8
> @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> bool add)
> {
> struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> + struct i40e_ethertype_filter *ethertype_filter, *node;
> struct i40e_control_filter_stats stats;
> uint16_t flags = 0;
> int ret;
> @@ -7982,6 +8119,22 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag is"
> " not supported.");
>
> + /* Check if there is the filter in SW list */
> + ethertype_filter = rte_zmalloc("ethertype_filter",
> + sizeof(*ethertype_filter), 0);
> + i40e_ethertype_filter_convert(filter, ethertype_filter);
> + node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
> + ðertype_filter->input);
> + if (add && node) {
> + PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
> + rte_free(ethertype_filter);
> + return -EINVAL;
> + } else if (!add && !node) {
> + PMD_DRV_LOG(ERR, "There's no corresponding ethertype
> filter!");
> + rte_free(ethertype_filter);
> + return -EINVAL;
> + }
How about malloc ethertype_filter after check? Especially, no need to malloc it when delete a filter.
Thanks
Jingjing
^ permalink raw reply
* [PATCH v2] crypto/aesni_gcm: migration from MB library to ISA-L
From: Michal Jastrzebski @ 2016-12-27 18:53 UTC (permalink / raw)
To: dev; +Cc: pablo.de.lara.guarch, Piotr Azarewicz
From: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Current Cryptodev AESNI-GCM PMD is implemented using AESNI-MB
library.This patch reimplement Cryptodev AESni-GCM using ISA-L Crypto
library: https://github.com/01org/isa-l_crypto.
In new version 256-bit key support and AAD variable length is available.
Verified current unit tests and added new unit tests to verify new
functionalities.
v2 changes:
- implement native scatter-gatter support for chained mbufs (only out-of
place and destination mbuf must be contiguous)
- write unit test for session-less mode
- write unit test for out-of place processing
- add support for GMAC authentication algorithm
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
---
app/test/test_cryptodev.c | 739 +++++++++++++++++++---
app/test/test_cryptodev_gcm_test_vectors.h | 487 +++++++++++++-
doc/guides/cryptodevs/aesni_gcm.rst | 23 +-
doc/guides/rel_notes/release_17_02.rst | 13 +
drivers/crypto/aesni_gcm/Makefile | 8 +-
drivers/crypto/aesni_gcm/aesni_gcm_ops.h | 95 +--
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 307 ++++-----
drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 49 +-
drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h | 15 +-
mk/rte.app.mk | 3 +-
10 files changed, 1356 insertions(+), 383 deletions(-)
diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 00dced5..0bea584 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -3931,16 +3931,48 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
}
static int
+create_gcm_xforms(struct rte_crypto_op *op,
+ enum rte_crypto_cipher_operation cipher_op,
+ uint8_t *key, const uint8_t key_len,
+ const uint8_t aad_len, const uint8_t auth_len,
+ enum rte_crypto_auth_operation auth_op)
+{
+ TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 2),
+ "failed to allocate space for crypto transforms");
+
+ struct rte_crypto_sym_op *sym_op = op->sym;
+
+ /* Setup Cipher Parameters */
+ sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+ sym_op->xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM;
+ sym_op->xform->cipher.op = cipher_op;
+ sym_op->xform->cipher.key.data = key;
+ sym_op->xform->cipher.key.length = key_len;
+
+ TEST_HEXDUMP(stdout, "key:", key, key_len);
+
+ /* Setup Authentication Parameters */
+ sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+ sym_op->xform->next->auth.algo = RTE_CRYPTO_AUTH_AES_GCM;
+ sym_op->xform->next->auth.op = auth_op;
+ sym_op->xform->next->auth.digest_length = auth_len;
+ sym_op->xform->next->auth.add_auth_data_length = aad_len;
+ sym_op->xform->next->auth.key.length = 0;
+ sym_op->xform->next->auth.key.data = NULL;
+ sym_op->xform->next->next = NULL;
+
+ return 0;
+}
+
+static int
create_gcm_operation(enum rte_crypto_cipher_operation op,
- const uint8_t *auth_tag, const unsigned auth_tag_len,
- const uint8_t *iv, const unsigned iv_len,
- const uint8_t *aad, const unsigned aad_len,
- const unsigned data_len, unsigned data_pad_len)
+ const struct gcm_test_data *tdata)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct crypto_unittest_params *ut_params = &unittest_params;
- unsigned iv_pad_len = 0, aad_buffer_len;
+ uint8_t *plaintext, *ciphertext;
+ unsigned int iv_pad_len, aad_pad_len, plaintext_pad_len;
/* Generate Crypto op data structure */
ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
@@ -3950,63 +3982,118 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
- sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
- ut_params->ibuf, auth_tag_len);
- TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
- "no room to append digest");
- sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
- ut_params->ibuf, data_pad_len);
- sym_op->auth.digest.length = auth_tag_len;
-
- if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
- rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len);
- TEST_HEXDUMP(stdout, "digest:",
- sym_op->auth.digest.data,
- sym_op->auth.digest.length);
- }
+ /* Append aad data */
+ aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16);
+ sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ aad_pad_len);
+ TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data,
+ "no room to append aad");
- /* iv */
- iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16);
+ sym_op->auth.aad.length = tdata->aad.len;
+ sym_op->auth.aad.phys_addr =
+ rte_pktmbuf_mtophys(ut_params->ibuf);
+ memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len);
+ TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data,
+ sym_op->auth.aad.length);
+ /* Prepend iv */
+ iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16);
sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(
ut_params->ibuf, iv_pad_len);
TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv");
memset(sym_op->cipher.iv.data, 0, iv_pad_len);
sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
- sym_op->cipher.iv.length = iv_len;
+ sym_op->cipher.iv.length = tdata->iv.len;
- rte_memcpy(sym_op->cipher.iv.data, iv, iv_len);
+ rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len);
+ TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data,
+ sym_op->cipher.iv.length);
- /*
- * Always allocate the aad up to the block size.
- * The cryptodev API calls out -
- * - the array must be big enough to hold the AAD, plus any
- * space to round this up to the nearest multiple of the
- * block size (16 bytes).
- */
- aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16);
+ /* Append plaintext/ciphertext */
+ if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+ plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+ plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ plaintext_pad_len);
+ TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext");
- sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend(
- ut_params->ibuf, aad_buffer_len);
- TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data,
- "no room to prepend aad");
- sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(
- ut_params->ibuf);
- sym_op->auth.aad.length = aad_len;
+ memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);
+ TEST_HEXDUMP(stdout, "plaintext:", plaintext,
+ tdata->plaintext.len);
- memset(sym_op->auth.aad.data, 0, aad_buffer_len);
- rte_memcpy(sym_op->auth.aad.data, aad, aad_len);
+ if (ut_params->obuf) {
+ ciphertext = (uint8_t *)rte_pktmbuf_append(
+ ut_params->obuf,
+ plaintext_pad_len + aad_pad_len +
+ iv_pad_len);
+ TEST_ASSERT_NOT_NULL(ciphertext,
+ "no room to append ciphertext");
- TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len);
- TEST_HEXDUMP(stdout, "aad:",
- sym_op->auth.aad.data, aad_len);
+ memset(ciphertext + aad_pad_len + iv_pad_len, 0,
+ tdata->ciphertext.len);
+ }
+ } else {
+ plaintext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16);
+ ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ plaintext_pad_len);
+ TEST_ASSERT_NOT_NULL(ciphertext,
+ "no room to append ciphertext");
+
+ memcpy(ciphertext, tdata->ciphertext.data,
+ tdata->ciphertext.len);
+ TEST_HEXDUMP(stdout, "ciphertext:", ciphertext,
+ tdata->ciphertext.len);
+
+ if (ut_params->obuf) {
+ plaintext = (uint8_t *)rte_pktmbuf_append(
+ ut_params->obuf,
+ plaintext_pad_len + aad_pad_len +
+ iv_pad_len);
+ TEST_ASSERT_NOT_NULL(plaintext,
+ "no room to append plaintext");
+
+ memset(plaintext + aad_pad_len + iv_pad_len, 0,
+ tdata->plaintext.len);
+ }
+ }
+
+ /* Append digest data */
+ if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+ sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+ ut_params->obuf ? ut_params->obuf :
+ ut_params->ibuf,
+ tdata->auth_tag.len);
+ TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+ "no room to append digest");
+ memset(sym_op->auth.digest.data, 0, tdata->auth_tag.len);
+ sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+ ut_params->obuf ? ut_params->obuf :
+ ut_params->ibuf,
+ plaintext_pad_len +
+ aad_pad_len + iv_pad_len);
+ sym_op->auth.digest.length = tdata->auth_tag.len;
+ } else {
+ sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+ ut_params->ibuf, tdata->auth_tag.len);
+ TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+ "no room to append digest");
+ sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+ ut_params->ibuf,
+ plaintext_pad_len + aad_pad_len + iv_pad_len);
+ sym_op->auth.digest.length = tdata->auth_tag.len;
+
+ rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data,
+ tdata->auth_tag.len);
+ TEST_HEXDUMP(stdout, "digest:",
+ sym_op->auth.digest.data,
+ sym_op->auth.digest.length);
+ }
- sym_op->cipher.data.length = data_len;
- sym_op->cipher.data.offset = aad_buffer_len + iv_pad_len;
+ sym_op->cipher.data.length = tdata->plaintext.len;
+ sym_op->cipher.data.offset = aad_pad_len + iv_pad_len;
- sym_op->auth.data.offset = aad_buffer_len + iv_pad_len;
- sym_op->auth.data.length = data_len;
+ sym_op->auth.data.length = tdata->plaintext.len;
+ sym_op->auth.data.offset = aad_pad_len + iv_pad_len;
return 0;
}
@@ -4018,9 +4105,9 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
struct crypto_unittest_params *ut_params = &unittest_params;
int retval;
-
- uint8_t *plaintext, *ciphertext, *auth_tag;
+ uint8_t *ciphertext, *auth_tag;
uint16_t plaintext_pad_len;
+ uint32_t i;
/* Create GCM session */
retval = create_gcm_session(ts_params->valid_devs[0],
@@ -4031,31 +4118,20 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
if (retval < 0)
return retval;
-
- ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ if (tdata->aad.len > MBUF_SIZE) {
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool);
+ /* Populate full size of add data */
+ for (i = 32; i < GMC_MAX_AAD_LENGTH; i += 32)
+ memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32);
+ } else
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
/* clear mbuf payload */
memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
rte_pktmbuf_tailroom(ut_params->ibuf));
- /*
- * Append data which is padded to a multiple
- * of the algorithms block size
- */
- plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
-
- plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
- plaintext_pad_len);
- memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);
-
- TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len);
-
- /* Create GCM opertaion */
- retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT,
- tdata->auth_tag.data, tdata->auth_tag.len,
- tdata->iv.data, tdata->iv.len,
- tdata->aad.data, tdata->aad.len,
- tdata->plaintext.len, plaintext_pad_len);
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
if (retval < 0)
return retval;
@@ -4070,14 +4146,18 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
"crypto op processing failed");
+ plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
if (ut_params->op->sym->m_dst) {
ciphertext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst,
uint8_t *);
auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst,
uint8_t *, plaintext_pad_len);
} else {
- ciphertext = plaintext;
- auth_tag = plaintext + plaintext_pad_len;
+ ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src,
+ uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
+ auth_tag = ciphertext + plaintext_pad_len;
}
TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
@@ -4143,15 +4223,68 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
}
static int
+test_mb_AES_GCM_auth_encryption_test_case_256_1(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_1);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_2(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_2);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_3(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_3);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_4(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_4);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_5(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_5);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_6(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_6);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_7(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_7);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_aad_1(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_1);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_aad_2(void)
+{
+ return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_2);
+}
+
+static int
test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct crypto_unittest_params *ut_params = &unittest_params;
int retval;
-
- uint8_t *plaintext, *ciphertext;
- uint16_t ciphertext_pad_len;
+ uint8_t *plaintext;
+ uint32_t i;
/* Create GCM session */
retval = create_gcm_session(ts_params->valid_devs[0],
@@ -4162,31 +4295,23 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
if (retval < 0)
return retval;
-
/* alloc mbuf and set payload */
- ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ if (tdata->aad.len > MBUF_SIZE) {
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool);
+ /* Populate full size of add data */
+ for (i = 32; i < GMC_MAX_AAD_LENGTH; i += 32)
+ memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32);
+ } else
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
rte_pktmbuf_tailroom(ut_params->ibuf));
- ciphertext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16);
-
- ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
- ciphertext_pad_len);
- memcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);
-
- TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
-
- /* Create GCM opertaion */
- retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT,
- tdata->auth_tag.data, tdata->auth_tag.len,
- tdata->iv.data, tdata->iv.len,
- tdata->aad.data, tdata->aad.len,
- tdata->ciphertext.len, ciphertext_pad_len);
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
if (retval < 0)
return retval;
-
rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
ut_params->op->sym->m_src = ut_params->ibuf;
@@ -4202,7 +4327,9 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
plaintext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst,
uint8_t *);
else
- plaintext = ciphertext;
+ plaintext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src,
+ uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
@@ -4262,6 +4389,358 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
}
static int
+test_mb_AES_GCM_auth_decryption_test_case_256_1(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_1);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_2(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_2);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_3(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_3);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_4(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_4);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_5(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_5);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_6(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_6);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_7(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_7);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_aad_1(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_1);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_aad_2(void)
+{
+ return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_2);
+}
+
+static int
+test_AES_GCM_authenticated_encryption_oop(const struct gcm_test_data *tdata)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+
+ int retval;
+ uint8_t *ciphertext, *auth_tag;
+ uint16_t plaintext_pad_len;
+
+ /* Create GCM session */
+ retval = create_gcm_session(ts_params->valid_devs[0],
+ RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+ tdata->key.data, tdata->key.len,
+ tdata->aad.len, tdata->auth_tag.len,
+ RTE_CRYPTO_AUTH_OP_GENERATE);
+ if (retval < 0)
+ return retval;
+
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+ /* clear mbuf payload */
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+ memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->obuf));
+
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
+ if (retval < 0)
+ return retval;
+
+ rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+ ut_params->op->sym->m_src = ut_params->ibuf;
+ ut_params->op->sym->m_dst = ut_params->obuf;
+
+ /* Process crypto operation */
+ TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op), "failed to process sym crypto op");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "crypto op processing failed");
+
+ plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
+ ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
+ auth_tag = ciphertext + plaintext_pad_len;
+
+ TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
+ TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->auth_tag.len);
+
+ /* Validate obuf */
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ ciphertext,
+ tdata->ciphertext.data,
+ tdata->ciphertext.len,
+ "GCM Ciphertext data not as expected");
+
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ auth_tag,
+ tdata->auth_tag.data,
+ tdata->auth_tag.len,
+ "GCM Generated auth tag not as expected");
+
+ return 0;
+
+}
+
+static int
+test_mb_AES_GCM_authenticated_encryption_oop(void)
+{
+ return test_AES_GCM_authenticated_encryption_oop(&gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_decryption_oop(const struct gcm_test_data *tdata)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+
+ int retval;
+ uint8_t *plaintext;
+
+ /* Create GCM session */
+ retval = create_gcm_session(ts_params->valid_devs[0],
+ RTE_CRYPTO_CIPHER_OP_DECRYPT,
+ tdata->key.data, tdata->key.len,
+ tdata->aad.len, tdata->auth_tag.len,
+ RTE_CRYPTO_AUTH_OP_VERIFY);
+ if (retval < 0)
+ return retval;
+
+ /* alloc mbuf and set payload */
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+ memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->obuf));
+
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
+ if (retval < 0)
+ return retval;
+
+ rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+ ut_params->op->sym->m_src = ut_params->ibuf;
+ ut_params->op->sym->m_dst = ut_params->obuf;
+
+ /* Process crypto operation */
+ TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op), "failed to process sym crypto op");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "crypto op processing failed");
+
+ plaintext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
+
+ TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
+
+ /* Validate obuf */
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ plaintext,
+ tdata->plaintext.data,
+ tdata->plaintext.len,
+ "GCM plaintext data not as expected");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status,
+ RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "GCM authentication failed");
+ return 0;
+}
+
+static int
+test_mb_AES_GCM_authenticated_decryption_oop(void)
+{
+ return test_AES_GCM_authenticated_decryption_oop(&gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_encryption_sessionless(
+ const struct gcm_test_data *tdata)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+
+ int retval;
+ uint8_t *ciphertext, *auth_tag;
+ uint16_t plaintext_pad_len;
+ uint8_t key[tdata->key.len + 1];
+
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+ /* clear mbuf payload */
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
+ if (retval < 0)
+ return retval;
+
+ /* Create GCM xforms */
+ memcpy(key, tdata->key.data, tdata->key.len);
+ retval = create_gcm_xforms(ut_params->op,
+ RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+ key, tdata->key.len,
+ tdata->aad.len, tdata->auth_tag.len,
+ RTE_CRYPTO_AUTH_OP_GENERATE);
+ if (retval < 0)
+ return retval;
+
+ ut_params->op->sym->m_src = ut_params->ibuf;
+
+ TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+ RTE_CRYPTO_SYM_OP_SESSIONLESS,
+ "crypto op session type not sessionless");
+
+ /* Process crypto operation */
+ TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op), "failed to process sym crypto op");
+
+ TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "crypto op status not success");
+
+ plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
+ ciphertext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
+ auth_tag = ciphertext + plaintext_pad_len;
+
+ TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
+ TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->auth_tag.len);
+
+ /* Validate obuf */
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ ciphertext,
+ tdata->ciphertext.data,
+ tdata->ciphertext.len,
+ "GCM Ciphertext data not as expected");
+
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ auth_tag,
+ tdata->auth_tag.data,
+ tdata->auth_tag.len,
+ "GCM Generated auth tag not as expected");
+
+ return 0;
+
+}
+
+static int
+test_mb_AES_GCM_authenticated_encryption_sessionless(void)
+{
+ return test_AES_GCM_authenticated_encryption_sessionless(
+ &gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_decryption_sessionless(
+ const struct gcm_test_data *tdata)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+
+ int retval;
+ uint8_t *plaintext;
+ uint8_t key[tdata->key.len + 1];
+
+ /* alloc mbuf and set payload */
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+
+ /* Create GCM operation */
+ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
+ if (retval < 0)
+ return retval;
+
+ /* Create GCM xforms */
+ memcpy(key, tdata->key.data, tdata->key.len);
+ retval = create_gcm_xforms(ut_params->op,
+ RTE_CRYPTO_CIPHER_OP_DECRYPT,
+ key, tdata->key.len,
+ tdata->aad.len, tdata->auth_tag.len,
+ RTE_CRYPTO_AUTH_OP_VERIFY);
+ if (retval < 0)
+ return retval;
+
+ ut_params->op->sym->m_src = ut_params->ibuf;
+
+ TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+ RTE_CRYPTO_SYM_OP_SESSIONLESS,
+ "crypto op session type not sessionless");
+
+ /* Process crypto operation */
+ TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op), "failed to process sym crypto op");
+
+ TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "crypto op status not success");
+
+ plaintext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *,
+ ut_params->op->sym->cipher.data.offset);
+
+ TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
+
+ /* Validate obuf */
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(
+ plaintext,
+ tdata->plaintext.data,
+ tdata->plaintext.len,
+ "GCM plaintext data not as expected");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status,
+ RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "GCM authentication failed");
+ return 0;
+}
+
+static int
+test_mb_AES_GCM_authenticated_decryption_sessionless(void)
+{
+ return test_AES_GCM_authenticated_decryption_sessionless(
+ &gcm_test_case_5);
+}
+
+static int
test_stats(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -6332,6 +6811,82 @@ struct test_crypto_vector {
TEST_CASE_ST(ut_setup, ut_teardown,
test_mb_AES_GCM_authenticated_decryption_test_case_7),
+ /** AES GCM Authenticated Encryption 256 bits key */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_2),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_3),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_4),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_5),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_6),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_256_7),
+
+ /** AES GCM Authenticated Decryption 256 bits key */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_2),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_3),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_4),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_5),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_6),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_256_7),
+
+ /** AES GCM Authenticated Encryption big aad size */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_aad_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_encryption_test_case_aad_2),
+
+ /** AES GCM Authenticated Decryption big aad size */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_aad_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_auth_decryption_test_case_aad_2),
+
+ /** AES GMAC Authentication */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_test_case_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_verify_test_case_1),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_test_case_3),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_verify_test_case_3),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_test_case_4),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_GMAC_authentication_verify_test_case_4),
+
+ /** Negative tests */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_AES128_GMAC_fail_data_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_AES128_GMAC_fail_tag_corrupt),
+
+ /** Out of place tests */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_authenticated_encryption_oop),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_authenticated_decryption_oop),
+
+ /** Session-less tests */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_authenticated_encryption_sessionless),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_mb_AES_GCM_authenticated_decryption_sessionless),
+
TEST_CASES_END() /**< NULL terminate unit test array */
}
};
diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h
index b404242..9a31a38 100644
--- a/app/test/test_cryptodev_gcm_test_vectors.h
+++ b/app/test/test_cryptodev_gcm_test_vectors.h
@@ -33,7 +33,17 @@
#ifndef TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
#define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
-#define GMAC_LARGE_PLAINTEXT_LENGTH 65376
+#define GMAC_LARGE_PLAINTEXT_LENGTH 65344
+#define GMC_MAX_AAD_LENGTH 65536
+#define GMC_LARGE_AAD_LENGTH 65296
+
+static uint8_t gcm_aad_zero_text[GMC_MAX_AAD_LENGTH] = { 0 };
+
+static uint8_t gcm_aad_text[GMC_MAX_AAD_LENGTH] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0xf1, 0xe2, 0xd3, 0xc4, 0xb5, 0xa6, 0x97,
+ 0x88, 0x79, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f };
struct gcm_test_data {
struct {
@@ -47,7 +57,7 @@ struct gcm_test_data {
} iv;
struct {
- uint8_t data[64];
+ uint8_t *data;
unsigned len;
} aad;
@@ -111,7 +121,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = { 0 },
+ .data = gcm_aad_zero_text,
.len = 0
},
.plaintext = {
@@ -148,7 +158,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = { 0 },
+ .data = gcm_aad_zero_text,
.len = 0
},
.plaintext = {
@@ -186,7 +196,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = { 0 },
+ .data = gcm_aad_zero_text,
.len = 0
},
.plaintext = {
@@ -238,8 +248,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .data = gcm_aad_zero_text,
.len = 8
},
.plaintext = {
@@ -294,8 +303,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = {
- 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef },
+ .data = gcm_aad_text,
.len = 8
},
.plaintext = {
@@ -346,15 +354,11 @@ struct gmac_test_data {
.iv = {
.data = {
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
- 0xde, 0xca, 0xf8, 0x88
- },
+ 0xde, 0xca, 0xf8, 0x88 },
.len = 12
},
.aad = {
- .data = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- },
+ .data = gcm_aad_zero_text,
.len = 12
},
.plaintext = {
@@ -409,10 +413,7 @@ struct gmac_test_data {
.len = 12
},
.aad = {
- .data = {
- 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
- 0xfe, 0xed, 0xfa, 0xce
- },
+ .data = gcm_aad_text,
.len = 12
},
.plaintext = {
@@ -450,6 +451,450 @@ struct gmac_test_data {
}
};
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_1 = {
+ .key = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_zero_text,
+ .len = 0
+ },
+ .plaintext = {
+ .data = { 0x00 },
+ .len = 0
+ },
+ .ciphertext = {
+ .data = { 0x00 },
+ .len = 0
+ },
+ .auth_tag = {
+ .data = {
+ 0x53, 0x0F, 0x8A, 0xFB, 0xC7, 0x45, 0x36, 0xB9,
+ 0xA9, 0x63, 0xB4, 0xF1, 0xC4, 0xCB, 0x73, 0x8B },
+ .len = 16
+ }
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_2 = {
+ .key = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_zero_text,
+ .len = 0
+ },
+ .plaintext = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .len = 16
+ },
+ .ciphertext = {
+ .data = {
+ 0xCE, 0xA7, 0x40, 0x3D, 0x4D, 0x60, 0x6B, 0x6E,
+ 0x07, 0x4E, 0xC5, 0xD3, 0xBA, 0xF3, 0x9D, 0x18 },
+ .len = 16
+ },
+ .auth_tag = {
+ .data = {
+ 0xD0, 0xD1, 0xC8, 0xA7, 0x99, 0x99, 0x6B, 0xF0,
+ 0x26, 0x5B, 0x98, 0xB5, 0xD4, 0x8A, 0xB9, 0x19 },
+ .len = 16
+ }
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_3 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_zero_text,
+ .len = 0
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .len = 64
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E },
+ .len = 64
+ },
+ .auth_tag = {
+ .data = {
+ 0x64, 0xAF, 0x1D, 0xFB, 0xE8, 0x0D, 0x37, 0xD8,
+ 0x92, 0xC3, 0xB9, 0x1D, 0xD3, 0x08, 0xAB, 0xFC },
+ .len = 16
+ }
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_4 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_zero_text,
+ .len = 8
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .len = 60
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E },
+ .len = 60
+ },
+ .auth_tag = {
+ .data = {
+ 0x63, 0x16, 0x91, 0xAE, 0x17, 0x05, 0x5E, 0xA6,
+ 0x6D, 0x0A, 0x51, 0xE2, 0x50, 0x21, 0x85, 0x4A },
+ .len = 16
+ }
+
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_5 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_text,
+ .len = 8
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .len = 60
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E },
+ .len = 60
+ },
+ .auth_tag = {
+ .data = {
+ 0xA7, 0x99, 0xAC, 0xB8, 0x27, 0xDA, 0xB1, 0x82,
+ 0x79, 0xFD, 0x83, 0x73, 0x52, 0x4D, 0xDB, 0xF1 },
+ .len = 16
+ }
+
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_6 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_zero_text,
+ .len = 12
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .len = 60
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E },
+ .len = 60
+ },
+ .auth_tag = {
+ .data = {
+ 0x5D, 0xA5, 0x0E, 0x53, 0x64, 0x7F, 0x3F, 0xAE,
+ 0x1A, 0x1F, 0xC0, 0xB0, 0xD8, 0xBE, 0xF2, 0x64 },
+ .len = 16
+ }
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_7 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_text,
+ .len = 12
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .len = 60
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E },
+ .len = 60
+ },
+ .auth_tag = {
+ .data = {
+ 0x4E, 0xD0, 0x91, 0x95, 0x83, 0xA9, 0x38, 0x72,
+ 0x09, 0xA9, 0xCE, 0x5F, 0x89, 0x06, 0x4E, 0xC8 },
+ .len = 16
+ }
+};
+
+/** variable AAD AES-128 Test Vectors */
+static const struct gcm_test_data gcm_test_case_aad_1 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .len = 16
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_text,
+ .len = GMC_LARGE_AAD_LENGTH
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .len = 64
+ },
+ .ciphertext = {
+ .data = {
+ 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24,
+ 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C,
+ 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0,
+ 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E,
+ 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C,
+ 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05,
+ 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97,
+ 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85
+ },
+ .len = 64
+ },
+ .auth_tag = {
+ .data = {
+ 0xCA, 0x70, 0xAF, 0x96, 0xA8, 0x5D, 0x40, 0x47,
+ 0x0C, 0x3C, 0x48, 0xF5, 0xF0, 0xF5, 0xA5, 0x7D
+ },
+ .len = 16
+ }
+};
+
+/** variable AAD AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_aad_2 = {
+ .key = {
+ .data = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+ .len = 32
+ },
+ .iv = {
+ .data = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .len = 12
+ },
+ .aad = {
+ .data = gcm_aad_text,
+ .len = GMC_LARGE_AAD_LENGTH
+ },
+ .plaintext = {
+ .data = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .len = 64
+ },
+ .ciphertext = {
+ .data = {
+ 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+ 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+ 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+ 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+ 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+ 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+ 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+ 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E
+ },
+ .len = 64
+ },
+ .auth_tag = {
+ .data = {
+ 0xBA, 0x06, 0xDA, 0xA1, 0x91, 0xE1, 0xFE, 0x22,
+ 0x59, 0xDA, 0x67, 0xAF, 0x9D, 0xA5, 0x43, 0x94
+ },
+ .len = 16
+ }
+};
+
/** GMAC Test Vectors */
static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -1228,8 +1673,8 @@ struct cryptodev_perf_test_data {
},
.gmac_tag = {
.data = {
- 0x88, 0x82, 0xb4, 0x93, 0x8f, 0x04, 0xcd, 0x06,
- 0xfd, 0xac, 0x6d, 0x8b, 0x9c, 0x9e, 0x8f, 0xec
+ 0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2,
+ 0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda
},
.len = 16
}
diff --git a/doc/guides/cryptodevs/aesni_gcm.rst b/doc/guides/cryptodevs/aesni_gcm.rst
index 04bf43c..184b71c 100644
--- a/doc/guides/cryptodevs/aesni_gcm.rst
+++ b/doc/guides/cryptodevs/aesni_gcm.rst
@@ -32,10 +32,8 @@ AES-NI GCM Crypto Poll Mode Driver
The AES-NI GCM PMD (**librte_pmd_aesni_gcm**) provides poll mode crypto driver
-support for utilizing Intel multi buffer library (see AES-NI Multi-buffer PMD documentation
-to learn more about it, including installation).
-
-The AES-NI GCM PMD has current only been tested on Fedora 21 64-bit with gcc.
+support for utilizing Intel ISA-L crypto library, which provides operation acceleration
+through the AES-NI instruction sets for AES-GCM authenticated cipher algorithm.
Features
--------
@@ -49,16 +47,21 @@ Cipher algorithms:
Authentication algorithms:
* RTE_CRYPTO_AUTH_AES_GCM
+* RTE_CRYPTO_AUTH_AES_GMAC
+
+Installation
+------------
+
+To build DPDK with the AESNI_GCM_PMD the user is required to install
+the ``libisal_crypto`` library in the build environment.
+For download and more details please visit `<https://github.com/01org/isa-l_crypto>`_.
Initialization
--------------
In order to enable this virtual crypto PMD, user must:
-* Export the environmental variable AESNI_MULTI_BUFFER_LIB_PATH with the path where
- the library was extracted.
-
-* Build the multi buffer library (go to Installation section in AES-NI MB PMD documentation).
+* Install the ISA-L crypto library (explained in Installation section).
* Set CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=y in config/common_base.
@@ -86,9 +89,7 @@ Example:
Limitations
-----------
-* Chained mbufs are not supported.
+* Chained mbufs are supported but only out-of-place (destination mbuf must be contiguous).
* Hash only is not supported.
* Cipher only is not supported.
-* Only in-place is currently supported (destination address is the same as source address).
-* Only supports session-oriented API implementation (session-less APIs are not supported).
* Not performance tuned.
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 3b65038..a253f0b 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -39,6 +39,19 @@ New Features
=========================================================
+* **Updated the AES-NI GCM PMD.**
+
+ The AES-NI GCM PMD was migrated from MB library to ISA-L library.
+ The migration entailed the following additional support for:
+
+ * GMAC algorithm.
+ * 256-bit cipher key.
+ * Session-less mode.
+ * Out-of place processing
+ * Scatter-gatter support for chained mbufs (only out-of place and destination
+ mbuf must be contiguous)
+
+
Resolved Issues
---------------
diff --git a/drivers/crypto/aesni_gcm/Makefile b/drivers/crypto/aesni_gcm/Makefile
index 5898cae..fb17fbf 100644
--- a/drivers/crypto/aesni_gcm/Makefile
+++ b/drivers/crypto/aesni_gcm/Makefile
@@ -31,9 +31,6 @@
include $(RTE_SDK)/mk/rte.vars.mk
ifneq ($(MAKECMDGOALS),clean)
-ifeq ($(AESNI_MULTI_BUFFER_LIB_PATH),)
-$(error "Please define AESNI_MULTI_BUFFER_LIB_PATH environment variable")
-endif
endif
# library name
@@ -50,10 +47,7 @@ LIBABIVER := 1
EXPORT_MAP := rte_pmd_aesni_gcm_version.map
# external library dependencies
-CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)
-CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)/include
-LDLIBS += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
-LDLIBS += -lcrypto
+LDLIBS += -lisal_crypto
# library source files
SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm_pmd.c
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_ops.h b/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
index c399068..e9de654 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
@@ -37,91 +37,26 @@
#define LINUX
#endif
-#include <gcm_defines.h>
-#include <aux_funcs.h>
+#include <isa-l_crypto/aes_gcm.h>
-/** Supported vector modes */
-enum aesni_gcm_vector_mode {
- RTE_AESNI_GCM_NOT_SUPPORTED = 0,
- RTE_AESNI_GCM_SSE,
- RTE_AESNI_GCM_AVX,
- RTE_AESNI_GCM_AVX2
-};
-
-typedef void (*aes_keyexp_128_enc_t)(void *key, void *enc_exp_keys);
+typedef void (*aesni_gcm_init_t)(struct gcm_data *my_ctx_data,
+ uint8_t *iv,
+ uint8_t const *aad,
+ uint64_t aad_len);
-typedef void (*aesni_gcm_t)(gcm_data *my_ctx_data, u8 *out, const u8 *in,
- u64 plaintext_len, u8 *iv, const u8 *aad, u64 aad_len,
- u8 *auth_tag, u64 auth_tag_len);
+typedef void (*aesni_gcm_update_t)(struct gcm_data *my_ctx_data,
+ uint8_t *out,
+ const uint8_t *in,
+ uint64_t plaintext_len);
-typedef void (*aesni_gcm_precomp_t)(gcm_data *my_ctx_data, u8 *hash_subkey);
+typedef void (*aesni_gcm_finalize_t)(struct gcm_data *my_ctx_data,
+ uint8_t *auth_tag,
+ uint64_t auth_tag_len);
-/** GCM library function pointer table */
struct aesni_gcm_ops {
- struct {
- struct {
- aes_keyexp_128_enc_t aes128_enc;
- /**< AES128 enc key expansion */
- } keyexp;
- /**< Key expansion functions */
- } aux; /**< Auxiliary functions */
-
- struct {
- aesni_gcm_t enc; /**< GCM encode function pointer */
- aesni_gcm_t dec; /**< GCM decode function pointer */
- aesni_gcm_precomp_t precomp; /**< GCM pre-compute */
- } gcm; /**< GCM functions */
+ aesni_gcm_init_t init;
+ aesni_gcm_update_t update;
+ aesni_gcm_finalize_t finalize;
};
-
-static const struct aesni_gcm_ops gcm_ops[] = {
- [RTE_AESNI_GCM_NOT_SUPPORTED] = {
- .aux = {
- .keyexp = {
- NULL
- }
- },
- .gcm = {
- NULL
- }
- },
- [RTE_AESNI_GCM_SSE] = {
- .aux = {
- .keyexp = {
- aes_keyexp_128_enc_sse
- }
- },
- .gcm = {
- aesni_gcm_enc_sse,
- aesni_gcm_dec_sse,
- aesni_gcm_precomp_sse
- }
- },
- [RTE_AESNI_GCM_AVX] = {
- .aux = {
- .keyexp = {
- aes_keyexp_128_enc_avx,
- }
- },
- .gcm = {
- aesni_gcm_enc_avx_gen2,
- aesni_gcm_dec_avx_gen2,
- aesni_gcm_precomp_avx_gen2
- }
- },
- [RTE_AESNI_GCM_AVX2] = {
- .aux = {
- .keyexp = {
- aes_keyexp_128_enc_avx2,
- }
- },
- .gcm = {
- aesni_gcm_enc_avx_gen4,
- aesni_gcm_dec_avx_gen4,
- aesni_gcm_precomp_avx_gen4
- }
- }
-};
-
-
#endif /* _AESNI_GCM_OPS_H_ */
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index dba5e15..31d7e35 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -30,8 +30,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <openssl/aes.h>
-
#include <rte_common.h>
#include <rte_config.h>
#include <rte_hexdump.h>
@@ -43,6 +41,34 @@
#include "aesni_gcm_pmd_private.h"
+/** GCM encode functions pointer table */
+static const struct aesni_gcm_ops aesni_gcm_enc[] = {
+ [AESNI_GCM_KEY_128] = {
+ aesni_gcm128_init,
+ aesni_gcm128_enc_update,
+ aesni_gcm128_enc_finalize
+ },
+ [AESNI_GCM_KEY_256] = {
+ aesni_gcm256_init,
+ aesni_gcm256_enc_update,
+ aesni_gcm256_enc_finalize
+ }
+};
+
+/** GCM decode functions pointer table */
+static const struct aesni_gcm_ops aesni_gcm_dec[] = {
+ [AESNI_GCM_KEY_128] = {
+ aesni_gcm128_init,
+ aesni_gcm128_dec_update,
+ aesni_gcm128_dec_finalize
+ },
+ [AESNI_GCM_KEY_256] = {
+ aesni_gcm256_init,
+ aesni_gcm256_dec_update,
+ aesni_gcm256_dec_finalize
+ }
+};
+
/**
* Global static parameter used to create a unique name for each AES-NI multi
* buffer crypto device.
@@ -64,112 +90,68 @@
return 0;
}
-static int
-aesni_gcm_calculate_hash_sub_key(uint8_t *hsubkey, unsigned hsubkey_length,
- uint8_t *aeskey, unsigned aeskey_length)
-{
- uint8_t key[aeskey_length] __rte_aligned(16);
- AES_KEY enc_key;
-
- if (hsubkey_length % 16 != 0 && aeskey_length % 16 != 0)
- return -EFAULT;
-
- memcpy(key, aeskey, aeskey_length);
-
- if (AES_set_encrypt_key(key, aeskey_length << 3, &enc_key) != 0)
- return -EFAULT;
-
- AES_encrypt(hsubkey, hsubkey, &enc_key);
-
- return 0;
-}
-
-/** Get xform chain order */
-static int
-aesni_gcm_get_mode(const struct rte_crypto_sym_xform *xform)
-{
- /*
- * GCM only supports authenticated encryption or authenticated
- * decryption, all other options are invalid, so we must have exactly
- * 2 xform structs chained together
- */
- if (xform->next == NULL || xform->next->next != NULL)
- return -1;
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
- xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
- return AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
- }
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
- xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
- return AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
- }
-
- return -1;
-}
-
/** Parse crypto xform chain and set private session parameters */
int
-aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops,
- struct aesni_gcm_session *sess,
+aesni_gcm_set_session_parameters(struct aesni_gcm_session *sess,
const struct rte_crypto_sym_xform *xform)
{
- const struct rte_crypto_sym_xform *auth_xform = NULL;
- const struct rte_crypto_sym_xform *cipher_xform = NULL;
-
- uint8_t hsubkey[16] __rte_aligned(16) = { 0 };
+ const struct rte_crypto_sym_xform *auth_xform;
+ const struct rte_crypto_sym_xform *cipher_xform;
- /* Select Crypto operation - hash then cipher / cipher then hash */
- switch (aesni_gcm_get_mode(xform)) {
- case AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION:
- sess->op = AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
+ if (xform->next == NULL || xform->next->next != NULL) {
+ GCM_LOG_ERR("Two and only two chained xform required");
+ return -EINVAL;
+ }
- cipher_xform = xform;
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+ xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
auth_xform = xform->next;
- break;
- case AESNI_GCM_OP_AUTHENTICATED_DECRYPTION:
- sess->op = AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
-
+ cipher_xform = xform;
+ } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+ xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
auth_xform = xform;
cipher_xform = xform->next;
- break;
- default:
- GCM_LOG_ERR("Unsupported operation chain order parameter");
+ } else {
+ GCM_LOG_ERR("Cipher and auth xform required");
return -EINVAL;
}
- /* We only support AES GCM */
- if (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM &&
- auth_xform->auth.algo != RTE_CRYPTO_AUTH_AES_GCM)
+ if (!(cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_GCM &&
+ (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GCM ||
+ auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC))) {
+ GCM_LOG_ERR("We only support AES GCM and AES GMAC");
return -EINVAL;
+ }
- /* Select cipher direction */
- if (sess->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION &&
- cipher_xform->cipher.op !=
- RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
- GCM_LOG_ERR("xform chain (CIPHER/AUTH) and cipher operation "
- "(DECRYPT) specified are an invalid selection");
- return -EINVAL;
- } else if (sess->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION &&
- cipher_xform->cipher.op !=
- RTE_CRYPTO_CIPHER_OP_DECRYPT) {
- GCM_LOG_ERR("xform chain (AUTH/CIPHER) and cipher operation "
- "(ENCRYPT) specified are an invalid selection");
+ /* Select Crypto operation */
+ if (cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
+ auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE)
+ sess->op = AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
+ else if (cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
+ auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+ sess->op = AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
+ else {
+ GCM_LOG_ERR("Cipher/Auth operations: Encrypt/Generate or"
+ " Decrypt/Verify are valid only");
return -EINVAL;
}
- /* Expand GCM AES128 key */
- (*gcm_ops->aux.keyexp.aes128_enc)(cipher_xform->cipher.key.data,
- sess->gdata.expanded_keys);
+ /* Check key length and calculate GCM pre-compute. */
+ switch (cipher_xform->cipher.key.length) {
+ case 16:
+ aesni_gcm128_pre(cipher_xform->cipher.key.data, &sess->gdata);
+ sess->key = AESNI_GCM_KEY_128;
- /* Calculate hash sub key here */
- aesni_gcm_calculate_hash_sub_key(hsubkey, sizeof(hsubkey),
- cipher_xform->cipher.key.data,
- cipher_xform->cipher.key.length);
+ break;
+ case 32:
+ aesni_gcm256_pre(cipher_xform->cipher.key.data, &sess->gdata);
+ sess->key = AESNI_GCM_KEY_256;
- /* Calculate GCM pre-compute */
- (*gcm_ops->gcm.precomp)(&sess->gdata, hsubkey);
+ break;
+ default:
+ GCM_LOG_ERR("Unsupported cipher key length");
+ return -EINVAL;
+ }
return 0;
}
@@ -193,10 +175,10 @@
return sess;
sess = (struct aesni_gcm_session *)
- ((struct rte_cryptodev_session *)_sess)->_private;
+ ((struct rte_cryptodev_sym_session *)_sess)->_private;
- if (unlikely(aesni_gcm_set_session_parameters(qp->ops,
- sess, op->xform) != 0)) {
+ if (unlikely(aesni_gcm_set_session_parameters(sess,
+ op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
sess = NULL;
}
@@ -216,19 +198,45 @@
*
*/
static int
-process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_sym_op *op,
+process_gcm_crypto_op(struct rte_crypto_sym_op *op,
struct aesni_gcm_session *session)
{
uint8_t *src, *dst;
- struct rte_mbuf *m = op->m_src;
+ struct rte_mbuf *m_src = op->m_src;
+ uint32_t offset = op->cipher.data.offset;
+ uint32_t part_len, total_len, data_len;
+
+ RTE_ASSERT(m_src != NULL);
+
+ while (offset >= m_src->data_len) {
+ offset -= m_src->data_len;
+ m_src = m_src->next;
+
+ RTE_ASSERT(m_src != NULL);
+ }
+
+ data_len = m_src->data_len - offset;
+ part_len = (data_len < op->cipher.data.length) ? data_len :
+ op->cipher.data.length;
+
+ /* Destination buffer is required when segmented source buffer */
+ RTE_ASSERT((part_len == op->cipher.data.length) ||
+ ((part_len != op->cipher.data.length) &&
+ (op->m_dst != NULL)));
+ /* Segmented destination buffer is not supported */
+ RTE_ASSERT((op->m_dst == NULL) ||
+ ((op->m_dst != NULL) &&
+ rte_pktmbuf_is_contiguous(op->m_dst)));
+
- src = rte_pktmbuf_mtod(m, uint8_t *) + op->cipher.data.offset;
dst = op->m_dst ?
rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *,
op->cipher.data.offset) :
- rte_pktmbuf_mtod_offset(m, uint8_t *,
+ rte_pktmbuf_mtod_offset(op->m_src, uint8_t *,
op->cipher.data.offset);
+ src = rte_pktmbuf_mtod_offset(m_src, uint8_t *, offset);
+
/* sanity checks */
if (op->cipher.iv.length != 16 && op->cipher.iv.length != 12 &&
op->cipher.iv.length != 0) {
@@ -244,48 +252,81 @@
op->cipher.iv.data[15] = 1;
}
- if (op->auth.aad.length != 12 && op->auth.aad.length != 8 &&
- op->auth.aad.length != 0) {
- GCM_LOG_ERR("iv");
- return -1;
- }
-
if (op->auth.digest.length != 16 &&
op->auth.digest.length != 12 &&
- op->auth.digest.length != 8 &&
- op->auth.digest.length != 0) {
- GCM_LOG_ERR("iv");
+ op->auth.digest.length != 8) {
+ GCM_LOG_ERR("digest");
return -1;
}
if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) {
- (*qp->ops->gcm.enc)(&session->gdata, dst, src,
- (uint64_t)op->cipher.data.length,
+ aesni_gcm_enc[session->key].init(&session->gdata,
op->cipher.iv.data,
op->auth.aad.data,
- (uint64_t)op->auth.aad.length,
+ (uint64_t)op->auth.aad.length);
+
+ aesni_gcm_enc[session->key].update(&session->gdata, dst, src,
+ (uint64_t)part_len);
+ total_len = op->cipher.data.length - part_len;
+
+ while (total_len) {
+ dst += part_len;
+ m_src = m_src->next;
+
+ RTE_ASSERT(m_src != NULL);
+
+ src = rte_pktmbuf_mtod(m_src, uint8_t *);
+ part_len = (m_src->data_len < total_len) ?
+ m_src->data_len : total_len;
+
+ aesni_gcm_enc[session->key].update(&session->gdata,
+ dst, src,
+ (uint64_t)part_len);
+ total_len -= part_len;
+ }
+
+ aesni_gcm_enc[session->key].finalize(&session->gdata,
op->auth.digest.data,
(uint64_t)op->auth.digest.length);
- } else if (session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) {
- uint8_t *auth_tag = (uint8_t *)rte_pktmbuf_append(m,
+ } else { /* session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION */
+ uint8_t *auth_tag = (uint8_t *)rte_pktmbuf_append(op->m_dst ?
+ op->m_dst : op->m_src,
op->auth.digest.length);
if (!auth_tag) {
- GCM_LOG_ERR("iv");
+ GCM_LOG_ERR("auth_tag");
return -1;
}
- (*qp->ops->gcm.dec)(&session->gdata, dst, src,
- (uint64_t)op->cipher.data.length,
+ aesni_gcm_dec[session->key].init(&session->gdata,
op->cipher.iv.data,
op->auth.aad.data,
- (uint64_t)op->auth.aad.length,
+ (uint64_t)op->auth.aad.length);
+
+ aesni_gcm_dec[session->key].update(&session->gdata, dst, src,
+ (uint64_t)part_len);
+ total_len = op->cipher.data.length - part_len;
+
+ while (total_len) {
+ dst += part_len;
+ m_src = m_src->next;
+
+ RTE_ASSERT(m_src != NULL);
+
+ src = rte_pktmbuf_mtod(m_src, uint8_t *);
+ part_len = (m_src->data_len < total_len) ?
+ m_src->data_len : total_len;
+
+ aesni_gcm_dec[session->key].update(&session->gdata,
+ dst, src,
+ (uint64_t)part_len);
+ total_len -= part_len;
+ }
+
+ aesni_gcm_dec[session->key].finalize(&session->gdata,
auth_tag,
(uint64_t)op->auth.digest.length);
- } else {
- GCM_LOG_ERR("iv");
- return -1;
}
return 0;
@@ -375,7 +416,7 @@
break;
}
- retval = process_gcm_crypto_op(qp, ops[i]->sym, sess);
+ retval = process_gcm_crypto_op(ops[i]->sym, sess);
if (retval < 0) {
ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
qp->qp_stats.enqueue_err_count++;
@@ -413,7 +454,6 @@
struct rte_cryptodev *dev;
char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
struct aesni_gcm_private *internals;
- enum aesni_gcm_vector_mode vector_mode;
/* Check CPU for support for AES instruction set */
if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) {
@@ -421,18 +461,6 @@
return -EFAULT;
}
- /* Check CPU for supported vector instruction set */
- if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2))
- vector_mode = RTE_AESNI_GCM_AVX2;
- else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX))
- vector_mode = RTE_AESNI_GCM_AVX;
- else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1))
- vector_mode = RTE_AESNI_GCM_SSE;
- else {
- GCM_LOG_ERR("Vector instructions are not supported by CPU");
- return -EFAULT;
- }
-
/* create a unique device name */
if (create_unique_device_name(crypto_dev_name,
RTE_CRYPTODEV_NAME_MAX_LEN) != 0) {
@@ -459,25 +487,8 @@
RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
RTE_CRYPTODEV_FF_CPU_AESNI;
- switch (vector_mode) {
- case RTE_AESNI_GCM_SSE:
- dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_SSE;
- break;
- case RTE_AESNI_GCM_AVX:
- dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX;
- break;
- case RTE_AESNI_GCM_AVX2:
- dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX2;
- break;
- default:
- break;
- }
-
- /* Set vector instructions mode supported */
internals = dev->data->dev_private;
- internals->vector_mode = vector_mode;
-
internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
internals->max_nb_sessions = init_params->max_nb_sessions;
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index e824d4b..899ef28 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -39,17 +39,17 @@
#include "aesni_gcm_pmd_private.h"
static const struct rte_cryptodev_capabilities aesni_gcm_pmd_capabilities[] = {
- { /* AES GCM (AUTH) */
+ { /* AES GMAC (AUTH) */
.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
{.sym = {
.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
{.auth = {
- .algo = RTE_CRYPTO_AUTH_AES_GCM,
+ .algo = RTE_CRYPTO_AUTH_AES_GMAC,
.block_size = 16,
.key_size = {
.min = 16,
- .max = 16,
- .increment = 0
+ .max = 32,
+ .increment = 16
},
.digest_size = {
.min = 8,
@@ -57,9 +57,34 @@
.increment = 4
},
.aad_size = {
+ .min = 0,
+ .max = 65535,
+ .increment = 1
+ }
+ }, }
+ }, }
+ },
+ { /* AES GCM (AUTH) */
+ .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+ {.sym = {
+ .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+ {.auth = {
+ .algo = RTE_CRYPTO_AUTH_AES_GCM,
+ .block_size = 16,
+ .key_size = {
+ .min = 16,
+ .max = 32,
+ .increment = 16
+ },
+ .digest_size = {
.min = 8,
- .max = 12,
+ .max = 16,
.increment = 4
+ },
+ .aad_size = {
+ .min = 0,
+ .max = 65535,
+ .increment = 1
}
}, }
}, }
@@ -73,8 +98,8 @@
.block_size = 16,
.key_size = {
.min = 16,
- .max = 16,
- .increment = 0
+ .max = 32,
+ .increment = 16
},
.iv_size = {
.min = 16,
@@ -221,7 +246,6 @@
int socket_id)
{
struct aesni_gcm_qp *qp = NULL;
- struct aesni_gcm_private *internals = dev->data->dev_private;
/* Free memory prior to re-allocation if needed. */
if (dev->data->queue_pairs[qp_id] != NULL)
@@ -239,8 +263,6 @@
if (aesni_gcm_pmd_qp_set_unique_name(dev, qp))
goto qp_setup_cleanup;
- qp->ops = &gcm_ops[internals->vector_mode];
-
qp->processed_pkts = aesni_gcm_pmd_qp_create_processed_pkts_ring(qp,
qp_conf->nb_descriptors, socket_id);
if (qp->processed_pkts == NULL)
@@ -291,18 +313,15 @@
/** Configure a aesni gcm session from a crypto xform chain */
static void *
-aesni_gcm_pmd_session_configure(struct rte_cryptodev *dev,
+aesni_gcm_pmd_session_configure(struct rte_cryptodev *dev __rte_unused,
struct rte_crypto_sym_xform *xform, void *sess)
{
- struct aesni_gcm_private *internals = dev->data->dev_private;
-
if (unlikely(sess == NULL)) {
GCM_LOG_ERR("invalid session struct");
return NULL;
}
- if (aesni_gcm_set_session_parameters(&gcm_ops[internals->vector_mode],
- sess, xform) != 0) {
+ if (aesni_gcm_set_session_parameters(sess, xform) != 0) {
GCM_LOG_ERR("failed configure session parameters");
return NULL;
}
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 9878d6e..0496b44 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -58,8 +58,6 @@
/** private data structure for each virtual AESNI GCM device */
struct aesni_gcm_private {
- enum aesni_gcm_vector_mode vector_mode;
- /**< Vector mode */
unsigned max_nb_queue_pairs;
/**< Max number of queue pairs supported by device */
unsigned max_nb_sessions;
@@ -71,8 +69,6 @@ struct aesni_gcm_qp {
/**< Queue Pair Identifier */
char name[RTE_CRYPTODEV_NAME_LEN];
/**< Unique Queue Pair Name */
- const struct aesni_gcm_ops *ops;
- /**< Architecture dependent function pointer table of the gcm APIs */
struct rte_ring *processed_pkts;
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
@@ -87,10 +83,17 @@ enum aesni_gcm_operation {
AESNI_GCM_OP_AUTHENTICATED_DECRYPTION
};
+enum aesni_gcm_key {
+ AESNI_GCM_KEY_128,
+ AESNI_GCM_KEY_256
+};
+
/** AESNI GCM private session structure */
struct aesni_gcm_session {
enum aesni_gcm_operation op;
/**< GCM operation type */
+ enum aesni_gcm_key key;
+ /**< GCM key type */
struct gcm_data gdata __rte_cache_aligned;
/**< GCM parameters */
};
@@ -98,7 +101,6 @@ struct aesni_gcm_session {
/**
* Setup GCM session parameters
- * @param ops gcm ops function pointer table
* @param sess aesni gcm session structure
* @param xform crypto transform chain
*
@@ -107,8 +109,7 @@ struct aesni_gcm_session {
* - On failure returns error code < 0
*/
extern int
-aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *ops,
- struct aesni_gcm_session *sess,
+aesni_gcm_set_session_parameters(struct aesni_gcm_session *sess,
const struct rte_crypto_sym_xform *xform);
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e2..ed3eab5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -134,8 +134,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lisal_crypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += -lrte_pmd_openssl -lcrypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v3 0/6] Add MACsec offload support for ixgbe
From: Tiwei Bie @ 2016-12-27 17:42 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: dev, wenzhuo.lu, wei.dai, xiao.w.wang, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang
In-Reply-To: <20161227143746.GC3737@6wind.com>
Hi Adrien,
On Tue, Dec 27, 2016 at 03:37:46PM +0100, Adrien Mazarguil wrote:
> Hi Tiwei,
>
> On Tue, Dec 27, 2016 at 09:33:31AM +0800, Tiwei Bie wrote:
> > Hi Adrien,
> >
> > On Mon, Dec 26, 2016 at 04:15:37PM +0100, Adrien Mazarguil wrote:
> > > Hi Tiwei,
> > >
> > > On Sun, Dec 25, 2016 at 10:57:54PM +0800, Tiwei Bie wrote:
> > > > This patch set adds the MACsec offload support for ixgbe.
> > > > The testpmd is also updated to support MACsec cmds.
[...]
> > > - Why can't the MACsec API be defined globally, for instance won't i40e
> > > implement it as well someday?
> >
> > I think currently we prefer to implement some PMD features based on the
> > PMD-specific APIs at first to avoid the bloating of the ethdev APIs. And
> > when it proves to be generic (which means many people really need it and
> > care about it, and more drivers are really going to implement it), then
> > we make it as the global ethdev API.
>
> Understandable, but then unless the global API remains exactly the same
> including the "rte_ixgbe_macsec" prefix (which I think won't happen),
> applications need to be rewritten, it's not convenient, and as a result may
> prevent adoption due to the following cycle:
>
> - Applications wait for the API to evolve before using MACsec.
> - DPDK waits for applications to use the ixgbe MACsec API to improve it.
>
Yeah, I also saw these problems. And I also don't think this is a
perfect way. But it seems that many of us prefer this way, so I just
choose to accept it.
> In the end, flags tied to a single PMD remain allocated in the global
> namespace while the API is kept in this temporary state forever.
>
> I think doing the extra work to make it global from the start is worth the
> trouble. This step could perhaps be made easier if people agreed that
> struct eth_dev_ops (and friends) must be opaque to applications.
>
[...]
>
> > > Assuming these patches are kept as-is, I suggest we define a reserved space
> > > documented as such for PMD-specific flags wherever they are used.
> > >
> >
> > It sounds good to me. But it may involve many pieces of the lib, such
> > as the mbuf ol_flags, ethdev event type, ethdev offload capabilities,
> > and so on. So maybe it can be done as another work.
>
> Right, that was just an idea from the top of my head, we could define
> reserved values only when they become necessary for a PMD as in this case,
> e.g. instead of defining PKT_TX_MACSEC, one would define PKT_TX_RESERVED_0
> which would be interpreted as MACSEC by ixgbe until this API is exposed
> globally.
>
> Other PMDs could implement other unrelated PMD-specific APIs through
> RESERVED_0 in the meantime, so we preserve the precious space we have
> for global APIs (especially inside mbufs).
>
> Thoughts?
>
When a certain PMD implemented several different features based on
the PMD-specific API, and many of them need to define some flags in
mbuf or the like, it still needs to waste many bits (i.e. we'll need
to reserve many bits by that time). But any way, I love your idea!
It's much better than the current approach! I'll update my patch.
Thank you very much! ;-)
Best regards,
Tiwei Bie
^ permalink raw reply
* DPDK Acceleartion Enhancement - compression
From: Ant loves honey @ 2016-12-27 16:08 UTC (permalink / raw)
To: Dev
In-Reply-To: <1815632810.2503307.1482854884965.ref@mail.yahoo.com>
Is this the correct forum to ask question about adding code for DPDK Acceleration Enhancement? Or this is strictly for code review? If so, please direct me to the correct forum.
I have already read these 2 documents:
- http://dpdk.org/doc/guides/ cryptodevs/qat.html
- http://dpdk.org/doc/guides/ sample_app_ug/intel_ quickassist.html
I am new to DPDK and would like to do some work but is hitting a road block. I am interested in making DPDK able to to use the Intel QuickAssist Technology for data compression. I think this will help IP payload compression and save bandwidth.
Any help to get me going is greatly appreciated.
Anthony.
^ permalink raw reply
* Re: [PATCH v3 0/6] Add MACsec offload support for ixgbe
From: Adrien Mazarguil @ 2016-12-27 14:37 UTC (permalink / raw)
To: Tiwei Bie
Cc: dev, wenzhuo.lu, wei.dai, xiao.w.wang, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang
In-Reply-To: <20161227013330.GA145018@dpdk19>
Hi Tiwei,
On Tue, Dec 27, 2016 at 09:33:31AM +0800, Tiwei Bie wrote:
> Hi Adrien,
>
> On Mon, Dec 26, 2016 at 04:15:37PM +0100, Adrien Mazarguil wrote:
> > Hi Tiwei,
> >
> > On Sun, Dec 25, 2016 at 10:57:54PM +0800, Tiwei Bie wrote:
> > > This patch set adds the MACsec offload support for ixgbe.
> > > The testpmd is also updated to support MACsec cmds.
> >
> > I'm not commenting on any specific patch from this series, however I'm
> > noticing this new trend of working around ethdev to add PMD-specific APIs.
> > I would like to make sure it's not getting out of hand.
> >
> > To use the "rte_pmd_ixgbe_macsec_*()" API, applications must be linked with
> > librte_pmd_ixgbe directly and have the related code under #ifdef
> > RTE_LIBRTE_IXGBE_PMD like testpmd.
> >
> > Here we can see this ixgbe-specific API affects rte_mbuf.h and rte_ethdev.h
> > (new PKT_TX_MACSEC, RTE_ETH_EVENT_MACSEC, DEV_RX_OFFLOAD_MACSEC_STRIP and
> > DEV_TX_OFFLOAD_MACSEC_INSERT flags).
> >
> > - Shouldn't these flags have "IXGBE" somewhere in their name and/or be
> > defined under #ifdef RTE_LIBRTE_IXGBE_PMD?
> >
>
> I think those flags are very generic, simple and innocent, so we could just
> define them in the normal way. And currently it seems that we lack a way to
> define the PMD-specific flags for mbuf, ethdev, etc.
Yes, this is probably the least intrusive approach. I'm just pointing out
that in the meantime, assigned values are not available for other generic
uses which is a problem unless there is a plan to make this API available
globally.
Missing flags and bits could also be defined directly by rte_pmd_ixgbe.h.
> > - Why can't the MACsec API be defined globally, for instance won't i40e
> > implement it as well someday?
>
> I think currently we prefer to implement some PMD features based on the
> PMD-specific APIs at first to avoid the bloating of the ethdev APIs. And
> when it proves to be generic (which means many people really need it and
> care about it, and more drivers are really going to implement it), then
> we make it as the global ethdev API.
Understandable, but then unless the global API remains exactly the same
including the "rte_ixgbe_macsec" prefix (which I think won't happen),
applications need to be rewritten, it's not convenient, and as a result may
prevent adoption due to the following cycle:
- Applications wait for the API to evolve before using MACsec.
- DPDK waits for applications to use the ixgbe MACsec API to improve it.
In the end, flags tied to a single PMD remain allocated in the global
namespace while the API is kept in this temporary state forever.
I think doing the extra work to make it global from the start is worth the
trouble. This step could perhaps be made easier if people agreed that
struct eth_dev_ops (and friends) must be opaque to applications.
> > - Why bothering with TX/RX offload capabilities if applications know the
> > underlying PMD anyway?
> >
>
> Not every NIC supported by IXGBE supports the MACsec offload. So even
> if the application knows it's using IXGBE PMD, it still needs to check
> whether the MACsec offload capabilities are supported.
OK, I assumed they all did.
> > Assuming these patches are kept as-is, I suggest we define a reserved space
> > documented as such for PMD-specific flags wherever they are used.
> >
>
> It sounds good to me. But it may involve many pieces of the lib, such
> as the mbuf ol_flags, ethdev event type, ethdev offload capabilities,
> and so on. So maybe it can be done as another work.
Right, that was just an idea from the top of my head, we could define
reserved values only when they become necessary for a PMD as in this case,
e.g. instead of defining PKT_TX_MACSEC, one would define PKT_TX_RESERVED_0
which would be interpreted as MACSEC by ixgbe until this API is exposed
globally.
Other PMDs could implement other unrelated PMD-specific APIs through
RESERVED_0 in the meantime, so we preserve the precious space we have
for global APIs (especially inside mbufs).
Thoughts?
Best regards,
--
Adrien Mazarguil
6WIND
^ permalink raw reply
* [PATCH v3] ethtool: dispaly bus info and firmware version
From: Qiming Yang @ 2016-12-27 13:06 UTC (permalink / raw)
To: dev, thomas.monjalon; +Cc: remy.horton, ferruh.yigit, Qiming Yang
In-Reply-To: <1481008582-69416-6-git-send-email-qiming.yang@intel.com>
This patch enhances the ethtool example to support to show
bus information and firmware version, in the same way that
the Linux kernel ethtool does.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
v3 changes:
* split this patch from the patch set of rte_eth_dev_fw_info_get
use the new version function.
---
---
examples/ethtool/ethtool-app/ethapp.c | 2 ++
examples/ethtool/lib/rte_ethtool.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethtool-app/ethapp.c
index 6aeaa06..192d941 100644
--- a/examples/ethtool/ethtool-app/ethapp.c
+++ b/examples/ethtool/ethtool-app/ethapp.c
@@ -185,6 +185,8 @@ pcmd_drvinfo_callback(__rte_unused void *ptr_params,
printf("Port %i driver: %s (ver: %s)\n",
id_port, info.driver, info.version
);
+ printf("bus-info: %s\n", info.bus_info);
+ printf("firmware-version: %s\n", info.fw_version);
}
}
diff --git a/examples/ethtool/lib/rte_ethtool.c b/examples/ethtool/lib/rte_ethtool.c
index 6f0ce84..f62f1d3 100644
--- a/examples/ethtool/lib/rte_ethtool.c
+++ b/examples/ethtool/lib/rte_ethtool.c
@@ -54,6 +54,11 @@ rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ uint32_t fw_major = 0;
+ uint32_t fw_minor = 0;
+ uint32_t etrack = 0;
+
+ rte_eth_dev_fw_info_get(port_id, &fw_major, &fw_minor, NULL, &etrack);
memset(&dev_info, 0, sizeof(dev_info));
rte_eth_dev_info_get(port_id, &dev_info);
@@ -61,6 +66,12 @@ rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
dev_info.driver_name);
snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
rte_version());
+ if (strcmp(drvinfo->driver, "net_ixgbe") == 0)
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+ "0x%08x", etrack);
+ else
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+ "%d.%02d 0x%08x", fw_major, fw_minor, etrack);
if (dev_info.pci_dev)
snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
"%04x:%02x:%02x.%x",
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2 15/17] net/i40e: add flow flush function
From: Adrien Mazarguil @ 2016-12-27 12:40 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-16-git-send-email-beilei.xing@intel.com>
Hi Beilei,
On Tue, Dec 27, 2016 at 02:26:22PM +0800, Beilei Xing wrote:
> This patch adds i40e_flow_flush function to flush all
> filters for users. And flow director flush function
> is involved first.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.h | 3 +++
> drivers/net/i40e/i40e_fdir.c | 8 ++------
> drivers/net/i40e/i40e_flow.c | 46 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 51 insertions(+), 6 deletions(-)
[...]
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
[...]
> +static int
> +i40e_fdir_filter_flush(struct i40e_pf *pf)
> +{
> + struct rte_eth_dev *dev = pf->adapter->eth_dev;
> + struct i40e_fdir_info *fdir_info = &pf->fdir;
> + struct i40e_fdir_filter *fdir_filter;
> + struct i40e_flow *flow;
> + int ret = 0;
> +
> + ret = i40e_fdir_flush(dev);
> + if (!ret) {
> + /* Delete FDIR filters in FDIR list. */
> + while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list)))
> + i40e_sw_fdir_filter_del(pf, fdir_filter);
> +
> + /* Delete FDIR flows in flow list. */
> + TAILQ_FOREACH(flow, &pf->flow_list, node) {
> + if (flow->filter_type == RTE_ETH_FILTER_FDIR) {
> + TAILQ_REMOVE(&pf->flow_list, flow, node);
> + rte_free(flow);
> + }
> + }
Be careful, I'm not sure calling TAILQ_REMOVE() followed by rte_free()
inside a TAILQ_FOREACH() is safe. BSD has the _SAFE() variant for this
purpose but Linux does not.
> + }
> +
> + return ret;
> +}
--
Adrien Mazarguil
6WIND
^ permalink raw reply
* Re: [PATCH v2 07/17] net/i40e: add flow validate function
From: Adrien Mazarguil @ 2016-12-27 12:40 UTC (permalink / raw)
To: Beilei Xing; +Cc: jingjing.wu, helin.zhang, dev
In-Reply-To: <1482819984-14120-8-git-send-email-beilei.xing@intel.com>
Hi Beilei,
A few comments below.
On Tue, Dec 27, 2016 at 02:26:14PM +0800, Beilei Xing wrote:
> This patch adds i40e_flow_validation function to check if
> a flow is valid according to the flow pattern.
> i40e_parse_ethertype_filter is added first, it also gets
> the ethertype info.
> i40e_flow.c is added to handle all generic filter events.
>
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
> drivers/net/i40e/Makefile | 1 +
> drivers/net/i40e/i40e_ethdev.c | 5 +
> drivers/net/i40e/i40e_ethdev.h | 20 ++
> drivers/net/i40e/i40e_flow.c | 431 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 457 insertions(+)
> create mode 100644 drivers/net/i40e/i40e_flow.c
[...]
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> new file mode 100644
> index 0000000..bf451ef
> --- /dev/null
> +++ b/drivers/net/i40e/i40e_flow.c
[...]
> + if (ethertype_filter->queue >= pf->dev_data->nb_rx_queues) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "Invalid queue ID for"
> + " ethertype_filter.");
When setting an error type related to an existing object provided by the
application, you should set the related cause pointer to a non-NULL
value. In this particular case, retrieving the action object seems difficult
so it can remain that way, however there are many places in this series
where it can be done.
> + return -EINVAL;
While this is perfectly valid, you could also return -rte_errno to avoid
duplicating EINVAL.
[...]
> + }
> + if (ethertype_filter->ether_type == ETHER_TYPE_IPv4 ||
> + ethertype_filter->ether_type == ETHER_TYPE_IPv6) {
> + rte_flow_error_set(error, ENOTSUP,
> + RTE_FLOW_ERROR_TYPE_ITEM,
> + NULL, "Unsupported ether_type in"
> + " control packet filter.");
> + return -ENOTSUP;
> + }
> + if (ethertype_filter->ether_type == ETHER_TYPE_VLAN)
> + PMD_DRV_LOG(WARNING, "filter vlan ether_type in"
> + " first tag is not supported.");
> +
> + return ret;
> +}
[...]
> +/* Parse attributes */
> +static int
> +i40e_parse_attr(const struct rte_flow_attr *attr,
> + struct rte_flow_error *error)
> +{
> + /* Must be input direction */
> + if (!attr->ingress) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
> + NULL, "Only support ingress.");
Regarding my previous comment, &attr could replace NULL here as well as in
subsequent calls to rte_flow_error_set().
> + return -EINVAL;
> + }
> +
> + /* Not supported */
> + if (attr->egress) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
> + NULL, "Not support egress.");
> + return -EINVAL;
> + }
> +
> + /* Not supported */
> + if (attr->priority) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
> + NULL, "Not support priority.");
> + return -EINVAL;
> + }
> +
> + /* Not supported */
> + if (attr->group) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
> + NULL, "Not support group.");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +i40e_parse_ethertype_pattern(const struct rte_flow_item *pattern,
> + struct rte_flow_error *error,
> + struct rte_eth_ethertype_filter *filter)
> +{
> + const struct rte_flow_item *item = pattern;
> + const struct rte_flow_item_eth *eth_spec;
> + const struct rte_flow_item_eth *eth_mask;
> + enum rte_flow_item_type item_type;
> +
> + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> + item_type = item->type;
> + switch (item_type) {
> + case RTE_FLOW_ITEM_TYPE_ETH:
> + eth_spec = (const struct rte_flow_item_eth *)item->spec;
> + eth_mask = (const struct rte_flow_item_eth *)item->mask;
> + /* Get the MAC info. */
> + if (!eth_spec || !eth_mask) {
> + rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ITEM,
> + NULL,
> + "NULL ETH spec/mask");
> + return -EINVAL;
> + }
While optional, I think you should allow eth_spec and eth_mask to be NULL
here as described in [1]:
- If eth_spec is NULL, you can match anything that looks like a valid
Ethernet header.
- If eth_mask is NULL, you should assume a default mask (for Ethernet it
usually means matching source/destination MACs perfectly).
- You must check the "last" field as well, if non-NULL it may probably be
supported as long as the following condition is satisfied:
(spec & mask) == (last & mask)
[1] http://dpdk.org/doc/guides/prog_guide/rte_flow.html#pattern-item
[...]
> + const struct rte_flow_action_queue *act_q;
> + uint32_t index = 0;
> +
> + /* Check if the first non-void action is QUEUE or DROP. */
> + NEXT_ITEM_OF_ACTION(act, actions, index);
> + if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
> + act->type != RTE_FLOW_ACTION_TYPE_DROP) {
> + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "Not supported action.");
Again, you could report &act instead of NULL here (please check all
remaining calls to rte_flow_error_set()).
[...]
--
Adrien Mazarguil
6WIND
^ permalink raw reply
* [PATCH v3 4/4] net/i40e: add firmware version get
From: Qiming Yang @ 2016-12-27 12:30 UTC (permalink / raw)
To: dev, thomas.monjalon; +Cc: remy.horton, ferruh.yigit, Qiming Yang
In-Reply-To: <1482841816-54143-1-git-send-email-qiming.yang@intel.com>
This patch add a new function i40e_fw_version_get.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
v3 changes:
* use i40e_fw_version_get(struct rte_eth_dev *dev, u32 *fw_major,
u32 *fw_minor, __rte_unused u32 *fw_patch, u32 *etrack_id)
instead of i40e_fw_version_get(struct rte_eth_dev *dev,
char *fw_version, int fw_length). Add statusment in
/doc/guides/nics/features/i40e.ini.
---
---
doc/guides/nics/features/i40e.ini | 1 +
drivers/net/i40e/i40e_ethdev.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
index 0d143bc..6dab9f7 100644
--- a/doc/guides/nics/features/i40e.ini
+++ b/doc/guides/nics/features/i40e.ini
@@ -46,3 +46,4 @@ Linux VFIO = Y
x86-32 = Y
x86-64 = Y
ARMv8 = Y
+FW version = Y
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8f63044..1dbbcc4 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -324,6 +324,8 @@ static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
uint16_t queue_id,
uint8_t stat_idx,
uint8_t is_rx);
+static void i40e_fw_version_get(struct rte_eth_dev *dev, u32 *fw_major,
+ u32 *fw_minor, __rte_unused u32 *fw_patch, u32 *etrack_id);
static void i40e_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
@@ -503,6 +505,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
.stats_reset = i40e_dev_stats_reset,
.xstats_reset = i40e_dev_stats_reset,
.queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set,
+ .fw_version_get = i40e_fw_version_get,
.dev_infos_get = i40e_dev_info_get,
.dev_supported_ptypes_get = i40e_dev_supported_ptypes_get,
.vlan_filter_set = i40e_vlan_filter_set,
@@ -2590,6 +2593,18 @@ i40e_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *dev,
}
static void
+i40e_fw_version_get(struct rte_eth_dev *dev, u32 *fw_major, u32 *fw_minor,
+ __rte_unused u32 *fw_patch, u32 *etrack_id)
+{
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ *fw_major = (hw->nvm.version >> 12) & 0xf;
+ *fw_minor = ((hw->nvm.version >> 4) & 0xff) * 10 +
+ (hw->nvm.version & 0xf);
+ *etrack_id = hw->nvm.eetrack;
+}
+
+static void
i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
--
2.7.4
^ permalink raw reply related
* [PATCH v3 3/4] net/ixgbe: add firmware version get
From: Qiming Yang @ 2016-12-27 12:30 UTC (permalink / raw)
To: dev, thomas.monjalon; +Cc: remy.horton, ferruh.yigit, Qiming Yang
In-Reply-To: <1482841816-54143-1-git-send-email-qiming.yang@intel.com>
This patch add a new function ixgbe_fw_version_get.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
v3 changes:
* use ixgbe_fw_version_get(struct rte_eth_dev *dev,
__rte_unused u32 *fw_major, __rte_unused u32 *fw_minor,
__rte_unused u32 *fw_patch, u32 *etrack_id) instead of
ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
int fw_length). Add statusment in /doc/guides/nics/features/ixgbe.ini.
---
---
doc/guides/nics/features/ixgbe.ini | 1 +
drivers/net/ixgbe/ixgbe_ethdev.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/doc/guides/nics/features/ixgbe.ini b/doc/guides/nics/features/ixgbe.ini
index 4a5667f..e4a0830 100644
--- a/doc/guides/nics/features/ixgbe.ini
+++ b/doc/guides/nics/features/ixgbe.ini
@@ -52,3 +52,4 @@ Linux VFIO = Y
ARMv8 = Y
x86-32 = Y
x86-64 = Y
+FW_version = Y
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ec2edad..e2234c0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -193,6 +193,9 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
uint16_t queue_id,
uint8_t stat_idx,
uint8_t is_rx);
+static void ixgbe_fw_version_get(struct rte_eth_dev *dev,
+ __rte_unused u32 *fw_major, __rte_unused u32 *fw_minor,
+ __rte_unused u32 *fw_patch, u32 *etrack_id);
static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
@@ -538,6 +541,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
+ .fw_version_get = ixgbe_fw_version_get,
.dev_infos_get = ixgbe_dev_info_get,
.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
.mtu_set = ixgbe_dev_mtu_set,
@@ -3029,6 +3033,19 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
}
static void
+ixgbe_fw_version_get(struct rte_eth_dev *dev, __rte_unused u32 *fw_major,
+ __rte_unused u32 *fw_minor, __rte_unused u32 *fw_patch, u32 *etrack_id)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ u16 eeprom_verh, eeprom_verl;
+
+ ixgbe_read_eeprom(hw, 0x2e, &eeprom_verh);
+ ixgbe_read_eeprom(hw, 0x2d, &eeprom_verl);
+
+ *etrack_id = (eeprom_verh << 16) | eeprom_verl;
+}
+
+static void
ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox