* [PATCH v6 12/25] net/i40e: fix VF MAC address assignment
From: Wenzhuo Lu @ 2016-12-21 6:34 UTC (permalink / raw)
To: dev; +Cc: stable, Ferruh Yigit
In-Reply-To: <1482302070-128496-1-git-send-email-wenzhuo.lu@intel.com>
If PF sets vf->mac_addr, in VF initialization hw->mac.addr will be set
to that same value. It is possible to check if PF set a MAC address or
not through the hw->mac.addr variable.
hw->mac.addr set by i40e_vf_parse_hw_config(), call stack is:
In PF side
i40e_pf_host_process_cmd_get_vf_resources()
eth_addr_copy(vf->mac_addr, vf_res->vsi_res[0].default_mac_address)
In VF sise
i40evf_init_vf()
i40evf_get_vf_resources()
i40e_vf_parse_hw_config()
memcpy(hw->mac.addr, vsi_res->default_mac_addr)
Updated code is after i40evf_get_vf_resources() and can benefit from
hw->mac.addr variable.
Fixes: 89e6b86384bb ("i40evf: rework MAC address validation")
CC: stable@dpdk.org
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
drivers/net/i40e/i40e_ethdev_vf.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 5016249..0977095 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1193,7 +1193,6 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
int i, err, bufsz;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
- struct ether_addr *p_mac_addr;
uint16_t interval =
i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
@@ -1270,13 +1269,10 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
vf->vsi.adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
/* Store the MAC address configured by host, or generate random one */
- p_mac_addr = (struct ether_addr *)(vf->vsi_res->default_mac_addr);
- if (is_valid_assigned_ether_addr(p_mac_addr)) { /* Configured by host */
- ether_addr_copy(p_mac_addr, (struct ether_addr *)hw->mac.addr);
+ if (is_valid_assigned_ether_addr((struct ether_addr *)hw->mac.addr))
vf->flags |= I40E_FLAG_VF_MAC_BY_PF;
- } else {
+ else
eth_random_addr(hw->mac.addr); /* Generate a random one */
- }
/* If the PF host is not DPDK, set the interval of ITR0 to max*/
if (vf->version_major != I40E_DPDK_VERSION_MAJOR) {
--
1.9.3
^ permalink raw reply related
* [PATCH v6 09/25] net/i40e: fix VF reset flow
From: Wenzhuo Lu @ 2016-12-21 6:34 UTC (permalink / raw)
To: dev; +Cc: stable, Qi Zhang
In-Reply-To: <1482302070-128496-1-git-send-email-wenzhuo.lu@intel.com>
Add missing step during VF reset: PF should
set I40E_VFGEN_RSTAT to ACTIVE at end of the
VF reset operation or VF driver may not able
to detect that reset is already completed.
This patch also remove the unnecessary enum
for vfr state.
Fixes: 4861cde46116 ("i40e: new poll mode driver")
CC: stable@dpdk.org
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/i40e/i40e_pf.c | 6 ++++--
drivers/net/i40e/i40e_pf.h | 5 -----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 8b8a14f..2bc3355 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -139,7 +139,7 @@
abs_vf_id = vf_id + hw->func_caps.vf_base_id;
/* Notify VF that we are in VFR progress */
- I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_INPROGRESS);
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_INPROGRESS);
/*
* If require a SW VF reset, a VFLR interrupt will be generated,
@@ -220,7 +220,7 @@
}
/* Reset done, Set COMPLETE flag and clear reset bit */
- I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_COMPLETED);
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_COMPLETED);
val = I40E_READ_REG(hw, I40E_VPGEN_VFRTRIG(vf_id));
val &= ~I40E_VPGEN_VFRTRIG_VFSWR_MASK;
I40E_WRITE_REG(hw, I40E_VPGEN_VFRTRIG(vf_id), val);
@@ -248,6 +248,8 @@
return -EFAULT;
}
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_VFACTIVE);
+
return ret;
}
diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
index 59bf2ee..ada398b 100644
--- a/drivers/net/i40e/i40e_pf.h
+++ b/drivers/net/i40e/i40e_pf.h
@@ -48,11 +48,6 @@
#define I40E_DPDK_OFFSET 0x100
-enum i40e_pf_vfr_state {
- I40E_PF_VFR_INPROGRESS = 0,
- I40E_PF_VFR_COMPLETED = 1,
-};
-
/* DPDK pf driver specific command to VF */
enum i40e_virtchnl_ops_dpdk {
/*
--
1.9.3
^ permalink raw reply related
* Re: [PATCH] i40e jumbo frames fix
From: Zhang, Helin @ 2016-12-21 5:44 UTC (permalink / raw)
To: Gregory Etelson; +Cc: dev@dpdk.org
In-Reply-To: <F35DEAC7BCE34641BA9FAC6BCA4A12E71A973ACC@SHSMSX103.ccr.corp.intel.com>
> From: Gregory Etelson [mailto:gregory@weka.io]
> Sent: Wednesday, December 21, 2016 1:16 PM
> To: dev
> Cc: Wu, Jingjing; Zhang, Helin
> Subject: [PATCH] i40e jumbo frames fix
The format of the title is not corect as requried by DPDK community.
Please refer to other patches.
>
> Allow i40e PF and VF ports to operate with Ethernet jumbo frames
Can you help to explain what's the issue? I am a little bit confused.
>
>
> Signed-off-by: Gregory Etelson <gregory@weka.io>
>
> ---
> drivers/net/i40e/i40e_ethdev_vf.c | 2 +- drivers/net/i40e/i40e_rxtx.c
> | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c
> b/drivers/net/i40e/i40e_ethdev_vf.c
> index aa306d6..cf814e9 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -1784,7 +1784,7 @@ static int i40evf_dev_xstats_get(struct
> rte_eth_dev *dev,
> * Check if the jumbo frame and maximum packet length are set correctly
> */ if (dev_data->dev_conf.rxmode.jumbo_frame == 1) {
> - if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
> + if (rxq->max_pkt_len < ETHER_MAX_LEN ||
> rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
> PMD_DRV_LOG(ERR, "maximum packet length must be "
> "larger than %u and smaller than %u, as jumbo "
> diff --git a/drivers/net/i40e/i40e_rxtx.c
> b/drivers/net/i40e/i40e_rxtx.c index
> 7ae7d9f..8cb4655 100644
> --- a/drivers/net/i40e/i40e_rxtx.c
> +++ b/drivers/net/i40e/i40e_rxtx.c
> @@ -2324,7 +2324,7 @@ static inline int __attribute__((always_inline))
> len =
> hw->func_caps.rx_buf_chain_len * rxq->rx_buf_len;
> rxq->max_pkt_len = RTE_MIN(len, data->dev_conf.rxmode.max_rx_pkt_len);
> if (data->dev_conf.rxmode.jumbo_frame == 1) {
> - if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
> + if (rxq->max_pkt_len < ETHER_MAX_LEN ||
> rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
> PMD_DRV_LOG(ERR, "maximum packet length must "
> "be larger than %u and smaller than %u,"
> --
> 1.7.1
>
>
>
^ permalink raw reply
* Re: [PATCH v2 06/25] app/testpmd: implement basic support for rte_flow
From: Xing, Beilei @ 2016-12-21 5:23 UTC (permalink / raw)
To: Adrien Mazarguil; +Cc: dev@dpdk.org, Pei, Yulong
In-Reply-To: <20161220093815.GO10340@6wind.com>
> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Tuesday, December 20, 2016 5:38 PM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Pei, Yulong <yulong.pei@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 06/25] app/testpmd: implement basic
> support for rte_flow
>
> On Tue, Dec 20, 2016 at 01:57:46AM +0000, Xing, Beilei wrote:
> > > -----Original Message-----
> > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > Sent: Monday, December 19, 2016 6:20 PM
> > > To: Xing, Beilei <beilei.xing@intel.com>
> > > Cc: dev@dpdk.org; Pei, Yulong <yulong.pei@intel.com>
> > > Subject: Re: [dpdk-dev] [PATCH v2 06/25] app/testpmd: implement
> > > basic support for rte_flow
> > >
> > > Hi Beilei,
> > >
> > > On Mon, Dec 19, 2016 at 08:37:20AM +0000, Xing, Beilei wrote:
> > > > Hi Adrien,
> > > >
> > > > > -----Original Message-----
> > > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien
> > > > > Mazarguil
> > > > > Sent: Saturday, December 17, 2016 12:25 AM
> > > > > To: dev@dpdk.org
> > > > > Subject: [dpdk-dev] [PATCH v2 06/25] app/testpmd: implement
> > > > > basic support for rte_flow
> > > > >
> > > > > Add basic management functions for the generic flow API
> > > > > (validate, create, destroy, flush, query and list). Flow rule
> > > > > objects and properties are arranged in lists associated with each port.
> > > > >
> > > > > Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > > > > +/** Create flow rule. */
> > > > > +int
> > > > > +port_flow_create(portid_t port_id,
> > > > > + const struct rte_flow_attr *attr,
> > > > > + const struct rte_flow_item *pattern,
> > > > > + const struct rte_flow_action *actions) {
> > > > > + struct rte_flow *flow;
> > > > > + struct rte_port *port;
> > > > > + struct port_flow *pf;
> > > > > + uint32_t id;
> > > > > + struct rte_flow_error error;
> > > > > +
> > > >
> > > > I think there should be memset for error here, e.g. memset(&error,
> > > > 0, sizeof(struct rte_flow_error)); Since both cause and message
> > > > may be NULL
> > > regardless of the error type, if there's no error.cause and
> > > error.message returned from PMD, Segmentation fault will happen in
> port_flow_complain.
> > > > PS: This issue doesn't happen if add "export EXTRA_CFLAGS=' -g
> > > > O0'" when
> > > compiling.
> > >
> > > Actually, PMDs must fill the error structure only in case of error
> > > if the application provides one, it's not optional. I didn't
> > > initialize this structure for this reason.
> > >
> > > I suggest we initialize it with a known poisoning value for
> > > debugging purposes though, to make it fail every time. Does it sound
> reasonable?
>
> Done for v3 by the way.
>
> > OK, I see. Do you want PMD to allocate the memory for cause and message
> of error, and must fill the cause and message if error exists, right?
> > So is it possible to set NULL for pointers of cause and message in application?
> then PMD can judge if it's need to allocate or overlap memory.
>
> PMDs never allocate this structure, applications do and initialize it however
> they want. They only provide a non-NULL pointer if they want additional
> details in case of error.
>
> It will likely be allocated on the stack in most cases (as in testpmd).
>
> From a PMD standpoint, the contents of this structure must be updated in
> case of non-NULL pointer and error state.
>
> Now the message pointer can be allocated dynamically but it's not
> recommended, it's far easier to make it point to some constant string.
> Applications won't free it anyway, so PMDs would have to do it during
> dev_close(). Please see "Verbose error reporting" documentation section.
Got it, thanks. Seems the rte_flow_error_set function can be used for PMD.
Regards,
Beilei
^ permalink raw reply
* [PATCH] i40e jumbo frames fix
From: Gregory Etelson @ 2016-12-21 5:15 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu, Helin Zhang
Allow i40e PF and VF ports to operate with Ethernet jumbo frames
Signed-off-by: Gregory Etelson <gregory@weka.io>
---
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/i40e/i40e_rxtx.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..cf814e9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1784,7 +1784,7 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
* Check if the jumbo frame and maximum packet length are set correctly
*/
if (dev_data->dev_conf.rxmode.jumbo_frame == 1) {
- if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
+ if (rxq->max_pkt_len < ETHER_MAX_LEN ||
rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
PMD_DRV_LOG(ERR, "maximum packet length must be "
"larger than %u and smaller than %u, as jumbo "
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 7ae7d9f..8cb4655 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2324,7 +2324,7 @@ static inline int __attribute__((always_inline))
len = hw->func_caps.rx_buf_chain_len * rxq->rx_buf_len;
rxq->max_pkt_len = RTE_MIN(len, data->dev_conf.rxmode.max_rx_pkt_len);
if (data->dev_conf.rxmode.jumbo_frame == 1) {
- if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
+ if (rxq->max_pkt_len < ETHER_MAX_LEN ||
rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
PMD_DRV_LOG(ERR, "maximum packet length must "
"be larger than %u and smaller than %u,"
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 10/24] ethdev: parse ethertype filter
From: Xing, Beilei @ 2016-12-21 3:54 UTC (permalink / raw)
To: Yigit, Ferruh, Wu, Jingjing, Zhang, Helin
Cc: dev@dpdk.org, Lu, Wenzhuo, Adrien Mazarguil
In-Reply-To: <ff1ef72f-7397-a7d0-071f-ff18be979bf6@intel.com>
Hi Ferruh,
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday, December 21, 2016 2:12 AM
> To: Xing, Beilei <beilei.xing@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
> Cc: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Adrien Mazarguil
> <adrien.mazarguil@6wind.com>
> Subject: Re: [dpdk-dev] [PATCH 10/24] ethdev: parse ethertype filter
>
> On 12/2/2016 11:53 AM, Beilei Xing wrote:
> > Check if the rule is a ethertype rule, and get the ethertype info BTW.
> >
> > Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> > Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> > ---
>
> CC: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>
> > lib/librte_ether/rte_flow.c | 136
> +++++++++++++++++++++++++++++++++++++
> > lib/librte_ether/rte_flow_driver.h | 34 ++++++++++
>
> <...>
>
> > diff --git a/lib/librte_ether/rte_flow_driver.h
> > b/lib/librte_ether/rte_flow_driver.h
> > index a88c621..2760c74 100644
> > --- a/lib/librte_ether/rte_flow_driver.h
> > +++ b/lib/librte_ether/rte_flow_driver.h
> > @@ -170,6 +170,40 @@ rte_flow_error_set(struct rte_flow_error *error,
> > const struct rte_flow_ops * rte_flow_ops_get(uint8_t port_id, struct
> > rte_flow_error *error);
> >
> > +int cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
> > + const struct rte_flow_item *pattern,
> > + const struct rte_flow_action *actions,
> > + struct rte_eth_ethertype_filter *filter,
> > + struct rte_flow_error *error);
>
> Although this is helper function, it may be good if it follows the rte_follow
> namespace.
OK, I will rename it in the next version, thanks very much.
>
> > +
> > +#define PATTERN_SKIP_VOID(filter, filter_struct, error_type)
> \
> > + do { \
> > + if (!pattern) { \
> > + memset(filter, 0, sizeof(filter_struct)); \
> > + error->type = error_type; \
> > + return -EINVAL;
> \
> > + } \
> > + item = pattern + i; \
>
> I believe macros that relies on variables that not passed as argument is not
> good idea.
Yes, I'm reworking the macros, and it will be changed in v2.
>
> > + while (item->type == RTE_FLOW_ITEM_TYPE_VOID) {
> \
> > + i++; \
> > + item = pattern + i; \
> > + } \
> > + } while (0)
> > +
> > +#define ACTION_SKIP_VOID(filter, filter_struct, error_type)
> \
> > + do { \
> > + if (!actions) { \
> > + memset(filter, 0, sizeof(filter_struct)); \
> > + error->type = error_type; \
> > + return -EINVAL;
> \
> > + } \
> > + act = actions + i; \
> > + while (act->type == RTE_FLOW_ACTION_TYPE_VOID) { \
> > + i++; \
> > + act = actions + i; \
> > + } \
> > + } while (0)
>
> Are these macros generic enough for all rte_flow consumers?
>
> What do you think separate this patch, and use these after applied,
> meanwhile keeping function and MACROS PMD internal?
The main purpose of the macros is to reduce the code in PMD, otherwise there'll be many such codes to get the next non-void item in all parse functions, including the parse_ethertype_filter function in rte_flow.c. But actually I'm not very sure if it's generic enough for all consumers, although I think it's general at present:)
Thanks for your advice, I'll move the macros to PMD currently, then there'll be no macros used in parse_ethertype_filter function, and optimize it after applied.
BTW, I plan to send out V2 patch set in this week.
Best Regards,
Beilei
>
> > +
> > #ifdef __cplusplus
> > }
> > #endif
> >
^ permalink raw reply
* [PATCH] net/fm10k/base: add a break statement
From: Chenghu Yao @ 2016-12-21 3:05 UTC (permalink / raw)
To: jing.d.chen; +Cc: dev, Chenghu Yao
In function fm10k_mbx_create_reply(), the last case branch
has no break statement.
Signed-off-by: Chenghu Yao <yao.chenghu@zte.com.cn>
---
drivers/net/fm10k/base/fm10k_mbx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/fm10k/base/fm10k_mbx.c b/drivers/net/fm10k/base/fm10k_mbx.c
index 2e70434..45d6ddb 100644
--- a/drivers/net/fm10k/base/fm10k_mbx.c
+++ b/drivers/net/fm10k/base/fm10k_mbx.c
@@ -1084,6 +1084,7 @@ STATIC s32 fm10k_mbx_create_reply(struct fm10k_hw *hw,
case FM10K_STATE_CLOSED:
/* generate new header based on data */
fm10k_mbx_create_disconnect_hdr(mbx);
+ break;
default:
break;
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v3] app/testpmd: supported offload capabilities query
From: Yuanhan Liu @ 2016-12-21 2:37 UTC (permalink / raw)
To: Qiming Yang; +Cc: dev, jingjing.wu
In-Reply-To: <1482286826-72737-1-git-send-email-qiming.yang@intel.com>
On Wed, Dec 21, 2016 at 10:20:26AM +0800, Qiming Yang wrote:
> Add two new commands "show port capa <port>" and "show
I think 'cap' is a more well-known shortening for capability than
"capa"?
--yliu
^ permalink raw reply
* [PATCH v3] app/testpmd: supported offload capabilities query
From: Qiming Yang @ 2016-12-21 2:20 UTC (permalink / raw)
To: dev; +Cc: jingjing.wu, Qiming Yang
In-Reply-To: <1481008055-68096-1-git-send-email-qiming.yang@intel.com>
Add two new commands "show port capa <port>" and "show
port capa all"to diaplay what offload capabilities supported
in ports. It will not only display all the capabilities of
the port, but also the enabling condition for each capability
in the running time.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
v2 changes:
* fixed the output style as Ferruh's patch show and add some
descriptions in testpmd_funcs.rst for new functions.
v3 changes:
* add new command in cmd_help_long_parsed.
---
---
app/test-pmd/cmdline.c | 17 ++-
app/test-pmd/config.c | 172 ++++++++++++++++++++++++++++
app/test-pmd/testpmd.h | 1 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 +-
4 files changed, 192 insertions(+), 10 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 63b55dc..21ffa0a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -182,7 +182,7 @@ static void cmd_help_long_parsed(void *parsed_result,
"Display:\n"
"--------\n\n"
- "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n"
+ "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc|capa) (port_id|all)\n"
" Display information for port_id, or all.\n\n"
"show port X rss reta (size) (mask0,mask1,...)\n"
@@ -5766,6 +5766,9 @@ static void cmd_showportall_parsed(void *parsed_result,
else if (!strcmp(res->what, "dcb_tc"))
FOREACH_PORT(i, ports)
port_dcb_info_display(i);
+ else if (!strcmp(res->what, "capa"))
+ FOREACH_PORT(i, ports)
+ port_offload_capa_display(i);
}
cmdline_parse_token_string_t cmd_showportall_show =
@@ -5775,13 +5778,14 @@ cmdline_parse_token_string_t cmd_showportall_port =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
cmdline_parse_token_string_t cmd_showportall_what =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
- "info#stats#xstats#fdir#stat_qmap#dcb_tc");
+ "info#stats#xstats#fdir#stat_qmap#dcb_tc#capa");
cmdline_parse_token_string_t cmd_showportall_all =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
cmdline_parse_inst_t cmd_showportall = {
.f = cmd_showportall_parsed,
.data = NULL,
- .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all",
+ .help_str = "show|clear port"
+ "info|stats|xstats|fdir|stat_qmap|dcb_tc|capa all",
.tokens = {
(void *)&cmd_showportall_show,
(void *)&cmd_showportall_port,
@@ -5821,6 +5825,8 @@ static void cmd_showport_parsed(void *parsed_result,
nic_stats_mapping_display(res->portnum);
else if (!strcmp(res->what, "dcb_tc"))
port_dcb_info_display(res->portnum);
+ else if (!strcmp(res->what, "capa"))
+ port_offload_capa_display(res->portnum);
}
cmdline_parse_token_string_t cmd_showport_show =
@@ -5830,14 +5836,15 @@ cmdline_parse_token_string_t cmd_showport_port =
TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
cmdline_parse_token_string_t cmd_showport_what =
TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
- "info#stats#xstats#fdir#stat_qmap#dcb_tc");
+ "info#stats#xstats#fdir#stat_qmap#dcb_tc#capa");
cmdline_parse_token_num_t cmd_showport_portnum =
TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8);
cmdline_parse_inst_t cmd_showport = {
.f = cmd_showport_parsed,
.data = NULL,
- .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X (X = port number)",
+ .help_str = "show|clear port"
+ "info|stats|xstats|fdir|stat_qmap|dcb_tc|capa <port_id>",
.tokens = {
(void *)&cmd_showport_show,
(void *)&cmd_showport_port,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 36c47ab..9571426 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -536,6 +536,178 @@ port_infos_display(portid_t port_id)
dev_info.tx_desc_lim.nb_min);
printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
}
+void
+port_offload_capa_display(portid_t port_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ static const char *info_border = "************";
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ dev = &rte_eth_devices[port_id];
+ rte_eth_dev_info_get(port_id, &dev_info);
+
+ printf("\n%s Port %d supported offload features: %s\n",
+ info_border, port_id, info_border);
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP) {
+ printf("VLAN stripped: ");
+ if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM) {
+ printf("RX IPv4 checksum: ");
+ if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM) {
+ printf("RX UDP checksum: ");
+ if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM) {
+ printf("TCP checksum: ");
+ if (dev->data->dev_conf.rxmode.hw_ip_checksum)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
+ printf("Large receive offload: ");
+ if (dev->data->dev_conf.rxmode.enable_lro)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP) {
+ printf("Double VLANs stripped: ");
+ if (dev->data->dev_conf.rxmode.hw_vlan_extend)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
+ printf("Outer IPv4 checksum: ");
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) {
+ printf("VLAN insert: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_VLAN)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) {
+ printf("TX IPv4 checksum: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) {
+ printf("TX UDP checksum: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) {
+ printf("TX TCP checksum: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) {
+ printf("TX SCTP checksum: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) {
+ printf("TX TCP segmentation: ");
+ if (ports[port_id].tso_segsz != 0)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TSO) {
+ printf("UDP segmentation: ");
+ if (ports[port_id].tso_segsz != 0)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
+ printf("Outer IPv4 checksum: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) {
+ printf("Double VLANs insert: ");
+ if (ports[port_id].tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO) {
+ printf("VXLAN TSO for tunnel packet: ");
+ if (ports[port_id].tunnel_tso_segsz)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO) {
+ printf("Generic TSO for tunnel packet: ");
+ if (ports[port_id].tunnel_tso_segsz)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO) {
+ printf("IPIP TSO for tunnel packet: ");
+ if (ports[port_id].tunnel_tso_segsz)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
+ printf("GENEVE TSO for tunnel packet: ");
+ if (ports[port_id].tunnel_tso_segsz)
+ printf("on\n");
+ else
+ printf("off\n");
+ }
+
+}
int
port_id_is_invalid(portid_t port_id, enum print_warning warning)
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9c1e703..c59bb03 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -484,6 +484,7 @@ void nic_xstats_display(portid_t port_id);
void nic_xstats_clear(portid_t port_id);
void nic_stats_mapping_display(portid_t port_id);
void port_infos_display(portid_t port_id);
+void port_offload_capa_display(portid_t port_id);
void rx_queue_infos_display(portid_t port_idi, uint16_t queue_id);
void tx_queue_infos_display(portid_t port_idi, uint16_t queue_id);
void fwd_lcores_config_display(void);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f1c269a..6f4dd4a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -51,10 +51,10 @@ If you type a partial command and hit ``<TAB>`` you get a list of the available
testpmd> show port <TAB>
- info [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X
- info [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all
- stats [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X
- stats [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all
+ info [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc|capa X
+ info [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc|capa all
+ stats [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc|capa X
+ stats [Mul-choice STRING]: show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc|capa all
...
@@ -131,7 +131,7 @@ show port
Display information for a given port or all ports::
- testpmd> show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)
+ testpmd> show port (info|stats|xstats|fdir|stat_qmap|dcb_tc|capa) (port_id|all)
The available information categories are:
@@ -147,6 +147,8 @@ The available information categories are:
* ``dcb_tc``: DCB information such as TC mapping.
+* ``capa``: Supported offload capabilities.
+
For example:
.. code-block:: console
--
2.7.4
^ permalink raw reply related
* [PATCH v2] net/ixgbe/base: clear redundant macro define
From: Chenghu Yao @ 2016-12-21 2:03 UTC (permalink / raw)
To: wenzhuo.lu, helin.zhang; +Cc: dev, Chenghu Yao
In head file "ixgbe_mbx.h", macro define IXGBE_VF_API_NEGOTIATE and
IXGBE_VF_GET_QUEUES appear two times with the same name, value,
and notes.
Version 2.0 VF requests can inherit the two macro defines
in previous version 1.0 and 1.1. Otherwise, maybe cause confusion.
Signed-off-by: Chenghu Yao <yao.chenghu@zte.com.cn>
---
v2:
* eliminate commit warning
---
drivers/net/ixgbe/base/ixgbe_mbx.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ixgbe/base/ixgbe_mbx.h b/drivers/net/ixgbe/base/ixgbe_mbx.h
index 7556a81..483e9b3 100644
--- a/drivers/net/ixgbe/base/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/base/ixgbe_mbx.h
@@ -128,8 +128,6 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_PF_CONTROL_MSG 0x0100 /* PF control message */
/* mailbox API, version 2.0 VF requests */
-#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */
-#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
#define IXGBE_VF_ENABLE_MACADDR 0x0A /* enable MAC address */
#define IXGBE_VF_DISABLE_MACADDR 0x0B /* disable MAC address */
#define IXGBE_VF_GET_MACADDRS 0x0C /* get all configured MAC addrs */
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v5 29/29] net/i40e: set/clear VF stats from PF
From: Lu, Wenzhuo @ 2016-12-21 0:56 UTC (permalink / raw)
To: Iremonger, Bernard, Yigit, Ferruh, dev@dpdk.org
Cc: Wu, Jingjing, Zhang, Helin, Zhang, Qi Z, Chen, Jing D
In-Reply-To: <8CEF83825BEC744B83065625E567D7C224D17A76@IRSMSX108.ger.corp.intel.com>
Hi all,
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Tuesday, December 20, 2016 9:40 PM
> To: Yigit, Ferruh; dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Zhang, Qi Z; Lu, Wenzhuo; Chen, Jing D
> Subject: RE: [dpdk-dev] [PATCH v5 29/29] net/i40e: set/clear VF stats from PF
>
> Hi Ferruh,
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> > Sent: Tuesday, December 20, 2016 1:25 PM
> > To: dev@dpdk.org
> > Cc: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> > <helin.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Lu,
> > Wenzhuo <wenzhuo.lu@intel.com>; Chen, Jing D <jing.d.chen@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v5 29/29] net/i40e: set/clear VF stats
> > from PF
> >
> > On 12/16/2016 7:02 PM, Ferruh Yigit wrote:
> > > From: Qi Zhang <qi.z.zhang@intel.com>
> > >
> > > This patch add support to get/clear VF statistics from PF side.
> > > Two APIs are added:
> > > rte_pmd_i40e_get_vf_stats.
> > > rte_pmd_i40e_reset_vf_stats.
> > >
> > > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > > ---
> >
> > <...>
> >
> > > diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> > > b/drivers/net/i40e/rte_pmd_i40e_version.map
> > > index 8ac1bc8..7a5d211 100644
> > > --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> > > +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> > > @@ -6,7 +6,9 @@ DPDK_2.0 {
> > > DPDK_17.02 {
> > > global:
> > >
> > > + rte_pmd_i40e_get_vf_stats;
> > > rte_pmd_i40e_ping_vfs;
> > > + rte_pmd_i40e_reset_vf_stats;
> > > rte_pmd_i40e_set_tx_loopback;
> > > rte_pmd_i40e_set_vf_broadcast;
> > > rte_pmd_i40e_set_vf_mac_addr;
> >
> > Hi Wenzhuo, Mark,
> >
> > I think this is the list of all APIs added with this patchset.
> >
> > Just a question, what do you think following a logic in API naming as:
> > <name_space>_<object>_<action> ?
> >
> > So API names become:
> > rte_pmd_i40e_tx_loopback_set;
> > rte_pmd_i40e_vf_broadcast_set;
> > rte_pmd_i40e_vf_mac_addr_set;
> > rte_pmd_i40e_vfs_ping;
> > rte_pmd_i40e_vf_stats_get;
> > rte_pmd_i40e_vf_stats_reset;
> >
> >
> > After above rename, rte_pmd_i40e_tx_loopback_set() is not giving a
> > hint that this is something related to the PF controlling VF, perhaps
> > we can rename the API ?
> >
> > Also rte_pmd_i40e_vfs_ping() can become rte_pmd_i40e_vf_ping_all() to
> > be more consistent about _vf_ usage.
> >
> > Overall, they can be something like:
> > rte_pmd_i40e_vf_broadcast_set;
> > rte_pmd_i40e_vf_mac_addr_set;
> > rte_pmd_i40e_vf_ping_all;
> > rte_pmd_i40e_vf_stats_get;
> > rte_pmd_i40e_vf_stats_reset;
> > rte_pmd_i40e_vf_tx_loopback_set;
> >
> > What do you think?
> >
>
> I think the naming should be consistent with what has already been implemented
> for the ixgbe PMD.
> rte_pmd_ixgbe_set_all_queues_drop_en;
> rte_pmd_ixgbe_set_tx_loopback;
> rte_pmd_ixgbe_set_vf_mac_addr;
> rte_pmd_ixgbe_set_vf_mac_anti_spoof;
> rte_pmd_ixgbe_set_vf_split_drop_en;
> rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
> rte_pmd_ixgbe_set_vf_vlan_insert;
> rte_pmd_ixgbe_set_vf_vlan_stripq;
>
> rte_pmd_ixgbe_set_vf_rate_limit;
> rte_pmd_ixgbe_set_vf_rx;
> rte_pmd_ixgbe_set_vf_rxmode;
> rte_pmd_ixgbe_set_vf_tx;
> rte_pmd_ixgbe_set_vf_vlan_filter;
So, seems better to use the current names. Rework both ixgbe and i40e's later. Not sure if it'll be counted as the ABI change if we change the ixgbe's name.
>
> Regards,
>
> Bernard.
^ permalink raw reply
* Re: [PATCH v5 00/29] Support VFD and DPDK PF + kernel VF on i40e
From: Lu, Wenzhuo @ 2016-12-21 0:50 UTC (permalink / raw)
To: Yigit, Ferruh, Vincent JARDIN, Chen, Jing D, Thomas Monjalon
Cc: dev@dpdk.org, Wu, Jingjing, Zhang, Helin
In-Reply-To: <23012b3e-b02a-d5ff-762b-be352766c274@intel.com>
Hi all,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Tuesday, December 20, 2016 11:32 PM
> To: Vincent JARDIN; Chen, Jing D; Thomas Monjalon
> Cc: dev@dpdk.org; Wu, Jingjing; Zhang, Helin
> Subject: Re: [dpdk-dev] [PATCH v5 00/29] Support VFD and DPDK PF + kernel VF
> on i40e
>
> On 12/20/2016 3:18 PM, Vincent JARDIN wrote:
> > Le 20/12/2016 à 05:48, Chen, Jing D a écrit :
> >> That's a collaboration with another team. we'll follow-up that but
> >> not guarantee it will happen.
> >> May I ask if my reply make it clear? Still NAC for this patch?
> >
> > Yes still nack, I am not confident with this PF approach since you are
> > breaking Linux PF behavior. It does not provide guarantees with PF.
> > Something is missing to guarantee the compatibilities.
>
> Hi Vincent, Mark,
>
> What do you think separating the mentioned patch (patch 24/29) from patchset
> and submit as a standalone patch, so that it can be discussed more without
> blocking the patchset?
+1 :)
>
> Thanks,
> ferruh
>
> >
> > Thank you,
> > Vincent
> >
^ permalink raw reply
* Re: [PATCH 1/7] net/qede: reduce noise in debug logs
From: Mody, Rasesh @ 2016-12-20 23:29 UTC (permalink / raw)
To: Ferruh Yigit, Harish Patil, dev@dpdk.org; +Cc: Dept-EngDPDKDev@qlogic.com
In-Reply-To: <eedda5d5-a276-70c2-41a5-431c6fa1e128@intel.com>
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Thursday, December 08, 2016 8:49 AM
>
> On 12/3/2016 2:43 AM, Harish Patil wrote:
> > From: Rasesh Mody <Rasesh.Mody@cavium.com>
> >
> > Replace CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER with
> > CONFIG_RTE_LIBRTE_QEDE_DEBUG_VAL which is a 32-bit bitmapped value
> > where each bit represent a particular submodule to debug. Also move
> > notice messages under CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO.
> >
> > Signed-off-by: Harish Patil <harish.patil@qlogic.com>
> > Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
> > ---
>
> Is 32bit supported by driver?
We compile test our drivers for 32bit.
> If so it is throwing a compilation error for it [1], if not can you please
> document it?
>
> [1]
> In file included from .../drivers/net/qede/base/ecore.h:35:0,
> from .../drivers/net/qede/qede_ethdev.h:22,
> from .../drivers/net/qede/qede_ethdev.c:9:
> .../drivers/net/qede/qede_ethdev.c: In function 'qede_rss_hash_update':
> .../drivers/net/qede/base/../qede_logs.h:33:3: error: format '%lx'
> expects argument of type 'long unsigned int', but argument 7 has type
> 'uint64_t {aka long long unsigned int}' [-Werror=format=]
> "[%s:%d(%s)]" fmt, \
> ^
> .../drivers/net/qede/qede_ethdev.c:1472:2: note: in expansion of macro
> 'DP_INFO'
> DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n", hf, len, key);
> ^~~~~~~
> cc1: all warnings being treated as errors
We'll fix the compilation error.
>
>
> <...>
^ permalink raw reply
* Re: [PATCH 1/8] net/qede: fix to get vendor/device id info
From: Mody, Rasesh @ 2016-12-20 23:25 UTC (permalink / raw)
To: Ferruh Yigit, dev@dpdk.org; +Cc: Dept-Eng DPDK Dev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>
Hi Ferruh,
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Friday, December 09, 2016 5:36 AM
>
> Hi Rasesh,
>
> On 12/3/2016 6:35 AM, Rasesh Mody wrote:
> > Fixes: ec94dbc5 ("qede: add base driver")
> >
> > Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
>
> Related to the commit logs of this patchset. Many people, including me,
> won't know technical details of your driver as you do.
>
> From below patch, I also can see vendor_id and device_id get, which were
> not there before. But I have no clue why? Or what happens when you don't
> have them, or what works fine when you have them.
> Overall a little context helps a lot to understand what is really fixed, and what
> happens if not fixed.
The vendor_id and device_id are used to determine device type. If you don't have them, then check for determining device type fails and is always set to default device type.
Hope this helps.
> For example in patch 8/8, it is a one line easy modification :), but there is no
> way that I can understand what really it does, but commit log comes to help
> there, and describes it really fixes VF over legacy PF, by VF asking a FW
> overwrite instead of failing on PF reject msg. So patch subject can be here:
> fix VF over legacy PF.
Sounds good, will reword the subject.
> Please trying to provide more context on fixes.
>
>
> Also you need to add CC:stable@dpdk.org to commit log, so that git send-
> email ensures this fixes also sent to stable trees.
Will take care of this in v2 submission.
Thanks!
Rasesh
>
>
> Thanks,
>
> > ---
> > drivers/net/qede/qede_ethdev.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/net/qede/qede_ethdev.c
> > b/drivers/net/qede/qede_ethdev.c index 9c2a5eae..b9a325df 100644
> > --- a/drivers/net/qede/qede_ethdev.c
> > +++ b/drivers/net/qede/qede_ethdev.c
> > @@ -2071,6 +2071,10 @@ static int qede_common_dev_init(struct
> > rte_eth_dev *eth_dev, bool is_vf)
> >
> > rte_eth_copy_pci_info(eth_dev, pci_dev);
> >
> > + /* @DPDK */
> > + edev->vendor_id = pci_dev->id.vendor_id;
> > + edev->device_id = pci_dev->id.device_id;
> > +
> > qed_ops = qed_get_eth_ops();
> > if (!qed_ops) {
> > DP_ERR(edev, "Failed to get qed_eth_ops_pass\n");
> >
^ permalink raw reply
* Re: [PATCH 7/7] net/qede: restrict maximum queues for PF/VF
From: Harish Patil @ 2016-12-20 23:16 UTC (permalink / raw)
To: Ferruh Yigit, dev@dpdk.org; +Cc: Dept-Eng DPDK Dev
In-Reply-To: <c2f4e2b7-4d4a-fecc-eb41-b82c596edfc2@intel.com>
>
>On 12/12/2016 7:29 PM, Harish Patil wrote:
>>
>>> On 12/3/2016 2:43 AM, Harish Patil wrote:
>>>> Fix to adverstise max_rx_queues by taking into account the number
>>>
>>> s/adverstise/advertise
>>
>> Will correct that, thanks.
>>
>>>
>>>> of PF connections instead of returning max_queues supported by the
>>>> HW.
>>>
>>> Can you please describe what is the effect, what happens if this is not
>>> fixed, and driver keeps reporting max_queues supported by the HW?
>>
>> We have tested up to 32 Rx/Tx queues across different qede devices, so I
>> would like to advertise only those many.
>> Hope that is okay.
>
>That is OK, can you please add this information to the commit log,
>otherwise it is not possible to know the reasoning of the change just
>with code.
>
>Thanks.
Okay will do.
>
>>
>>>
>>>>
>>>> Fixes: 2ea6f76a ("qede: add core driver")
>>>>
>>>> Signed-off-by: Harish Patil <harish.patil@qlogic.com>
>>>> ---
>>> <...>
>>>
>>
>>
>
>
^ permalink raw reply
* Re: [PATCH 6/7] net/qede: fix maximum VF count to 0
From: Harish Patil @ 2016-12-20 23:15 UTC (permalink / raw)
To: Thomas Monjalon, Ferruh Yigit; +Cc: dev@dpdk.org, Dept-Eng DPDK Dev
In-Reply-To: <2614732.lzO8dLuuld@xps13>
>
>2016-12-12 18:13, Ferruh Yigit:
>> On 12/12/2016 5:47 PM, Harish Patil wrote:
>> >> btw, while checking feature list, I have seen qede_vf supports
>>SR-IOV,
>> >> is that correct?
>> >
>> > Yes. The supported combination for SR-IOV is VF driver (qede PMD)
>>with PF
>> > driver (qede linux driver).
>>
>> So you are using SR-IOV feature set in VF driver, as meaning VF driver
>> support exists. I don't know what SR-IOV feature mean for VF drivers.
>> Some other VF drivers not has this feature flag set.
>>
>> CC'ed Thomas for help, if this is the intention of the feature flag, it
>> is OK.
>
>Good question.
>I wonder where better describe the meaning of this row in the features
>table.
>Maybe it would be clearer by splitting in 2 rows:
>- SR-IOV VF
>- SR-IOV PF
>
Thanks, that would make it clearer.
Ferruh, for now I shall reword the patch title.
^ permalink raw reply
* Re: [PATCH 2/7] net/qede: refactor filtering code
From: Harish Patil @ 2016-12-20 23:12 UTC (permalink / raw)
To: Ferruh Yigit, dev@dpdk.org; +Cc: Dept-Eng DPDK Dev
In-Reply-To: <466b1cf9-78b0-4449-68a0-f5a0e20dbb5a@intel.com>
>
>On 12/12/2016 5:36 PM, Harish Patil wrote:
>>
>>> On 12/3/2016 2:43 AM, Harish Patil wrote:
>>>> The filter_config in qed_eth_ops_pass is a wrapper call driving all
>>>>the
>>>> filtering configuration. This requires defining multiple structures
>>>>and
>>>> passing different function arguments for each filter type which is
>>>> unnecessary. So as part of this refactoring we remove filter_config
>>>>from
>>>> qed_eth_ops_pass and invoke base apis directly. Another change is to
>>>> use a singly list for unicast/multicast macs and thereby prevent
>>>> duplicate
>>>
>>> singly linked list?
>>
>> Yes. Two lists to track unicast and multicast mac entries:
>> + SLIST_HEAD(mc_list_head, qede_mcast_entry) mc_list_head;
>>
>> + SLIST_HEAD(uc_list_head, qede_ucast_entry) uc_list_head;
>>
>>
>>
>>>
>>>> entries.
>>>>
>>>> This change is primarily intended to support future tunneling support
>>>> which makes use of existing L2 filtering/classifications.
>>>>
>>>> Fixes: 2ea6f76a ("qede: add core driver")
>>>
>>> What is fixed in this patch, isn't it a refactor?
>>
>> The fix part is to make use of the newly added lists and prevent
>>duplicate
>> mac filters.
>> Before that there were no checks. Other than that its refactoring to
>> mainly invoke direct base APIs.
>
>So this is not fixing any defect in driver, so I believe Fixes tag can
>be removed. This tag is mainly useful to pick commits for stable trees.
It also fixes the driver. Apart from preventing duplicate filter
programming, the existing qede_mac_addr_add() did not differentiate
between multicast and unicast mac entries. So the multicast mac addition
would wrongly go to unicast table.
So we would need Fixes tag and would need to be picked up for stable trees.
>
>>
>>>
>>> btw, all Fixes formats are wrong in the patchset, can you please use
>>>the
>>> git alias provided:
>>>
>>>http://dpdk.org/doc/guides/contributing/patches.html#commit-messages-bod
>>>y
OK sure.
>>>
>>>>
>>>> Signed-off-by: Harish Patil <harish.patil@qlogic.com>
>>>> ---
>>> <...>
>>>
>>
>>
>
>
^ permalink raw reply
* Re: [PATCH 1/7] net/qede: reduce noise in debug logs
From: Harish Patil @ 2016-12-20 22:02 UTC (permalink / raw)
To: Ferruh Yigit, dev@dpdk.org; +Cc: Dept-Eng DPDK Dev, Mody, Rasesh
In-Reply-To: <aa9e1cd8-e5a1-2d52-3e03-b2ef2b7f2360@intel.com>
>
>On 12/12/2016 5:15 PM, Harish Patil wrote:
>> Hi Ferruh,
>>
>>> On 12/3/2016 2:43 AM, Harish Patil wrote:
>>>> From: Rasesh Mody <Rasesh.Mody@cavium.com>
>>>>
>>>> Replace CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER with
>>>> CONFIG_RTE_LIBRTE_QEDE_DEBUG_VAL which is a 32-bit bitmapped value
>>>> where each bit represent a particular submodule to debug. Also move
>>>> notice messages under CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO.
>>>>
>>>> Signed-off-by: Harish Patil <harish.patil@qlogic.com>
>>>> Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
>>>> ---
>>>> config/common_base | 2 +-
>>>> doc/guides/nics/qede.rst | 4 ++--
>>>> drivers/net/qede/qede_ethdev.c | 4 ++--
>>>> drivers/net/qede/qede_logs.h | 21 +++++----------------
>>>> 4 files changed, 10 insertions(+), 21 deletions(-)
>>>>
>>>> diff --git a/config/common_base b/config/common_base
>>>> index 4bff83a..2ffd557 100644
>>>> --- a/config/common_base
>>>> +++ b/config/common_base
>>>> @@ -320,7 +320,7 @@ CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
>>>> CONFIG_RTE_LIBRTE_QEDE_PMD=y
>>>> CONFIG_RTE_LIBRTE_QEDE_DEBUG_INIT=n
>>>> CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO=n
>>>> -CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER=n
>>>> +CONFIG_RTE_LIBRTE_QEDE_DEBUG_VAL=0
>>>> CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX=n
>>>> CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX=n
>>>> #Provides abs path/name of the firmware file.
>>>> diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
>>>> index d22ecdd..ddf4248 100644
>>>> --- a/doc/guides/nics/qede.rst
>>>> +++ b/doc/guides/nics/qede.rst
>>>> @@ -103,9 +103,9 @@ enabling debugging options may affect system
>>>> performance.
>>>>
>>>> Toggle display of generic debugging messages.
>>>>
>>>> -- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER`` (default **n**)
>>>> +- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_VAL`` (default **0**)
>>>
>>> Does it make sense to document how DEBUG_VAL used?
>>>
>>> Also commit log says bitmapped value to enable/disable a particular
>>> submodule, you may want to document here which value enable/disable
>>> which submodule.
>>>
>>>>
>>>> - Toggle display of ecore related messages.
>>>> + Control driver debug verbosity using 32-bit bitmap flags.
>>>>
>>>> - ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX`` (default **n**)
>>>>
>>
>> Not really, I think that would be too much. But if you think it really
>> helps then perhaps yes we can document.
>> Otherwise it is just for internal debugging.
>
>As a user of your driver, how can I know how to enable / disable a
>module log?
>I know VAL enables / disables them, but I don't know what modules exists
>and what values are required.
>
>If this is just for internal debugging and user not need to configure
>this one, does it needs to be a config option in configuration file?
Okay then let me revert this change as before in v2 series. Earlier, it
was boolean config option and CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER=y would
enable all debug logs.
>
>>
>>
>>>
>>> <...>
>>>
>>>> diff --git a/drivers/net/qede/qede_logs.h
>>>>b/drivers/net/qede/qede_logs.h
>>>> index 45c4af0..08fdf04 100644
>>>> --- a/drivers/net/qede/qede_logs.h
>>>> +++ b/drivers/net/qede/qede_logs.h
>>>> @@ -16,15 +16,18 @@
>>>> (p_dev)->name ? (p_dev)->name : "", \
>>>> ##__VA_ARGS__)
>>>>
>>>> +#ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
>>>
>>> Is "_INFO" carries any meaning in this config option, why not just
>>> RTE_LIBRTE_QEDE_DEBUG?
>>
>> INFO is used to mean just informational type of messages.
>> If you think it doesn’t make sense then I can rename it.
>
>I don't have a strong opinion, I think that _INFO is not adding value
>unless you have different config options per each level like _VERBOSE,
>_INFO, _NOTICE. But if you believe your users will benefit from it, it
>is your call.
Yes, I would like to retain INFO as it provides high-level informational
messages currently.
>
>>
>>>
>>>> #define DP_NOTICE(p_dev, is_assert, fmt, ...) \
>>>> rte_log(RTE_LOG_NOTICE, RTE_LOGTYPE_PMD,\
>>>> "[QEDE PMD: (%s)]%s:" fmt, \
>>>> (p_dev)->name ? (p_dev)->name : "", \
>>>> __func__, \
>>>> ##__VA_ARGS__)
>>>> +#else
>>>> +#define DP_NOTICE(p_dev, fmt, ...) do { } while (0)
>>>> +#endif
>>>>
>>>> #ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
>>>> -
>>>> #define DP_INFO(p_dev, fmt, ...) \
>>>> rte_log(RTE_LOG_INFO, RTE_LOGTYPE_PMD, \
>>>> "[%s:%d(%s)]" fmt, \
>>>> @@ -33,10 +36,8 @@
>>>> ##__VA_ARGS__)
>>>> #else
>>>> #define DP_INFO(p_dev, fmt, ...) do { } while (0)
>>>> -
>>>> #endif
>>>>
>>>> -#ifdef RTE_LIBRTE_QEDE_DEBUG_DRIVER
>>>
>>> Are you sure you want to enable DP_VERBOSE, I guess most verbose log
>>> macro, by default? Perhaps may want to control it via
>>> RTE_LIBRTE_QEDE_DEBUG_INFO?
>>
>> DP_VERBOSE is enabled but it has a check:
>> if ((p_dev)->dp_module & module)
>> which controls what to print.
>> Here dp_module is controlled by CONFIG_RTE_LIBRTE_QEDE_DEBUG_VAL flag.
>> Hope it is clear.
>
>Clear thanks,
>
>I guess right now:
>DEBUG_VAL: enables verbose debug for selected module(s)
>DEBUG_INFO: Enables NOTICE and INFO level for ? (all modules?)
>ERR level is always enabled
>
>Again it is your call, but I think CONFIG_RTE_LIBRTE_QEDE_DEBUG can be
>used to enable/disable all debugs, and when enabled QEDE_DEBUG_VAL can
>select which modules to enable verbose debug ...
>
>>>
>>>> #define DP_VERBOSE(p_dev, module, fmt, ...) \
>>>> do { \
>>>> if ((p_dev)->dp_module & module) \
>>>> @@ -46,9 +47,7 @@
>>>> (p_dev)->name ? (p_dev)->name : "", \
>>>> ##__VA_ARGS__); \
>>>> } while (0)
>>>> -#else
>>>> -#define DP_VERBOSE(p_dev, fmt, ...) do { } while (0)
>>>> -#endif
>>>> +
>>>>
>>> <...>
>>>
>>>
>>
>
>
^ permalink raw reply
* Re: [PATCH v3 3/4] crypto/aesni_mb: add single operation functionality
From: Declan Doherty @ 2016-12-20 21:16 UTC (permalink / raw)
To: Pablo de Lara; +Cc: dev
In-Reply-To: <1482168543-40289-4-git-send-email-pablo.de.lara.guarch@intel.com>
On 19/12/16 17:29, Pablo de Lara wrote:
> Update driver to use new AESNI Multibuffer IPSec library single
> operation functionality (cipher only and authentication only).
> This patch also adds tests for this new feature.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
> app/test/test_cryptodev.c | 34 ++++++++
> app/test/test_cryptodev_aes_test_vectors.h | 36 +++++---
> app/test/test_cryptodev_hash_test_vectors.h | 54 ++++++++----
> doc/guides/cryptodevs/aesni_mb.rst | 2 -
> doc/guides/rel_notes/release_17_02.rst | 1 +
> drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 95 ++++++++++++++++------
> drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 9 ++
> 7 files changed, 172 insertions(+), 59 deletions(-)
>
> diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
> index f1f3542..5895d99 100644
> --- a/app/test/test_cryptodev.c
> +++ b/app/test/test_cryptodev.c
> @@ -1466,6 +1466,38 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
> }
>
> static int
> +test_AES_cipheronly_mb_all(void)
> +{
> + struct crypto_testsuite_params *ts_params = &testsuite_params;
> + int status;
> +
> + status = test_blockcipher_all_tests(ts_params->mbuf_pool,
> + ts_params->op_mpool, ts_params->valid_devs[0],
> + RTE_CRYPTODEV_AESNI_MB_PMD,
> + BLKCIPHER_AES_CIPHERONLY_TYPE);
> +
> + TEST_ASSERT_EQUAL(status, 0, "Test failed");
> +
> + return TEST_SUCCESS;
> +}
> +
> +static int
> +test_authonly_mb_all(void)
> +{
> + struct crypto_testsuite_params *ts_params = &testsuite_params;
> + int status;
> +
> + status = test_blockcipher_all_tests(ts_params->mbuf_pool,
> + ts_params->op_mpool, ts_params->valid_devs[0],
> + RTE_CRYPTODEV_AESNI_MB_PMD,
> + BLKCIPHER_AUTHONLY_TYPE);
> +
> + TEST_ASSERT_EQUAL(status, 0, "Test failed");
> +
> + return TEST_SUCCESS;
> +}
> +
> +static int
> test_AES_chain_mb_all(void)
> {
> struct crypto_testsuite_params *ts_params = &testsuite_params;
> @@ -6559,6 +6591,8 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = {
> .teardown = testsuite_teardown,
> .unit_test_cases = {
> TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all),
> + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_mb_all),
> + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_mb_all),
>
> TEST_CASES_END() /**< NULL terminate unit test array */
> }
> diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
> index efbe7da..898aae1 100644
> --- a/app/test/test_cryptodev_aes_test_vectors.h
> +++ b/app/test/test_cryptodev_aes_test_vectors.h
> @@ -1025,84 +1025,96 @@ static const struct blockcipher_test_case aes_cipheronly_test_cases[] = {
> .test_data = &aes_test_data_4,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-128-CBC Decryption",
> .test_data = &aes_test_data_4,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-192-CBC Encryption",
> .test_data = &aes_test_data_10,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-192-CBC Decryption",
> .test_data = &aes_test_data_10,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-256-CBC Encryption",
> .test_data = &aes_test_data_11,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-256-CBC Decryption",
> .test_data = &aes_test_data_11,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-128-CTR Encryption",
> .test_data = &aes_test_data_1,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-128-CTR Decryption",
> .test_data = &aes_test_data_1,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-192-CTR Encryption",
> .test_data = &aes_test_data_2,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-192-CTR Decryption",
> .test_data = &aes_test_data_2,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-256-CTR Encryption",
> .test_data = &aes_test_data_3,
> .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "AES-256-CTR Decryption",
> .test_data = &aes_test_data_3,
> .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
> .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> - BLOCKCIPHER_TEST_TARGET_PMD_QAT
> + BLOCKCIPHER_TEST_TARGET_PMD_QAT |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> };
>
> diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h
> index 9f095cf..a8f9da0 100644
> --- a/app/test/test_cryptodev_hash_test_vectors.h
> +++ b/app/test/test_cryptodev_hash_test_vectors.h
> @@ -97,7 +97,8 @@ hmac_md5_test_vector = {
> 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE,
> 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B
> },
> - .len = 16
> + .len = 16,
> + .truncated_len = 12
> }
> };
>
> @@ -139,7 +140,8 @@ hmac_sha1_test_vector = {
> 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17,
> 0x3F, 0x91, 0x64, 0x59
> },
> - .len = 20
> + .len = 20,
> + .truncated_len = 12
> }
> };
>
> @@ -184,7 +186,8 @@ hmac_sha224_test_vector = {
> 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F,
> 0x92, 0xF6, 0xAA, 0x19
> },
> - .len = 28
> + .len = 28,
> + .truncated_len = 14
> }
> };
>
> @@ -229,7 +232,8 @@ hmac_sha256_test_vector = {
> 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77,
> 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17
> },
> - .len = 32
> + .len = 32,
> + .truncated_len = 16
> }
> };
>
> @@ -280,7 +284,8 @@ hmac_sha384_test_vector = {
> 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0,
> 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E
> },
> - .len = 48
> + .len = 48,
> + .truncated_len = 24
> }
> };
>
> @@ -337,7 +342,8 @@ hmac_sha512_test_vector = {
> 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87,
> 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20
> },
> - .len = 64
> + .len = 64,
> + .truncated_len = 32
> }
> };
>
> @@ -358,13 +364,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-MD5 Digest",
> .test_data = &hmac_md5_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-MD5 Digest Verify",
> .test_data = &hmac_md5_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "SHA1 Digest",
> @@ -382,13 +390,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-SHA1 Digest",
> .test_data = &hmac_sha1_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-SHA1 Digest Verify",
> .test_data = &hmac_sha1_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "SHA224 Digest",
> @@ -406,13 +416,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-SHA224 Digest",
> .test_data = &hmac_sha224_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-SHA224 Digest Verify",
> .test_data = &hmac_sha224_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "SHA256 Digest",
> @@ -430,13 +442,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-SHA256 Digest",
> .test_data = &hmac_sha256_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-SHA256 Digest Verify",
> .test_data = &hmac_sha256_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "SHA384 Digest",
> @@ -454,13 +468,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-SHA384 Digest",
> .test_data = &hmac_sha384_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-SHA384 Digest Verify",
> .test_data = &hmac_sha384_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "SHA512 Digest",
> @@ -478,13 +494,15 @@ static const struct blockcipher_test_case hash_test_cases[] = {
> .test_descr = "HMAC-SHA512 Digest",
> .test_data = &hmac_sha512_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> {
> .test_descr = "HMAC-SHA512 Digest Verify",
> .test_data = &hmac_sha512_test_vector,
> .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
> - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
> + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
> + BLOCKCIPHER_TEST_TARGET_PMD_MB
> },
> };
>
> diff --git a/doc/guides/cryptodevs/aesni_mb.rst b/doc/guides/cryptodevs/aesni_mb.rst
> index b47cb6a..cb429d7 100644
> --- a/doc/guides/cryptodevs/aesni_mb.rst
> +++ b/doc/guides/cryptodevs/aesni_mb.rst
> @@ -62,8 +62,6 @@ Limitations
> -----------
>
> * Chained mbufs are not supported.
> -* 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).
>
> diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
> index 4f666df..5aa8a94 100644
> --- a/doc/guides/rel_notes/release_17_02.rst
> +++ b/doc/guides/rel_notes/release_17_02.rst
> @@ -49,6 +49,7 @@ New Features
>
> * The Intel(R) Multi Buffer Crypto for IPsec library used in
> AESNI MB PMD has been moved to a new repository, in github.
> + * Support for single operations (cipher only and authentication only).
>
>
> Resolved Issues
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> index 7443b47..bafd4d7 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> @@ -107,26 +107,27 @@ calculate_auth_precomputes(hash_one_block_t one_block_hash,
> }
>
> /** Get xform chain order */
> -static int
> +static enum aesni_mb_operation
> aesni_mb_get_chain_order(const struct rte_crypto_sym_xform *xform)
> {
> - /*
> - * Multi-buffer only supports HASH_CIPHER or CIPHER_HASH chained
> - * operations, 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_AUTH &&
> - xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
> - return HASH_CIPHER;
> + if (xform == NULL)
> + return AESNI_MB_OP_NOT_SUPPORTED;
> +
> + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
> + if (xform->next == NULL)
> + return AESNI_MB_OP_CIPHER_ONLY;
> + if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
> + return AESNI_MB_OP_CIPHER_HASH;
> + }
>
> - if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
> - xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
> - return CIPHER_HASH;
> + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
> + if (xform->next == NULL)
> + return AESNI_MB_OP_HASH_ONLY;
> + if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
> + return AESNI_MB_OP_HASH_CIPHER;
> + }
>
> - return -1;
> + return AESNI_MB_OP_NOT_SUPPORTED;
> }
>
> /** Set session authentication parameters */
> @@ -137,11 +138,19 @@ aesni_mb_set_session_auth_parameters(const struct aesni_mb_ops *mb_ops,
> {
> hash_one_block_t hash_oneblock_fn;
>
> + if (xform == NULL) {
> + sess->auth.algo = NULL_HASH;
> + return 0;
> + }
> +
> if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) {
> MB_LOG_ERR("Crypto xform struct not of type auth");
> return -1;
> }
>
> + /* Select auth generate/verify */
> + sess->auth.operation = xform->auth.op;
> +
> /* Set Authentication Parameters */
> if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
> sess->auth.algo = AES_XCBC;
> @@ -199,6 +208,11 @@ aesni_mb_set_session_cipher_parameters(const struct aesni_mb_ops *mb_ops,
> {
> aes_keyexp_t aes_keyexp_fn;
>
> + if (xform == NULL) {
> + sess->cipher.mode = NULL_CIPHER;
> + return 0;
> + }
> +
> if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {
> MB_LOG_ERR("Crypto xform struct not of type cipher");
> return -1;
> @@ -268,16 +282,36 @@ aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops,
>
> /* Select Crypto operation - hash then cipher / cipher then hash */
> switch (aesni_mb_get_chain_order(xform)) {
> - case HASH_CIPHER:
> + case AESNI_MB_OP_HASH_CIPHER:
> sess->chain_order = HASH_CIPHER;
> auth_xform = xform;
> cipher_xform = xform->next;
> break;
> - case CIPHER_HASH:
> + case AESNI_MB_OP_CIPHER_HASH:
> sess->chain_order = CIPHER_HASH;
> auth_xform = xform->next;
> cipher_xform = xform;
> break;
> + case AESNI_MB_OP_HASH_ONLY:
> + sess->chain_order = HASH_CIPHER;
> + auth_xform = xform;
> + cipher_xform = NULL;
> + break;
> + case AESNI_MB_OP_CIPHER_ONLY:
> + /*
> + * Multi buffer library operates only at two modes,
> + * CIPHER_HASH and HASH_CIPHER. When doing ciphering only,
> + * chain order depends on cipher operation: encryption is always
> + * the first operation and decryption the last one.
> + */
> + if (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
> + sess->chain_order = CIPHER_HASH;
> + else
> + sess->chain_order = HASH_CIPHER;
> + auth_xform = NULL;
> + cipher_xform = xform;
> + break;
> + case AESNI_MB_OP_NOT_SUPPORTED:
> default:
> MB_LOG_ERR("Unsupported operation chain order parameter");
> return -1;
> @@ -397,7 +431,8 @@ process_crypto_op(struct aesni_mb_qp *qp, struct rte_crypto_op *op,
> }
>
> /* Set digest output location */
> - if (job->cipher_direction == DECRYPT) {
> + if (job->hash_alg != NULL_HASH &&
> + session->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
> job->auth_tag_output = (uint8_t *)rte_pktmbuf_append(m_dst,
> get_digest_byte_length(job->hash_alg));
>
> @@ -459,6 +494,7 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
> (struct rte_crypto_op *)job->user_data;
> struct rte_mbuf *m_dst =
> (struct rte_mbuf *)job->user_data2;
> + struct aesni_mb_session *sess;
>
> if (op == NULL || m_dst == NULL)
> return NULL;
> @@ -470,14 +506,19 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
> if (unlikely(job->status != STS_COMPLETED)) {
> op->status = RTE_CRYPTO_OP_STATUS_ERROR;
> return op;
> - } else if (job->chain_order == HASH_CIPHER) {
> - /* Verify digest if required */
> - if (memcmp(job->auth_tag_output, op->sym->auth.digest.data,
> - job->auth_tag_output_len_in_bytes) != 0)
> - op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
> -
> - /* trim area used for digest from mbuf */
> - rte_pktmbuf_trim(m_dst, get_digest_byte_length(job->hash_alg));
> + } else if (job->hash_alg != NULL_HASH) {
> + sess = (struct aesni_mb_session *)op->sym->session->_private;
> + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
> + /* Verify digest if required */
> + if (memcmp(job->auth_tag_output,
> + op->sym->auth.digest.data,
> + job->auth_tag_output_len_in_bytes) != 0)
> + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
> +
> + /* trim area used for digest from mbuf */
> + rte_pktmbuf_trim(m_dst,
> + get_digest_byte_length(job->hash_alg));
> + }
> }
>
> /* Free session if a session-less crypto op */
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> index 17f367f..5f125b2 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> @@ -125,6 +125,13 @@ get_digest_byte_length(JOB_HASH_ALG algo)
> return auth_digest_byte_lengths[algo];
> }
>
> +enum aesni_mb_operation {
> + AESNI_MB_OP_HASH_CIPHER,
> + AESNI_MB_OP_CIPHER_HASH,
> + AESNI_MB_OP_HASH_ONLY,
> + AESNI_MB_OP_CIPHER_ONLY,
> + AESNI_MB_OP_NOT_SUPPORTED
> +};
>
> /** private data structure for each virtual AESNI device */
> struct aesni_mb_private {
> @@ -185,6 +192,8 @@ struct aesni_mb_session {
> /** Authentication Parameters */
> struct {
> JOB_HASH_ALG algo; /**< Authentication Algorithm */
> + enum rte_crypto_auth_operation operation;
> + /**< auth operation generate or verify */
> union {
> struct {
> uint8_t inner[128] __rte_aligned(16);
>
Acked-by: Declan Doherty <declan.doherty@intel.com>
^ permalink raw reply
* Re: [PATCH v3 1/4] crypto/aesni_mb: fix incorrect crypto session
From: Declan Doherty @ 2016-12-20 21:18 UTC (permalink / raw)
To: Pablo de Lara; +Cc: dev, stable
In-Reply-To: <1482168543-40289-2-git-send-email-pablo.de.lara.guarch@intel.com>
On 19/12/16 17:29, Pablo de Lara wrote:
> When using sessionless crypto operations, crypto session
> is obtained from a pool of sessions, when processing the
> operation. Once the operation is processed, the session
> is put back in the pool, but for the AESNI MB PMD, this
> session was not being saved in the operation and therefore,
> it did not return to the session pool.
>
> Fixes: 924e84f87306 ("aesni_mb: add driver for multi buffer based crypto")
>
> CC: stable@dpdk.org
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
> drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> index f07cd07..7443b47 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> @@ -322,6 +322,7 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
> rte_mempool_put(qp->sess_mp, _sess);
> sess = NULL;
> }
> + op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
> }
>
> return sess;
>
Acked-by: Declan Doherty <declan.doherty@intel.com>
^ permalink raw reply
* Re: [PATCH] net/af_packet: initialize link interrupt callback queue
From: Chas Williams @ 2016-12-20 20:57 UTC (permalink / raw)
To: Ferruh Yigit, dev; +Cc: John W. Linville
In-Reply-To: <40da3bb6-9d84-9703-36f7-a0eb21fc48dc@intel.com>
On Tue, 2016-12-20 at 14:20 +0000, Ferruh Yigit wrote:
> On 12/17/2016 6:03 PM, Chas Williams wrote:
> > This patch initializes the eth_dev->link_intr_cbs queue which is
> > used when af_packet is passed into rte_eth_ev_callback_register().
>
> Why do you want to register callback to af_packet PMD, it won't be
> calling them?
Because I have a some other code that basically treats all the PMD's
the same way. Do I really need to write an exception for that code
that says "if this is driver such and such don't call this API routine?"
> >
> > Fixes: 4dc294158cac ("ethdev: support optional Rx and Tx callbacks")
> >
> > Signed-off-by: Chas Williams <3chas3@gmail.com>
>
> Please cc the maintainers...
OK
>
> CC: John W. Linville <linville@tuxdriver.com>
>
> > ---
> > drivers/net/af_packet/rte_eth_af_packet.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
> > index a1e13ff..ea5070a 100644
> > --- a/drivers/net/af_packet/rte_eth_af_packet.c
> > +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> > @@ -708,6 +708,7 @@ rte_pmd_init_internals(const char *name,
> > (*eth_dev)->data->drv_name = pmd_af_packet_drv.driver.name;
> > (*eth_dev)->data->kdrv = RTE_KDRV_NONE;
> > (*eth_dev)->data->numa_node = numa_node;
> > + TAILQ_INIT(&((*eth_dev)->link_intr_cbs));
> >
> > return 0;
> >
> >
>
>
^ permalink raw reply
* [PATCH v4 25/25] doc: describe testpmd flow command
From: Adrien Mazarguil @ 2016-12-20 18:42 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482257521.git.adrien.mazarguil@6wind.com>
Document syntax, interaction with rte_flow and provide usage examples.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 612 +++++++++++++++++++++++
1 file changed, 612 insertions(+)
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f1c269a..8defb88 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1631,6 +1631,9 @@ Filter Functions
This section details the available filter functions that are available.
+Note these functions interface the deprecated legacy filtering framework,
+superseded by *rte_flow*. See `Flow rules management`_.
+
ethertype_filter
~~~~~~~~~~~~~~~~~~~~
@@ -2041,3 +2044,612 @@ Set different GRE key length for input set::
For example to set GRE key length for input set to 4 bytes on port 0::
testpmd> global_config 0 gre-key-len 4
+
+
+.. _testpmd_rte_flow:
+
+Flow rules management
+---------------------
+
+Control of the generic flow API (*rte_flow*) is fully exposed through the
+``flow`` command (validation, creation, destruction and queries).
+
+Considering *rte_flow* overlaps with all `Filter Functions`_, using both
+features simultaneously may cause undefined side-effects and is therefore
+not recommended.
+
+``flow`` syntax
+~~~~~~~~~~~~~~~
+
+Because the ``flow`` command uses dynamic tokens to handle the large number
+of possible flow rules combinations, its behavior differs slightly from
+other commands, in particular:
+
+- Pressing *?* or the *<tab>* key displays contextual help for the current
+ token, not that of the entire command.
+
+- Optional and repeated parameters are supported (provided they are listed
+ in the contextual help).
+
+The first parameter stands for the operation mode. Possible operations and
+their general syntax are described below. They are covered in detail in the
+following sections.
+
+- Check whether a flow rule can be created::
+
+ flow validate {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+- Create a flow rule::
+
+ flow create {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+- Destroy specific flow rules::
+
+ flow destroy {port_id} rule {rule_id} [...]
+
+- Destroy all flow rules::
+
+ flow flush {port_id}
+
+- Query an existing flow rule::
+
+ flow query {port_id} {rule_id} {action}
+
+- List existing flow rules sorted by priority, filtered by group
+ identifiers::
+
+ flow list {port_id} [group {group_id}] [...]
+
+Validating flow rules
+~~~~~~~~~~~~~~~~~~~~~
+
+``flow validate`` reports whether a flow rule would be accepted by the
+underlying device in its current state but stops short of creating it. It is
+bound to ``rte_flow_validate()``::
+
+ flow validate {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+If successful, it will show::
+
+ Flow rule validated
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
+This command uses the same parameters as ``flow create``, their format is
+described in `Creating flow rules`_.
+
+Check whether redirecting any Ethernet packet received on port 0 to RX queue
+index 6 is supported::
+
+ testpmd> flow validate 0 ingress pattern eth / end
+ actions queue index 6 / end
+ Flow rule validated
+ testpmd>
+
+Port 0 does not support TCPv6 rules::
+
+ testpmd> flow validate 0 ingress pattern eth / ipv6 / tcp / end
+ actions drop / end
+ Caught error type 9 (specific pattern item): Invalid argument.
+ testpmd>
+
+Creating flow rules
+~~~~~~~~~~~~~~~~~~~
+
+``flow create`` validates and creates the specified flow rule. It is bound
+to ``rte_flow_create()``::
+
+ flow create {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+If successful, it will return a flow rule ID usable with other commands::
+
+ Flow rule #[...] created
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
+Parameters describe in the following order:
+
+- Attributes (*group*, *priority*, *ingress*, *egress* tokens).
+- A matching pattern, starting with the *pattern* token and terminated by an
+ *end* pattern item.
+- Actions, starting with the *actions* token and terminated by an *end*
+ action.
+
+These translate directly to *rte_flow* objects provided as-is to the
+underlying functions.
+
+The shortest valid definition only comprises mandatory tokens::
+
+ testpmd> flow create 0 pattern end actions end
+
+Note that PMDs may refuse rules that essentially do nothing such as this
+one.
+
+**All unspecified object values are automatically initialized to 0.**
+
+Attributes
+^^^^^^^^^^
+
+These tokens affect flow rule attributes (``struct rte_flow_attr``) and are
+specified before the ``pattern`` token.
+
+- ``group {group id}``: priority group.
+- ``priority {level}``: priority level within group.
+- ``ingress``: rule applies to ingress traffic.
+- ``egress``: rule applies to egress traffic.
+
+Each instance of an attribute specified several times overrides the previous
+value as shown below (group 4 is used)::
+
+ testpmd> flow create 0 group 42 group 24 group 4 [...]
+
+Note that once enabled, ``ingress`` and ``egress`` cannot be disabled.
+
+While not specifying a direction is an error, some rules may allow both
+simultaneously.
+
+Most rules affect RX therefore contain the ``ingress`` token::
+
+ testpmd> flow create 0 ingress pattern [...]
+
+Matching pattern
+^^^^^^^^^^^^^^^^
+
+A matching pattern starts after the ``pattern`` token. It is made of pattern
+items and is terminated by a mandatory ``end`` item.
+
+Items are named after their type (*RTE_FLOW_ITEM_TYPE_* from ``enum
+rte_flow_item_type``).
+
+The ``/`` token is used as a separator between pattern items as shown
+below::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end [...]
+
+Note that protocol items like these must be stacked from lowest to highest
+layer to make sense. For instance, the following rule is either invalid or
+unlikely to match any packet::
+
+ testpmd> flow create 0 ingress pattern eth / udp / ipv4 / end [...]
+
+More information on these restrictions can be found in the *rte_flow*
+documentation.
+
+Several items support additional specification structures, for example
+``ipv4`` allows specifying source and destination addresses as follows::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 src is 10.1.1.1
+ dst is 10.2.0.0 / end [...]
+
+This rule matches all IPv4 traffic with the specified properties.
+
+In this example, ``src`` and ``dst`` are field names of the underlying
+``struct rte_flow_item_ipv4`` object. All item properties can be specified
+in a similar fashion.
+
+The ``is`` token means that the subsequent value must be matched exactly,
+and assigns ``spec`` and ``mask`` fields in ``struct rte_flow_item``
+accordingly. Possible assignment tokens are:
+
+- ``is``: match value perfectly (with full bit-mask).
+- ``spec``: match value according to configured bit-mask.
+- ``last``: specify upper bound to establish a range.
+- ``mask``: specify bit-mask with relevant bits set to one.
+- ``prefix``: generate bit-mask from a prefix length.
+
+These yield identical results::
+
+ ipv4 src is 10.1.1.1
+
+::
+
+ ipv4 src spec 10.1.1.1 src mask 255.255.255.255
+
+::
+
+ ipv4 src spec 10.1.1.1 src prefix 32
+
+::
+
+ ipv4 src is 10.1.1.1 src last 10.1.1.1 # range with a single value
+
+::
+
+ ipv4 src is 10.1.1.1 src last 0 # 0 disables range
+
+Inclusive ranges can be defined with ``last``::
+
+ ipv4 src is 10.1.1.1 src last 10.2.3.4 # 10.1.1.1 to 10.2.3.4
+
+Note that ``mask`` affects both ``spec`` and ``last``::
+
+ ipv4 src is 10.1.1.1 src last 10.2.3.4 src mask 255.255.0.0
+ # matches 10.1.0.0 to 10.2.255.255
+
+Properties can be modified multiple times::
+
+ ipv4 src is 10.1.1.1 src is 10.1.2.3 src is 10.2.3.4 # matches 10.2.3.4
+
+::
+
+ ipv4 src is 10.1.1.1 src prefix 24 src prefix 16 # matches 10.1.0.0/16
+
+Pattern items
+^^^^^^^^^^^^^
+
+This section lists supported pattern items and their attributes, if any.
+
+- ``end``: end list of pattern items.
+
+- ``void``: no-op pattern item.
+
+- ``invert``: perform actions when pattern does not match.
+
+- ``any``: match any protocol for the current layer.
+
+ - ``num {unsigned}``: number of layers covered.
+
+- ``pf``: match packets addressed to the physical function.
+
+- ``vf``: match packets addressed to a virtual function ID.
+
+ - ``id {unsigned}``: destination VF ID.
+
+- ``port``: device-specific physical port index to use.
+
+ - ``index {unsigned}``: physical port index.
+
+- ``raw``: match an arbitrary byte string.
+
+ - ``relative {boolean}``: look for pattern after the previous item.
+ - ``search {boolean}``: search pattern from offset (see also limit).
+ - ``offset {integer}``: absolute or relative offset for pattern.
+ - ``limit {unsigned}``: search area limit for start of pattern.
+ - ``pattern {string}``: byte string to look for.
+
+- ``eth``: match Ethernet header.
+
+ - ``dst {MAC-48}``: destination MAC.
+ - ``src {MAC-48}``: source MAC.
+ - ``type {unsigned}``: EtherType.
+
+- ``vlan``: match 802.1Q/ad VLAN tag.
+
+ - ``tpid {unsigned}``: tag protocol identifier.
+ - ``tci {unsigned}``: tag control information.
+
+- ``ipv4``: match IPv4 header.
+
+ - ``src {ipv4 address}``: source address.
+ - ``dst {ipv4 address}``: destination address.
+
+- ``ipv6``: match IPv6 header.
+
+ - ``src {ipv6 address}``: source address.
+ - ``dst {ipv6 address}``: destination address.
+
+- ``icmp``: match ICMP header.
+
+ - ``type {unsigned}``: ICMP packet type.
+ - ``code {unsigned}``: ICMP packet code.
+
+- ``udp``: match UDP header.
+
+ - ``src {unsigned}``: UDP source port.
+ - ``dst {unsigned}``: UDP destination port.
+
+- ``tcp``: match TCP header.
+
+ - ``src {unsigned}``: TCP source port.
+ - ``dst {unsigned}``: TCP destination port.
+
+- ``sctp``: match SCTP header.
+
+ - ``src {unsigned}``: SCTP source port.
+ - ``dst {unsigned}``: SCTP destination port.
+
+- ``vxlan``: match VXLAN header.
+
+ - ``vni {unsigned}``: VXLAN identifier.
+
+Actions list
+^^^^^^^^^^^^
+
+A list of actions starts after the ``actions`` token in the same fashion as
+`Matching pattern`_; actions are separated by ``/`` tokens and the list is
+terminated by a mandatory ``end`` action.
+
+Actions are named after their type (*RTE_FLOW_ACTION_TYPE_* from ``enum
+rte_flow_action_type``).
+
+Dropping all incoming UDPv4 packets can be expressed as follows::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions drop / end
+
+Several actions have configurable properties which must be specified when
+there is no valid default value. For example, ``queue`` requires a target
+queue index.
+
+This rule redirects incoming UDPv4 traffic to queue index 6::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions queue index 6 / end
+
+While this one could be rejected by PMDs (unspecified queue index)::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions queue / end
+
+As defined by *rte_flow*, the list is not ordered, all actions of a given
+rule are performed simultaneously. These are equivalent::
+
+ queue index 6 / void / mark id 42 / end
+
+::
+
+ void / mark id 42 / queue index 6 / end
+
+All actions in a list should have different types, otherwise only the last
+action of a given type is taken into account::
+
+ queue index 4 / queue index 5 / queue index 6 / end # will use queue 6
+
+::
+
+ drop / drop / drop / end # drop is performed only once
+
+::
+
+ mark id 42 / queue index 3 / mark id 24 / end # mark will be 24
+
+Considering they are performed simultaneously, opposite and overlapping
+actions can sometimes be combined when the end result is unambiguous::
+
+ drop / queue index 6 / end # drop has no effect
+
+::
+
+ drop / dup index 6 / end # same as above
+
+::
+
+ queue index 6 / rss queues 6 7 8 / end # queue has no effect
+
+::
+
+ drop / passthru / end # drop has no effect
+
+Note that PMDs may still refuse such combinations.
+
+Actions
+^^^^^^^
+
+This section lists supported actions and their attributes, if any.
+
+- ``end``: end list of actions.
+
+- ``void``: no-op action.
+
+- ``passthru``: let subsequent rule process matched packets.
+
+- ``mark``: attach 32 bit value to packets.
+
+ - ``id {unsigned}``: 32 bit value to return with packets.
+
+- ``flag``: flag packets.
+
+- ``queue``: assign packets to a given queue index.
+
+ - ``index {unsigned}``: queue index to use.
+
+- ``drop``: drop packets (note: passthru has priority).
+
+- ``count``: enable counters for this rule.
+
+- ``dup``: duplicate packets to a given queue index.
+
+ - ``index {unsigned}``: queue index to duplicate packets to.
+
+- ``rss``: spread packets among several queues.
+
+ - ``queues [{unsigned} [...]] end``: queue indices to use.
+
+- ``pf``: redirect packets to physical device function.
+
+- ``vf``: redirect packets to virtual device function.
+
+ - ``original {boolean}``: use original VF ID if possible.
+ - ``id {unsigned}``: VF ID to redirect packets to.
+
+Destroying flow rules
+~~~~~~~~~~~~~~~~~~~~~
+
+``flow destroy`` destroys one or more rules from their rule ID (as returned
+by ``flow create``), this command calls ``rte_flow_destroy()`` as many
+times as necessary::
+
+ flow destroy {port_id} rule {rule_id} [...]
+
+If successful, it will show::
+
+ Flow rule #[...] destroyed
+
+It does not report anything for rule IDs that do not exist. The usual error
+message is shown when a rule cannot be destroyed::
+
+ Caught error type [...] ([...]): [...]
+
+``flow flush`` destroys all rules on a device and does not take extra
+arguments. It is bound to ``rte_flow_flush()``::
+
+ flow flush {port_id}
+
+Any errors are reported as above.
+
+Creating several rules and destroying them::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow destroy 0 rule 0 rule 1
+ Flow rule #1 destroyed
+ Flow rule #0 destroyed
+ testpmd>
+
+The same result can be achieved using ``flow flush``::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow flush 0
+ testpmd>
+
+Non-existent rule IDs are ignored::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow destroy 0 rule 42 rule 10 rule 2
+ testpmd>
+ testpmd> flow destroy 0 rule 0
+ Flow rule #0 destroyed
+ testpmd>
+
+Querying flow rules
+~~~~~~~~~~~~~~~~~~~
+
+``flow query`` queries a specific action of a flow rule having that
+ability. Such actions collect information that can be reported using this
+command. It is bound to ``rte_flow_query()``::
+
+ flow query {port_id} {rule_id} {action}
+
+If successful, it will display either the retrieved data for known actions
+or the following message::
+
+ Cannot display result for action type [...] ([...])
+
+Otherwise, it will complain either that the rule does not exist or that some
+error occurred::
+
+ Flow rule #[...] not found
+
+::
+
+ Caught error type [...] ([...]): [...]
+
+Currently only the ``count`` action is supported. This action reports the
+number of packets that hit the flow rule and the total number of bytes. Its
+output has the following format::
+
+ count:
+ hits_set: [...] # whether "hits" contains a valid value
+ bytes_set: [...] # whether "bytes" contains a valid value
+ hits: [...] # number of packets
+ bytes: [...] # number of bytes
+
+Querying counters for TCPv6 packets redirected to queue 6::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / tcp / end
+ actions queue index 6 / count / end
+ Flow rule #4 created
+ testpmd> flow query 0 4 count
+ count:
+ hits_set: 1
+ bytes_set: 0
+ hits: 386446
+ bytes: 0
+ testpmd>
+
+Listing flow rules
+~~~~~~~~~~~~~~~~~~
+
+``flow list`` lists existing flow rules sorted by priority and optionally
+filtered by group identifiers::
+
+ flow list {port_id} [group {group_id}] [...]
+
+This command only fails with the following message if the device does not
+exist::
+
+ Invalid port [...]
+
+Output consists of a header line followed by a short description of each
+flow rule, one per line. There is no output at all when no flow rules are
+configured on the device::
+
+ ID Group Prio Attr Rule
+ [...] [...] [...] [...] [...]
+
+``Attr`` column flags:
+
+- ``i`` for ``ingress``.
+- ``e`` for ``egress``.
+
+Creating several flow rules and listing them::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 6 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #1 created
+ testpmd> flow create 0 priority 5 ingress pattern eth / ipv4 / udp / end
+ actions rss queues 6 7 8 end / end
+ Flow rule #2 created
+ testpmd> flow list 0
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH IPV4 => QUEUE
+ 1 0 0 i- ETH IPV6 => QUEUE
+ 2 0 5 i- ETH IPV4 UDP => RSS
+ testpmd>
+
+Rules are sorted by priority (i.e. group ID first, then priority level)::
+
+ testpmd> flow list 1
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH => COUNT
+ 6 0 500 i- ETH IPV6 TCP => DROP COUNT
+ 5 0 1000 i- ETH IPV6 ICMP => QUEUE
+ 1 24 0 i- ETH IPV4 UDP => QUEUE
+ 4 24 10 i- ETH IPV4 TCP => DROP
+ 3 24 20 i- ETH IPV4 => DROP
+ 2 24 42 i- ETH IPV4 UDP => QUEUE
+ 7 63 0 i- ETH IPV6 UDP VXLAN => MARK QUEUE
+ testpmd>
+
+Output can be limited to specific groups::
+
+ testpmd> flow list 1 group 0 group 63
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH => COUNT
+ 6 0 500 i- ETH IPV6 TCP => DROP COUNT
+ 5 0 1000 i- ETH IPV6 ICMP => QUEUE
+ 7 63 0 i- ETH IPV6 UDP VXLAN => MARK QUEUE
+ testpmd>
--
2.1.4
^ permalink raw reply related
* [PATCH v4 24/25] app/testpmd: add queue actions to flow command
From: Adrien Mazarguil @ 2016-12-20 18:42 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482257521.git.adrien.mazarguil@6wind.com>
- QUEUE: assign packets to a given queue index.
- DUP: duplicate packets to a given queue index.
- RSS: spread packets among several queues.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 152 +++++++++++++++++++++++++++++++++++++++
1 file changed, 152 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d0b6754..145838e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -156,8 +156,15 @@ enum index {
ACTION_MARK,
ACTION_MARK_ID,
ACTION_FLAG,
+ ACTION_QUEUE,
+ ACTION_QUEUE_INDEX,
ACTION_DROP,
ACTION_COUNT,
+ ACTION_DUP,
+ ACTION_DUP_INDEX,
+ ACTION_RSS,
+ ACTION_RSS_QUEUES,
+ ACTION_RSS_QUEUE,
ACTION_PF,
ACTION_VF,
ACTION_VF_ORIGINAL,
@@ -171,6 +178,14 @@ enum index {
#define ITEM_RAW_SIZE \
(offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
+/** Number of queue[] entries in struct rte_flow_action_rss. */
+#define ACTION_RSS_NUM 32
+
+/** Storage size for struct rte_flow_action_rss including queues. */
+#define ACTION_RSS_SIZE \
+ (offsetof(struct rte_flow_action_rss, queue) + \
+ sizeof(*((struct rte_flow_action_rss *)0)->queue) * ACTION_RSS_NUM)
+
/** Maximum number of subsequent tokens and arguments on the stack. */
#define CTX_STACK_SIZE 16
@@ -487,8 +502,11 @@ static const enum index next_action[] = {
ACTION_PASSTHRU,
ACTION_MARK,
ACTION_FLAG,
+ ACTION_QUEUE,
ACTION_DROP,
ACTION_COUNT,
+ ACTION_DUP,
+ ACTION_RSS,
ACTION_PF,
ACTION_VF,
ZERO,
@@ -500,6 +518,24 @@ static const enum index action_mark[] = {
ZERO,
};
+static const enum index action_queue[] = {
+ ACTION_QUEUE_INDEX,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_dup[] = {
+ ACTION_DUP_INDEX,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_rss[] = {
+ ACTION_RSS_QUEUES,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_vf[] = {
ACTION_VF_ORIGINAL,
ACTION_VF_ID,
@@ -517,6 +553,9 @@ static int parse_vc_spec(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
static int parse_vc_conf(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
+static int parse_vc_action_rss_queue(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -566,6 +605,8 @@ static int comp_port(struct context *, const struct token *,
unsigned int, char *, unsigned int);
static int comp_rule_id(struct context *, const struct token *,
unsigned int, char *, unsigned int);
+static int comp_vc_action_rss_queue(struct context *, const struct token *,
+ unsigned int, char *, unsigned int);
/** Token definitions. */
static const struct token token_list[] = {
@@ -1163,6 +1204,21 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_QUEUE] = {
+ .name = "queue",
+ .help = "assign packets to a given queue index",
+ .priv = PRIV_ACTION(QUEUE,
+ sizeof(struct rte_flow_action_queue)),
+ .next = NEXT(action_queue),
+ .call = parse_vc,
+ },
+ [ACTION_QUEUE_INDEX] = {
+ .name = "index",
+ .help = "queue index to use",
+ .next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+ .call = parse_vc_conf,
+ },
[ACTION_DROP] = {
.name = "drop",
.help = "drop packets (note: passthru has priority)",
@@ -1177,6 +1233,39 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_DUP] = {
+ .name = "dup",
+ .help = "duplicate packets to a given queue index",
+ .priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
+ .next = NEXT(action_dup),
+ .call = parse_vc,
+ },
+ [ACTION_DUP_INDEX] = {
+ .name = "index",
+ .help = "queue index to duplicate packets to",
+ .next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_RSS] = {
+ .name = "rss",
+ .help = "spread packets among several queues",
+ .priv = PRIV_ACTION(RSS, ACTION_RSS_SIZE),
+ .next = NEXT(action_rss),
+ .call = parse_vc,
+ },
+ [ACTION_RSS_QUEUES] = {
+ .name = "queues",
+ .help = "queue indices to use",
+ .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_RSS_QUEUE] = {
+ .name = "{queue}",
+ .help = "queue index",
+ .call = parse_vc_action_rss_queue,
+ .comp = comp_vc_action_rss_queue,
+ },
[ACTION_PF] = {
.name = "pf",
.help = "redirect packets to physical device function",
@@ -1556,6 +1645,51 @@ parse_vc_conf(struct context *ctx, const struct token *token,
return len;
}
+/**
+ * Parse queue field for RSS action.
+ *
+ * Valid tokens are queue indices and the "end" token.
+ */
+static int
+parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
+ int ret;
+ int i;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ACTION_RSS_QUEUE)
+ return -1;
+ i = ctx->objdata >> 16;
+ if (!strncmp(str, "end", len)) {
+ ctx->objdata &= 0xffff;
+ return len;
+ }
+ if (i >= ACTION_RSS_NUM)
+ return -1;
+ if (push_args(ctx, ARGS_ENTRY(struct rte_flow_action_rss, queue[i])))
+ return -1;
+ ret = parse_int(ctx, token, str, len, NULL, 0);
+ if (ret < 0) {
+ pop_args(ctx);
+ return -1;
+ }
+ ++i;
+ ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
+ /* Repeat token. */
+ if (ctx->next_num == RTE_DIM(ctx->next))
+ return -1;
+ ctx->next[ctx->next_num++] = next;
+ if (!ctx->object)
+ return len;
+ ((struct rte_flow_action_rss *)ctx->object)->num = i;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
@@ -2130,6 +2264,24 @@ comp_rule_id(struct context *ctx, const struct token *token,
return i;
}
+/** Complete queue field for RSS action. */
+static int
+comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ static const char *const str[] = { "", "end", NULL };
+ unsigned int i;
+
+ (void)ctx;
+ (void)token;
+ for (i = 0; str[i] != NULL; ++i)
+ if (buf && i == ent)
+ return snprintf(buf, size, "%s", str[i]);
+ if (buf)
+ return -1;
+ return i;
+}
+
/** Internal context. */
static struct context cmd_flow_context;
--
2.1.4
^ permalink raw reply related
* [PATCH v4 23/25] app/testpmd: add various actions to flow command
From: Adrien Mazarguil @ 2016-12-20 18:42 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482257521.git.adrien.mazarguil@6wind.com>
- MARK: attach 32 bit value to packets.
- FLAG: flag packets.
- DROP: drop packets.
- COUNT: enable counters for a rule.
- PF: redirect packets to physical device function.
- VF: redirect packets to virtual device function.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 121 +++++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e63982f..d0b6754 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -153,6 +153,15 @@ enum index {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+ ACTION_MARK,
+ ACTION_MARK_ID,
+ ACTION_FLAG,
+ ACTION_DROP,
+ ACTION_COUNT,
+ ACTION_PF,
+ ACTION_VF,
+ ACTION_VF_ORIGINAL,
+ ACTION_VF_ID,
};
/** Size of pattern[] field in struct rte_flow_item_raw. */
@@ -476,6 +485,25 @@ static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+ ACTION_MARK,
+ ACTION_FLAG,
+ ACTION_DROP,
+ ACTION_COUNT,
+ ACTION_PF,
+ ACTION_VF,
+ ZERO,
+};
+
+static const enum index action_mark[] = {
+ ACTION_MARK_ID,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_vf[] = {
+ ACTION_VF_ORIGINAL,
+ ACTION_VF_ID,
+ ACTION_NEXT,
ZERO,
};
@@ -487,6 +515,8 @@ static int parse_vc(struct context *, const struct token *,
void *, unsigned int);
static int parse_vc_spec(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf(struct context *, const struct token *,
+ const char *, unsigned int, void *, unsigned int);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -1112,6 +1142,70 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_MARK] = {
+ .name = "mark",
+ .help = "attach 32 bit value to packets",
+ .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
+ .next = NEXT(action_mark),
+ .call = parse_vc,
+ },
+ [ACTION_MARK_ID] = {
+ .name = "id",
+ .help = "32 bit value to return with packets",
+ .next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_FLAG] = {
+ .name = "flag",
+ .help = "flag packets",
+ .priv = PRIV_ACTION(FLAG, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_DROP] = {
+ .name = "drop",
+ .help = "drop packets (note: passthru has priority)",
+ .priv = PRIV_ACTION(DROP, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_COUNT] = {
+ .name = "count",
+ .help = "enable counters for this rule",
+ .priv = PRIV_ACTION(COUNT, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_PF] = {
+ .name = "pf",
+ .help = "redirect packets to physical device function",
+ .priv = PRIV_ACTION(PF, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_VF] = {
+ .name = "vf",
+ .help = "redirect packets to virtual device function",
+ .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+ .next = NEXT(action_vf),
+ .call = parse_vc,
+ },
+ [ACTION_VF_ORIGINAL] = {
+ .name = "original",
+ .help = "use original VF ID if possible",
+ .next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
+ original, 1)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_VF_ID] = {
+ .name = "id",
+ .help = "VF ID to redirect packets to",
+ .next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
@@ -1435,6 +1529,33 @@ parse_vc_spec(struct context *ctx, const struct token *token,
return len;
}
+/** Parse action configuration field. */
+static int
+parse_vc_conf(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct buffer *out = buf;
+ struct rte_flow_action *action;
+
+ (void)size;
+ /* Token name must match. */
+ if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ return -1;
+ /* Nothing else to do if there is no buffer. */
+ if (!out)
+ return len;
+ if (!out->args.vc.actions_n)
+ return -1;
+ action = &out->args.vc.actions[out->args.vc.actions_n - 1];
+ /* Point to selected object. */
+ ctx->object = out->args.vc.data;
+ ctx->objmask = NULL;
+ /* Update configuration pointer. */
+ action->conf = ctx->object;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
--
2.1.4
^ permalink raw reply related
* [PATCH v4 22/25] app/testpmd: add L4 items to flow command
From: Adrien Mazarguil @ 2016-12-20 18:42 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482257521.git.adrien.mazarguil@6wind.com>
Add the ability to match a few properties of common L4[.5] protocol
headers:
- ICMP: type and code.
- UDP: source and destination ports.
- TCP: source and destination ports.
- SCTP: source and destination ports.
- VXLAN: network identifier.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 163 +++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index dfb6d6f..e63982f 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -132,6 +132,20 @@ enum index {
ITEM_IPV6,
ITEM_IPV6_SRC,
ITEM_IPV6_DST,
+ ITEM_ICMP,
+ ITEM_ICMP_TYPE,
+ ITEM_ICMP_CODE,
+ ITEM_UDP,
+ ITEM_UDP_SRC,
+ ITEM_UDP_DST,
+ ITEM_TCP,
+ ITEM_TCP_SRC,
+ ITEM_TCP_DST,
+ ITEM_SCTP,
+ ITEM_SCTP_SRC,
+ ITEM_SCTP_DST,
+ ITEM_VXLAN,
+ ITEM_VXLAN_VNI,
/* Validate/create actions. */
ACTIONS,
@@ -359,6 +373,11 @@ static const enum index next_item[] = {
ITEM_VLAN,
ITEM_IPV4,
ITEM_IPV6,
+ ITEM_ICMP,
+ ITEM_UDP,
+ ITEM_TCP,
+ ITEM_SCTP,
+ ITEM_VXLAN,
ZERO,
};
@@ -419,6 +438,40 @@ static const enum index item_ipv6[] = {
ZERO,
};
+static const enum index item_icmp[] = {
+ ITEM_ICMP_TYPE,
+ ITEM_ICMP_CODE,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_udp[] = {
+ ITEM_UDP_SRC,
+ ITEM_UDP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_tcp[] = {
+ ITEM_TCP_SRC,
+ ITEM_TCP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_sctp[] = {
+ ITEM_SCTP_SRC,
+ ITEM_SCTP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_vxlan[] = {
+ ITEM_VXLAN_VNI,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -930,6 +983,103 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
hdr.dst_addr)),
},
+ [ITEM_ICMP] = {
+ .name = "icmp",
+ .help = "match ICMP header",
+ .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
+ .next = NEXT(item_icmp),
+ .call = parse_vc,
+ },
+ [ITEM_ICMP_TYPE] = {
+ .name = "type",
+ .help = "ICMP packet type",
+ .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+ hdr.icmp_type)),
+ },
+ [ITEM_ICMP_CODE] = {
+ .name = "code",
+ .help = "ICMP packet code",
+ .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+ hdr.icmp_code)),
+ },
+ [ITEM_UDP] = {
+ .name = "udp",
+ .help = "match UDP header",
+ .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
+ .next = NEXT(item_udp),
+ .call = parse_vc,
+ },
+ [ITEM_UDP_SRC] = {
+ .name = "src",
+ .help = "UDP source port",
+ .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+ hdr.src_port)),
+ },
+ [ITEM_UDP_DST] = {
+ .name = "dst",
+ .help = "UDP destination port",
+ .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+ hdr.dst_port)),
+ },
+ [ITEM_TCP] = {
+ .name = "tcp",
+ .help = "match TCP header",
+ .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
+ .next = NEXT(item_tcp),
+ .call = parse_vc,
+ },
+ [ITEM_TCP_SRC] = {
+ .name = "src",
+ .help = "TCP source port",
+ .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+ hdr.src_port)),
+ },
+ [ITEM_TCP_DST] = {
+ .name = "dst",
+ .help = "TCP destination port",
+ .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+ hdr.dst_port)),
+ },
+ [ITEM_SCTP] = {
+ .name = "sctp",
+ .help = "match SCTP header",
+ .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
+ .next = NEXT(item_sctp),
+ .call = parse_vc,
+ },
+ [ITEM_SCTP_SRC] = {
+ .name = "src",
+ .help = "SCTP source port",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.src_port)),
+ },
+ [ITEM_SCTP_DST] = {
+ .name = "dst",
+ .help = "SCTP destination port",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.dst_port)),
+ },
+ [ITEM_VXLAN] = {
+ .name = "vxlan",
+ .help = "match VXLAN header",
+ .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
+ .next = NEXT(item_vxlan),
+ .call = parse_vc,
+ },
+ [ITEM_VXLAN_VNI] = {
+ .name = "vni",
+ .help = "VXLAN identifier",
+ .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1491,6 +1641,19 @@ parse_int(struct context *ctx, const struct token *token,
case sizeof(uint16_t):
*(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
break;
+ case sizeof(uint8_t [3]):
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+ if (!arg->hton) {
+ ((uint8_t *)buf)[0] = u;
+ ((uint8_t *)buf)[1] = u >> 8;
+ ((uint8_t *)buf)[2] = u >> 16;
+ break;
+ }
+#endif
+ ((uint8_t *)buf)[0] = u >> 16;
+ ((uint8_t *)buf)[1] = u >> 8;
+ ((uint8_t *)buf)[2] = u;
+ break;
case sizeof(uint32_t):
*(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
break;
--
2.1.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