net/hinic: flush flow director filter

Supports to flush fdir filter.
Destroy all flow rules associated with a port on hinic.

Signed-off-by: Xiaoyun Wang <cloud.wangxiaoyun@huawei.com>
This commit is contained in:
Xiaoyun Wang 2019-10-10 22:51:55 +08:00 committed by Ferruh Yigit
parent f4ca3fd54c
commit 1742421b9e
3 changed files with 158 additions and 1 deletions

View File

@ -341,6 +341,9 @@ static int hinic_dev_configure(struct rte_eth_dev *dev)
return err;
}
/*clear fdir filter flag in function table*/
hinic_free_fdir_filter(nic_dev);
return HINIC_OK;
}
@ -1115,6 +1118,8 @@ static void hinic_dev_stop(struct rte_eth_dev *dev)
/* clean root context */
hinic_free_qp_ctxts(nic_dev->hwdev);
hinic_free_fdir_filter(nic_dev);
/* free mbuf */
hinic_free_all_rx_mbuf(dev);
hinic_free_all_tx_mbuf(dev);
@ -2816,6 +2821,7 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev)
struct rte_pci_device *pci_dev;
struct rte_ether_addr *eth_addr;
struct hinic_nic_dev *nic_dev;
struct hinic_filter_info *filter_info;
u32 mac_size;
int rc;
@ -2907,6 +2913,16 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev)
}
hinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
/* initialize filter info */
filter_info = &nic_dev->filter;
memset(filter_info, 0, sizeof(struct hinic_filter_info));
/* initialize 5tuple filter list */
TAILQ_INIT(&filter_info->fivetuple_list);
TAILQ_INIT(&nic_dev->filter_ntuple_list);
TAILQ_INIT(&nic_dev->filter_ethertype_list);
TAILQ_INIT(&nic_dev->filter_fdir_rule_list);
TAILQ_INIT(&nic_dev->hinic_flow_list);
hinic_set_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
PMD_DRV_LOG(INFO, "Initialize %s in primary successfully",
eth_dev->data->name);

View File

