cxgb4: add ethtool n-tuple filter deletion
Add support to delete ethtool n-tuple filter. Fetch the appropriate filter region (HPFILTER, HASH, NORMAL) in which the filter exists, and delete it from the respective region, accordingly. Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Vishal Kulkarni <vishal@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c8729cac2a
commit
db43b30cd8
|
@ -1573,6 +1573,22 @@ static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap,
|
||||
u32 ftid)
|
||||
{
|
||||
struct tid_info *t = &adap->tids;
|
||||
struct filter_entry *f;
|
||||
|
||||
if (ftid < t->nhpftids)
|
||||
f = &adap->tids.hpftid_tab[ftid];
|
||||
else if (ftid < t->nftids)
|
||||
f = &adap->tids.ftid_tab[ftid - t->nhpftids];
|
||||
else
|
||||
f = lookup_tid(&adap->tids, ftid);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
|
||||
u32 *rules)
|
||||
{
|
||||
|
@ -1636,6 +1652,48 @@ static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int cxgb4_ntuple_del_filter(struct net_device *dev,
|
||||
struct ethtool_rxnfc *cmd)
|
||||
{
|
||||
struct cxgb4_ethtool_filter_info *filter_info;
|
||||
struct adapter *adapter = netdev2adap(dev);
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct filter_entry *f;
|
||||
u32 filter_id;
|
||||
int ret;
|
||||
|
||||
if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
|
||||
return -EAGAIN; /* can still change nfilters */
|
||||
|
||||
if (!adapter->ethtool_filters)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
|
||||
dev_err(adapter->pdev_dev,
|
||||
"Location must be < %u",
|
||||
adapter->ethtool_filters->nentries);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
filter_info = &adapter->ethtool_filters->port[pi->port_id];
|
||||
|
||||
if (!test_bit(cmd->fs.location, filter_info->bmap))
|
||||
return -ENOENT;
|
||||
|
||||
filter_id = filter_info->loc_array[cmd->fs.location];
|
||||
f = cxgb4_get_filter_entry(adapter, filter_id);
|
||||
|
||||
ret = cxgb4_flow_rule_destroy(dev, f->fs.tc_prio, &f->fs, filter_id);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
clear_bit(cmd->fs.location, filter_info->bmap);
|
||||
filter_info->in_use--;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add Ethtool n-tuple filters. */
|
||||
static int cxgb4_ntuple_set_filter(struct net_device *netdev,
|
||||
struct ethtool_rxnfc *cmd)
|
||||
|
@ -1702,6 +1760,9 @@ static int set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
|
|||
case ETHTOOL_SRXCLSRLINS:
|
||||
ret = cxgb4_ntuple_set_filter(dev, cmd);
|
||||
break;
|
||||
case ETHTOOL_SRXCLSRLDEL:
|
||||
ret = cxgb4_ntuple_del_filter(dev, cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -797,23 +797,38 @@ free_entry:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
|
||||
struct ch_filter_specification *fs, int tid)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(dev);
|
||||
u8 hash;
|
||||
int ret;
|
||||
|
||||
hash = fs->hash;
|
||||
|
||||
ret = cxgb4_del_filter(dev, tid, fs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (hash)
|
||||
cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cxgb4_tc_flower_destroy(struct net_device *dev,
|
||||
struct flow_cls_offload *cls)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(dev);
|
||||
struct ch_tc_flower_entry *ch_flower;
|
||||
u32 tc_prio;
|
||||
bool hash;
|
||||
int ret;
|
||||
|
||||
ch_flower = ch_flower_lookup(adap, cls->cookie);
|
||||
if (!ch_flower)
|
||||
return -ENOENT;
|
||||
|
||||
hash = ch_flower->fs.hash;
|
||||
tc_prio = ch_flower->fs.tc_prio;
|
||||
|
||||
ret = cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
|
||||
ret = cxgb4_flow_rule_destroy(dev, ch_flower->fs.tc_prio,
|
||||
&ch_flower->fs, ch_flower->filter_id);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -825,9 +840,6 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
|
|||
}
|
||||
kfree_rcu(ch_flower, rcu);
|
||||
|
||||
if (hash)
|
||||
cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -124,6 +124,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
|
|||
int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
|
||||
u32 tc_prio, struct netlink_ext_ack *extack,
|
||||
struct ch_filter_specification *fs, u32 *tid);
|
||||
int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
|
||||
struct ch_filter_specification *fs, int tid);
|
||||
|
||||
int cxgb4_init_tc_flower(struct adapter *adap);
|
||||
void cxgb4_cleanup_tc_flower(struct adapter *adap);
|
||||
|
|
Loading…
Reference in New Issue