[dpdk-dev] [PATCH v2 02/17] net/i40e: store tunnel filter
Tiwei Bie
tiwei.bie at intel.com
Wed Dec 28 04:27:27 CET 2016
On Tue, Dec 27, 2016 at 02:26:09PM +0800, Beilei Xing wrote:
> Currently there's no tunnel filter stored in SW.
> This patch stores tunnel filter in SW with cuckoo
> hash, also adds protection if a tunnel filter has
> been added.
>
> Signed-off-by: Beilei Xing <beilei.xing at intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.c | 167 ++++++++++++++++++++++++++++++++++++++++-
> drivers/net/i40e/i40e_ethdev.h | 27 +++++++
> 2 files changed, 191 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 80dd8d7..c012d5d 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
[...]
> @@ -1267,6 +1314,7 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> pci_dev = dev->pci_dev;
> ethertype_rule = &pf->ethertype;
> + tunnel_rule = &pf->tunnel;
>
> if (hw->adapter_stopped == 0)
> i40e_dev_close(dev);
> @@ -1283,6 +1331,17 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
> rte_free(p_ethertype);
> }
>
> + /* Remove all tunnel director rules and hash */
> + if (tunnel_rule->hash_map)
> + rte_free(tunnel_rule->hash_map);
> + if (tunnel_rule->hash_table)
> + rte_hash_free(tunnel_rule->hash_table);
> +
> + while ((p_tunnel = TAILQ_FIRST(&tunnel_rule->tunnel_list))) {
There is a redundant pair of parentheses, or you should compare with
NULL.
> + TAILQ_REMOVE(&tunnel_rule->tunnel_list, p_tunnel, rules);
> + rte_free(p_tunnel);
> + }
> +
> dev->dev_ops = NULL;
> dev->rx_pkt_burst = NULL;
> dev->tx_pkt_burst = NULL;
> @@ -6482,6 +6541,81 @@ i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag)
> return 0;
> }
>
> +/* Convert tunnel filter structure */
> +static int
> +i40e_tunnel_filter_convert(struct i40e_aqc_add_remove_cloud_filters_element_data
> + *cld_filter,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + ether_addr_copy((struct ether_addr *)&cld_filter->outer_mac,
> + (struct ether_addr *)&tunnel_filter->input.outer_mac);
> + ether_addr_copy((struct ether_addr *)&cld_filter->inner_mac,
> + (struct ether_addr *)&tunnel_filter->input.inner_mac);
> + tunnel_filter->input.inner_vlan = cld_filter->inner_vlan;
> + tunnel_filter->input.flags = cld_filter->flags;
> + tunnel_filter->input.tenant_id = cld_filter->tenant_id;
> + tunnel_filter->queue = cld_filter->queue_number;
> +
> + return 0;
> +}
> +
> +/* Check if there exists the tunnel filter */
> +static struct i40e_tunnel_filter *
> +i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule,
> + const struct i40e_tunnel_filter_input *input)
> +{
> + int ret = 0;
> +
The initialization is meaningless, as it will be written by the below
assignment unconditionally.
> + ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input);
> + if (ret < 0)
> + return NULL;
> +
> + return tunnel_rule->hash_map[ret];
> +}
> +
> +/* Add a tunnel filter into the SW list */
> +static int
> +i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_add_key(tunnel_rule->hash_table,
> + &tunnel_filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to insert tunnel filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + tunnel_rule->hash_map[ret] = tunnel_filter;
> +
> + TAILQ_INSERT_TAIL(&tunnel_rule->tunnel_list, tunnel_filter, rules);
> +
> + return 0;
> +}
> +
> +/* Delete a tunnel filter from the SW list */
> +static int
> +i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
> + struct i40e_tunnel_filter *tunnel_filter)
> +{
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + int ret = 0;
> +
Same here.
> + ret = rte_hash_del_key(tunnel_rule->hash_table,
> + &tunnel_filter->input);
> + if (ret < 0)
> + PMD_DRV_LOG(ERR,
> + "Failed to delete tunnel filter to hash table %d!",
> + ret);
Function should return when ret < 0.
> + tunnel_rule->hash_map[ret] = NULL;
> +
> + TAILQ_REMOVE(&tunnel_rule->tunnel_list, tunnel_filter, rules);
> + rte_free(tunnel_filter);
> +
> + return 0;
> +}
> +
> static int
> i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> struct rte_eth_tunnel_filter_conf *tunnel_filter,
> @@ -6497,6 +6631,8 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> struct i40e_vsi *vsi = pf->main_vsi;
> struct i40e_aqc_add_remove_cloud_filters_element_data *cld_filter;
> struct i40e_aqc_add_remove_cloud_filters_element_data *pfilter;
> + struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
> + struct i40e_tunnel_filter *tunnel, *node;
>
> cld_filter = rte_zmalloc("tunnel_filter",
> sizeof(struct i40e_aqc_add_remove_cloud_filters_element_data),
> @@ -6559,11 +6695,36 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
> pfilter->tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id);
> pfilter->queue_number = rte_cpu_to_le_16(tunnel_filter->queue_id);
>
> - if (add)
> + tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
> + i40e_tunnel_filter_convert(cld_filter, tunnel);
> + node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &tunnel->input);
> + if (add && node) {
> + PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
> + rte_free(tunnel);
> + return -EINVAL;
> + } else if (!add && !node) {
When `if (add && node)' is true, function will return. There is no need
to use `else' here.
Best regards,
Tiwei Bie
More information about the dev
mailing list