@ -173,7 +173,6 @@ struct hinic_nic_dev {
u32 rx_mode_status; /* promisc or allmulticast */
unsigned long dev_status;
/* dpdk only */
char proc_dev_name[HINIC_DEV_NAME_LEN];
/* PF0->COS4, PF1->COS5, PF2->COS6, PF3->COS7,
* vf: the same with associate pf
@ -187,4 +186,6 @@ struct hinic_nic_dev {
struct hinic_flow_mem_list hinic_flow_list;
};
void hinic_free_fdir_filter(struct hinic_nic_dev *nic_dev);
#endif /* _HINIC_PMD_ETHDEV_H_ */

View File

@ -1456,6 +1456,40 @@ static int hinic_set_vrrp_tcam(struct hinic_nic_dev *nic_dev)
&vrrp_rule, &vrrp_action);
}
/**
* Clear all fdir configuration.
*
* @param nic_dev
* The hardware interface of a Ethernet device.
*
* @return
* 0 on success,
* negative error value otherwise.
*/
void hinic_free_fdir_filter(struct hinic_nic_dev *nic_dev)
{
struct hinic_filter_info *filter_info =
HINIC_DEV_PRIVATE_TO_FILTER_INFO(nic_dev);
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_BGPD_DPORT_TYPE)))
hinic_clear_fdir_tcam(nic_dev->hwdev, TCAM_PKT_BGP_DPORT);
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_BGPD_SPORT_TYPE)))
hinic_clear_fdir_tcam(nic_dev->hwdev, TCAM_PKT_BGP_SPORT);
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_VRRP_TYPE)))
hinic_clear_fdir_tcam(nic_dev->hwdev, TCAM_PKT_VRRP);
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_LACP_TYPE)))
hinic_clear_fdir_tcam(nic_dev->hwdev, TCAM_PKT_LACP);
hinic_set_fdir_filter(nic_dev->hwdev, 0, 0, 0, false);
}
static int
hinic_filter_info_init(struct hinic_5tuple_filter *filter,
struct hinic_filter_info *filter_info)
@ -2238,8 +2272,114 @@ static int hinic_flow_destroy(struct rte_eth_dev *dev,
return ret;
}
/* Remove all the n-tuple filters */
static void hinic_clear_all_ntuple_filter(struct rte_eth_dev *dev)
{
struct hinic_filter_info *filter_info =
HINIC_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
struct hinic_5tuple_filter *p_5tuple;
while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
hinic_remove_5tuple_filter(dev, p_5tuple);
}
/* Remove all the ether type filters */
static void hinic_clear_all_ethertype_filter(struct rte_eth_dev *dev)
{
struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
struct hinic_filter_info *filter_info =
HINIC_DEV_PRIVATE_TO_FILTER_INFO(nic_dev);
int ret = 0;
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_LACP_TYPE))) {
hinic_ethertype_filter_remove(filter_info,
HINIC_PKT_TYPE_FIND_ID(PKT_LACP_TYPE));
ret = hinic_set_fdir_filter(nic_dev->hwdev, PKT_LACP_TYPE,
filter_info->qid, false, true);
(void)hinic_clear_fdir_tcam(nic_dev->hwdev, TCAM_PKT_LACP);
}
if (filter_info->type_mask &
(1 << HINIC_PKT_TYPE_FIND_ID(PKT_ARP_TYPE))) {
hinic_ethertype_filter_remove(filter_info,
HINIC_PKT_TYPE_FIND_ID(PKT_ARP_TYPE));
ret = hinic_set_fdir_filter(nic_dev->hwdev, PKT_ARP_TYPE,
filter_info->qid, false, true);
}
if (ret)
PMD_DRV_LOG(ERR, "Clear ethertype failed, filter type: 0x%x",
filter_info->pkt_type);
}
/* Remove all the ether type filters */
static void hinic_clear_all_fdir_filter(struct rte_eth_dev *dev)
{
struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
(void)hinic_set_fdir_filter(nic_dev->hwdev, 0, 0, 0, false);
}
static void hinic_filterlist_flush(struct rte_eth_dev *dev)
{
struct hinic_ntuple_filter_ele *ntuple_filter_ptr;
struct hinic_ethertype_filter_ele *ethertype_filter_ptr;
struct hinic_fdir_rule_ele *fdir_rule_ptr;
struct hinic_flow_mem *hinic_flow_mem_ptr;
struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
while ((ntuple_filter_ptr =
TAILQ_FIRST(&nic_dev->filter_ntuple_list))) {
TAILQ_REMOVE(&nic_dev->filter_ntuple_list, ntuple_filter_ptr,
entries);
rte_free(ntuple_filter_ptr);
}
while ((ethertype_filter_ptr =
TAILQ_FIRST(&nic_dev->filter_ethertype_list))) {
TAILQ_REMOVE(&nic_dev->filter_ethertype_list,
ethertype_filter_ptr,
entries);
rte_free(ethertype_filter_ptr);
}
while ((fdir_rule_ptr =
TAILQ_FIRST(&nic_dev->filter_fdir_rule_list))) {
TAILQ_REMOVE(&nic_dev->filter_fdir_rule_list, fdir_rule_ptr,
entries);
rte_free(fdir_rule_ptr);
}
while ((hinic_flow_mem_ptr =
TAILQ_FIRST(&nic_dev->hinic_flow_list))) {
TAILQ_REMOVE(&nic_dev->hinic_flow_list, hinic_flow_mem_ptr,
entries);
rte_free(hinic_flow_mem_ptr->flow);
rte_free(hinic_flow_mem_ptr);
}
}
/* Destroy all flow rules associated with a port on hinic. */
static int hinic_flow_flush(struct rte_eth_dev *dev,
__rte_unused struct rte_flow_error *error)
{
struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
hinic_clear_all_ntuple_filter(dev);
hinic_clear_all_ethertype_filter(dev);
hinic_clear_all_fdir_filter(dev);
hinic_filterlist_flush(dev);
PMD_DRV_LOG(INFO, "Flush flow succeed, func_id: 0x%x",
hinic_global_func_id(nic_dev->hwdev));
return 0;
}
const struct rte_flow_ops hinic_flow_ops = {
.validate = hinic_flow_validate,
.create = hinic_flow_create,
.destroy = hinic_flow_destroy,
.flush = hinic_flow_flush,
};