forked from mirrors/linux
		
	net: dsa: refactor matchall mirred action to separate function
Make room for other actions for the matchall filter by keeping the mirred argument parsing self-contained in its own function. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									c9a7fe1238
								
							
						
					
					
						commit
						e13c207528
					
				
					 1 changed files with 42 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -842,24 +842,27 @@ dsa_slave_mall_tc_entry_find(struct net_device *dev, unsigned long cookie)
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dsa_slave_add_cls_matchall(struct net_device *dev,
 | 
			
		||||
				      struct tc_cls_matchall_offload *cls,
 | 
			
		||||
				      bool ingress)
 | 
			
		||||
static int
 | 
			
		||||
dsa_slave_add_cls_matchall_mirred(struct net_device *dev,
 | 
			
		||||
				  struct tc_cls_matchall_offload *cls,
 | 
			
		||||
				  bool ingress)
 | 
			
		||||
{
 | 
			
		||||
	struct dsa_port *dp = dsa_slave_to_port(dev);
 | 
			
		||||
	struct dsa_slave_priv *p = netdev_priv(dev);
 | 
			
		||||
	struct dsa_mall_mirror_tc_entry *mirror;
 | 
			
		||||
	struct dsa_mall_tc_entry *mall_tc_entry;
 | 
			
		||||
	__be16 protocol = cls->common.protocol;
 | 
			
		||||
	struct dsa_switch *ds = dp->ds;
 | 
			
		||||
	struct flow_action_entry *act;
 | 
			
		||||
	struct dsa_port *to_dp;
 | 
			
		||||
	int err = -EOPNOTSUPP;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	act = &cls->rule->action.entries[0];
 | 
			
		||||
 | 
			
		||||
	if (!ds->ops->port_mirror_add)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	if (!flow_offload_has_one_action(&cls->rule->action))
 | 
			
		||||
		return err;
 | 
			
		||||
	if (!act->dev)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (!flow_action_basic_hw_stats_check(&cls->rule->action,
 | 
			
		||||
					      cls->common.extack))
 | 
			
		||||
| 
						 | 
				
			
			@ -867,38 +870,45 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
 | 
			
		|||
 | 
			
		||||
	act = &cls->rule->action.entries[0];
 | 
			
		||||
 | 
			
		||||
	if (act->id == FLOW_ACTION_MIRRED && protocol == htons(ETH_P_ALL)) {
 | 
			
		||||
		struct dsa_mall_mirror_tc_entry *mirror;
 | 
			
		||||
	if (!dsa_slave_dev_check(act->dev))
 | 
			
		||||
		return -EOPNOTSUPP;
 | 
			
		||||
 | 
			
		||||
		if (!act->dev)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
	mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL);
 | 
			
		||||
	if (!mall_tc_entry)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
		if (!dsa_slave_dev_check(act->dev))
 | 
			
		||||
			return -EOPNOTSUPP;
 | 
			
		||||
	mall_tc_entry->cookie = cls->cookie;
 | 
			
		||||
	mall_tc_entry->type = DSA_PORT_MALL_MIRROR;
 | 
			
		||||
	mirror = &mall_tc_entry->mirror;
 | 
			
		||||
 | 
			
		||||
		mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL);
 | 
			
		||||
		if (!mall_tc_entry)
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
	to_dp = dsa_slave_to_port(act->dev);
 | 
			
		||||
 | 
			
		||||
		mall_tc_entry->cookie = cls->cookie;
 | 
			
		||||
		mall_tc_entry->type = DSA_PORT_MALL_MIRROR;
 | 
			
		||||
		mirror = &mall_tc_entry->mirror;
 | 
			
		||||
	mirror->to_local_port = to_dp->index;
 | 
			
		||||
	mirror->ingress = ingress;
 | 
			
		||||
 | 
			
		||||
		to_dp = dsa_slave_to_port(act->dev);
 | 
			
		||||
 | 
			
		||||
		mirror->to_local_port = to_dp->index;
 | 
			
		||||
		mirror->ingress = ingress;
 | 
			
		||||
 | 
			
		||||
		err = ds->ops->port_mirror_add(ds, dp->index, mirror, ingress);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			kfree(mall_tc_entry);
 | 
			
		||||
			return err;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		list_add_tail(&mall_tc_entry->list, &p->mall_tc_list);
 | 
			
		||||
	err = ds->ops->port_mirror_add(ds, dp->index, mirror, ingress);
 | 
			
		||||
	if (err) {
 | 
			
		||||
		kfree(mall_tc_entry);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	list_add_tail(&mall_tc_entry->list, &p->mall_tc_list);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dsa_slave_add_cls_matchall(struct net_device *dev,
 | 
			
		||||
				      struct tc_cls_matchall_offload *cls,
 | 
			
		||||
				      bool ingress)
 | 
			
		||||
{
 | 
			
		||||
	int err = -EOPNOTSUPP;
 | 
			
		||||
 | 
			
		||||
	if (cls->common.protocol == htons(ETH_P_ALL) &&
 | 
			
		||||
	    flow_offload_has_one_action(&cls->rule->action) &&
 | 
			
		||||
	    cls->rule->action.entries[0].id == FLOW_ACTION_MIRRED)
 | 
			
		||||
		err = dsa_slave_add_cls_matchall_mirred(dev, cls, ingress);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dsa_slave_del_cls_matchall(struct net_device *dev,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue