net/mrvl: support classifier
Add classifier configuration support via rte_flow api. Signed-off-by: Natalie Samsonov <nsamsono@marvell.com> Signed-off-by: Tomasz Duszynski <tdu@semihalf.com>
This commit is contained in:
parent
d7af79bba5
commit
7235341d75
@ -113,6 +113,9 @@ Prerequisites
|
||||
approval has been granted, library can be found by typing ``musdk`` in
|
||||
the search box.
|
||||
|
||||
To get better understanding of the library one can consult documentation
|
||||
available in the ``doc`` top level directory of the MUSDK sources.
|
||||
|
||||
MUSDK must be configured with the following features:
|
||||
|
||||
.. code-block:: console
|
||||
@ -318,6 +321,171 @@ the path to the MUSDK installation directory needs to be exported.
|
||||
sed -ri 's,(MRVL_PMD=)n,\1y,' build/.config
|
||||
make
|
||||
|
||||
Flow API
|
||||
--------
|
||||
|
||||
PPv2 offers packet classification capabilities via classifier engine which
|
||||
can be configured via generic flow API offered by DPDK.
|
||||
|
||||
Supported flow actions
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Following flow action items are supported by the driver:
|
||||
|
||||
* DROP
|
||||
* QUEUE
|
||||
|
||||
Supported flow items
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Following flow items and their respective fields are supported by the driver:
|
||||
|
||||
* ETH
|
||||
|
||||
* source MAC
|
||||
* destination MAC
|
||||
* ethertype
|
||||
|
||||
* VLAN
|
||||
|
||||
* PCP
|
||||
* VID
|
||||
|
||||
* IPV4
|
||||
|
||||
* DSCP
|
||||
* protocol
|
||||
* source address
|
||||
* destination address
|
||||
|
||||
* IPV6
|
||||
|
||||
* flow label
|
||||
* next header
|
||||
* source address
|
||||
* destination address
|
||||
|
||||
* UDP
|
||||
|
||||
* source port
|
||||
* destination port
|
||||
|
||||
* TCP
|
||||
|
||||
* source port
|
||||
* destination port
|
||||
|
||||
Classifier match engine
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Classifier has an internal match engine which can be configured to
|
||||
operate in either exact or maskable mode.
|
||||
|
||||
Mode is selected upon creation of the first unique flow rule as follows:
|
||||
|
||||
* maskable, if key size is up to 8 bytes.
|
||||
* exact, otherwise, i.e for keys bigger than 8 bytes.
|
||||
|
||||
Where the key size equals the number of bytes of all fields specified
|
||||
in the flow items.
|
||||
|
||||
.. table:: Examples of key size calculation
|
||||
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| Flow pattern | Key size in bytes | Used engine |
|
||||
+============================================================================+===================+=============+
|
||||
| ETH (destination MAC) / VLAN (VID) | 6 + 2 = 8 | Maskable |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| VLAN (VID) / IPV4 (source address) | 2 + 4 = 6 | Maskable |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| TCP (source port, destination port) | 2 + 2 = 4 | Maskable |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| VLAN (priority) / IPV4 (source address) | 1 + 4 = 5 | Maskable |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| IPV4 (destination address) / UDP (source port, destination port) | 6 + 2 + 2 = 10 | Exact |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| VLAN (VID) / IPV6 (flow label, destination address) | 2 + 3 + 16 = 21 | Exact |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| IPV4 (DSCP, source address, destination address) | 1 + 4 + 4 = 9 | Exact |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
| IPV6 (flow label, source address, destination address) | 3 + 16 + 16 = 35 | Exact |
|
||||
+----------------------------------------------------------------------------+-------------------+-------------+
|
||||
|
||||
From the user perspective maskable mode means that masks specified
|
||||
via flow rules are respected. In case of exact match mode, masks
|
||||
which do not provide exact matching (all bits masked) are ignored.
|
||||
|
||||
If the flow matches more than one classifier rule the first
|
||||
(with the lowest index) matched takes precedence.
|
||||
|
||||
Flow rules usage example
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before proceeding run testpmd user application:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./testpmd --vdev=net_mrvl,iface=eth0,iface=eth2 -c 3 -- -i --p 3 -a --disable-hw-vlan-strip
|
||||
|
||||
Example #1
|
||||
^^^^^^^^^^
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd> flow create 0 ingress pattern eth src is 10:11:12:13:14:15 / end actions drop / end
|
||||
|
||||
In this case key size is 6 bytes thus maskable type is selected. Testpmd
|
||||
will set mask to ff:ff:ff:ff:ff:ff i.e traffic explicitly matching
|
||||
above rule will be dropped.
|
||||
|
||||
Example #2
|
||||
^^^^^^^^^^
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd> flow create 0 ingress pattern ipv4 src spec 10.10.10.0 src mask 255.255.255.0 / tcp src spec 0x10 src mask 0x10 / end action drop / end
|
||||
|
||||
In this case key size is 8 bytes thus maskable type is selected.
|
||||
Flows which have IPv4 source addresses ranging from 10.10.10.0 to 10.10.10.255
|
||||
and tcp source port set to 16 will be dropped.
|
||||
|
||||
Example #3
|
||||
^^^^^^^^^^
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd> flow create 0 ingress pattern vlan vid spec 0x10 vid mask 0x10 / ipv4 src spec 10.10.1.1 src mask 255.255.0.0 dst spec 11.11.11.1 dst mask 255.255.255.0 / end actions drop / end
|
||||
|
||||
In this case key size is 10 bytes thus exact type is selected.
|
||||
Even though each item has partial mask set, masks will be ignored.
|
||||
As a result only flows with VID set to 16 and IPv4 source and destination
|
||||
addresses set to 10.10.1.1 and 11.11.11.1 respectively will be dropped.
|
||||
|
||||
Limitations
|
||||
~~~~~~~~~~~
|
||||
|
||||
Following limitations need to be taken into account while creating flow rules:
|
||||
|
||||
* For IPv4 exact match type the key size must be up to 12 bytes.
|
||||
* For IPv6 exact match type the key size must be up to 36 bytes.
|
||||
* Following fields cannot be partially masked (all masks are treated as
|
||||
if they were exact):
|
||||
|
||||
* ETH: ethertype
|
||||
* VLAN: PCP, VID
|
||||
* IPv4: protocol
|
||||
* IPv6: next header
|
||||
* TCP/UDP: source port, destination port
|
||||
|
||||
* Only one classifier table can be created thus all rules in the table
|
||||
have to match table format. Table format is set during creation of
|
||||
the first unique flow rule.
|
||||
* Up to 5 fields can be specified per flow rule.
|
||||
* Up to 20 flow rules can be added.
|
||||
|
||||
For additional information about classifier please consult
|
||||
``doc/musdk_cls_user_guide.txt``.
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
|
@ -37,5 +37,6 @@ LDLIBS += -lrte_bus_vdev
|
||||
# library source files
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MRVL_PMD) += mrvl_ethdev.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MRVL_PMD) += mrvl_qos.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MRVL_PMD) += mrvl_flow.c
|
||||
|
||||
include $(RTE_SDK)/mk/rte.lib.mk
|
||||
|
@ -659,6 +659,10 @@ mrvl_dev_stop(struct rte_eth_dev *dev)
|
||||
mrvl_dev_set_link_down(dev);
|
||||
mrvl_flush_rx_queues(dev);
|
||||
mrvl_flush_tx_shadow_queues(dev);
|
||||
if (priv->cls_tbl) {
|
||||
pp2_cls_tbl_deinit(priv->cls_tbl);
|
||||
priv->cls_tbl = NULL;
|
||||
}
|
||||
if (priv->qos_tbl) {
|
||||
pp2_cls_qos_tbl_deinit(priv->qos_tbl);
|
||||
priv->qos_tbl = NULL;
|
||||
@ -784,6 +788,9 @@ mrvl_promiscuous_enable(struct rte_eth_dev *dev)
|
||||
if (!priv->ppio)
|
||||
return;
|
||||
|
||||
if (priv->isolated)
|
||||
return;
|
||||
|
||||
ret = pp2_ppio_set_promisc(priv->ppio, 1);
|
||||
if (ret)
|
||||
RTE_LOG(ERR, PMD, "Failed to enable promiscuous mode\n");
|
||||
@ -804,6 +811,9 @@ mrvl_allmulticast_enable(struct rte_eth_dev *dev)
|
||||
if (!priv->ppio)
|
||||
return;
|
||||
|
||||
if (priv->isolated)
|
||||
return;
|
||||
|
||||
ret = pp2_ppio_set_mc_promisc(priv->ppio, 1);
|
||||
if (ret)
|
||||
RTE_LOG(ERR, PMD, "Failed enable all-multicast mode\n");
|
||||
@ -867,6 +877,9 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
|
||||
if (!priv->ppio)
|
||||
return;
|
||||
|
||||
if (priv->isolated)
|
||||
return;
|
||||
|
||||
ret = pp2_ppio_remove_mac_addr(priv->ppio,
|
||||
dev->data->mac_addrs[index].addr_bytes);
|
||||
if (ret) {
|
||||
@ -899,6 +912,9 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
|
||||
char buf[ETHER_ADDR_FMT_SIZE];
|
||||
int ret;
|
||||
|
||||
if (priv->isolated)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (index == 0)
|
||||
/* For setting index 0, mrvl_mac_addr_set() should be used.*/
|
||||
return -1;
|
||||
@ -946,6 +962,9 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
|
||||
if (!priv->ppio)
|
||||
return;
|
||||
|
||||
if (priv->isolated)
|
||||
return;
|
||||
|
||||
ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
|
||||
if (ret) {
|
||||
char buf[ETHER_ADDR_FMT_SIZE];
|
||||
@ -1227,6 +1246,9 @@ mrvl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
|
||||
if (!priv->ppio)
|
||||
return -EPERM;
|
||||
|
||||
if (priv->isolated)
|
||||
return -ENOTSUP;
|
||||
|
||||
return on ? pp2_ppio_add_vlan(priv->ppio, vlan_id) :
|
||||
pp2_ppio_remove_vlan(priv->ppio, vlan_id);
|
||||
}
|
||||
@ -1580,6 +1602,9 @@ mrvl_rss_hash_update(struct rte_eth_dev *dev,
|
||||
{
|
||||
struct mrvl_priv *priv = dev->data->dev_private;
|
||||
|
||||
if (priv->isolated)
|
||||
return -ENOTSUP;
|
||||
|
||||
return mrvl_configure_rss(priv, rss_conf);
|
||||
}
|
||||
|
||||
@ -1616,6 +1641,39 @@ mrvl_rss_hash_conf_get(struct rte_eth_dev *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DPDK callback to get rte_flow callbacks.
|
||||
*
|
||||
* @param dev
|
||||
* Pointer to the device structure.
|
||||
* @param filer_type
|
||||
* Flow filter type.
|
||||
* @param filter_op
|
||||
* Flow filter operation.
|
||||
* @param arg
|
||||
* Pointer to pass the flow ops.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, negative error value otherwise.
|
||||
*/
|
||||
static int
|
||||
mrvl_eth_filter_ctrl(struct rte_eth_dev *dev __rte_unused,
|
||||
enum rte_filter_type filter_type,
|
||||
enum rte_filter_op filter_op, void *arg)
|
||||
{
|
||||
switch (filter_type) {
|
||||
case RTE_ETH_FILTER_GENERIC:
|
||||
if (filter_op != RTE_ETH_FILTER_GET)
|
||||
return -EINVAL;
|
||||
*(const void **)arg = &mrvl_flow_ops;
|
||||
return 0;
|
||||
default:
|
||||
RTE_LOG(WARNING, PMD, "Filter type (%d) not supported",
|
||||
filter_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct eth_dev_ops mrvl_ops = {
|
||||
.dev_configure = mrvl_dev_configure,
|
||||
.dev_start = mrvl_dev_start,
|
||||
@ -1645,6 +1703,7 @@ static const struct eth_dev_ops mrvl_ops = {
|
||||
.tx_queue_release = mrvl_tx_queue_release,
|
||||
.rss_hash_update = mrvl_rss_hash_update,
|
||||
.rss_hash_conf_get = mrvl_rss_hash_conf_get,
|
||||
.filter_ctrl = mrvl_eth_filter_ctrl
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define _MRVL_ETHDEV_H_
|
||||
|
||||
#include <rte_spinlock.h>
|
||||
#include <rte_flow_driver.h>
|
||||
|
||||
#include <env/mv_autogen_comp_flags.h>
|
||||
#include <drivers/mv_pp2.h>
|
||||
@ -80,12 +81,21 @@ struct mrvl_priv {
|
||||
uint8_t rss_hf_tcp;
|
||||
uint8_t uc_mc_flushed;
|
||||
uint8_t vlan_flushed;
|
||||
uint8_t isolated;
|
||||
|
||||
struct pp2_ppio_params ppio_params;
|
||||
struct pp2_cls_qos_tbl_params qos_tbl_params;
|
||||
struct pp2_cls_tbl *qos_tbl;
|
||||
uint16_t nb_rx_queues;
|
||||
|
||||
struct pp2_cls_tbl_params cls_tbl_params;
|
||||
struct pp2_cls_tbl *cls_tbl;
|
||||
uint32_t cls_tbl_pattern;
|
||||
LIST_HEAD(mrvl_flows, rte_flow) flows;
|
||||
|
||||
struct pp2_cls_plcr *policer;
|
||||
};
|
||||
|
||||
/** Flow operations forward declaration. */
|
||||
extern const struct rte_flow_ops mrvl_flow_ops;
|
||||
#endif /* _MRVL_ETHDEV_H_ */
|
||||
|
2759
drivers/net/mrvl/mrvl_flow.c
Normal file
2759
drivers/net/mrvl/mrvl_flow.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user