xref: /openbmc/linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
19948a064SJiri Pirko // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
29948a064SJiri Pirko /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
37aa0f5aaSJiri Pirko 
47aa0f5aaSJiri Pirko #include <linux/kernel.h>
57aa0f5aaSJiri Pirko #include <linux/errno.h>
67aa0f5aaSJiri Pirko #include <linux/netdevice.h>
7af11e818SIdo Schimmel #include <linux/log2.h>
83aaff323SJiri Pirko #include <net/net_namespace.h>
97aa0f5aaSJiri Pirko #include <net/flow_dissector.h>
107aa0f5aaSJiri Pirko #include <net/pkt_cls.h>
117aa0f5aaSJiri Pirko #include <net/tc_act/tc_gact.h>
127aa0f5aaSJiri Pirko #include <net/tc_act/tc_mirred.h>
13a150201aSPetr Machata #include <net/tc_act/tc_vlan.h>
147aa0f5aaSJiri Pirko 
157aa0f5aaSJiri Pirko #include "spectrum.h"
167aa0f5aaSJiri Pirko #include "core_acl_flex_keys.h"
177aa0f5aaSJiri Pirko 
mlxsw_sp_policer_validate(const struct flow_action * action,const struct flow_action_entry * act,struct netlink_ext_ack * extack)18d97b4b10SJianbo Liu static int mlxsw_sp_policer_validate(const struct flow_action *action,
19d97b4b10SJianbo Liu 				     const struct flow_action_entry *act,
20d97b4b10SJianbo Liu 				     struct netlink_ext_ack *extack)
21d97b4b10SJianbo Liu {
22d97b4b10SJianbo Liu 	if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
23d97b4b10SJianbo Liu 		NL_SET_ERR_MSG_MOD(extack,
24d97b4b10SJianbo Liu 				   "Offload not supported when exceed action is not drop");
25d97b4b10SJianbo Liu 		return -EOPNOTSUPP;
26d97b4b10SJianbo Liu 	}
27d97b4b10SJianbo Liu 
28d97b4b10SJianbo Liu 	if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
29d97b4b10SJianbo Liu 	    act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
30d97b4b10SJianbo Liu 		NL_SET_ERR_MSG_MOD(extack,
31d97b4b10SJianbo Liu 				   "Offload not supported when conform action is not pipe or ok");
32d97b4b10SJianbo Liu 		return -EOPNOTSUPP;
33d97b4b10SJianbo Liu 	}
34d97b4b10SJianbo Liu 
35d97b4b10SJianbo Liu 	if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
36d97b4b10SJianbo Liu 	    !flow_action_is_last_entry(action, act)) {
37d97b4b10SJianbo Liu 		NL_SET_ERR_MSG_MOD(extack,
38d97b4b10SJianbo Liu 				   "Offload not supported when conform action is ok, but action is not last");
39d97b4b10SJianbo Liu 		return -EOPNOTSUPP;
40d97b4b10SJianbo Liu 	}
41d97b4b10SJianbo Liu 
42d97b4b10SJianbo Liu 	if (act->police.peakrate_bytes_ps ||
43d97b4b10SJianbo Liu 	    act->police.avrate || act->police.overhead) {
44d97b4b10SJianbo Liu 		NL_SET_ERR_MSG_MOD(extack,
45d97b4b10SJianbo Liu 				   "Offload not supported when peakrate/avrate/overhead is configured");
46d97b4b10SJianbo Liu 		return -EOPNOTSUPP;
47d97b4b10SJianbo Liu 	}
48d97b4b10SJianbo Liu 
49d97b4b10SJianbo Liu 	if (act->police.rate_pkt_ps) {
50d97b4b10SJianbo Liu 		NL_SET_ERR_MSG_MOD(extack,
51d97b4b10SJianbo Liu 				   "QoS offload not support packets per second");
52d97b4b10SJianbo Liu 		return -EOPNOTSUPP;
53d97b4b10SJianbo Liu 	}
54d97b4b10SJianbo Liu 
55d97b4b10SJianbo Liu 	return 0;
56d97b4b10SJianbo Liu }
57d97b4b10SJianbo Liu 
mlxsw_sp_flower_parse_actions(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct mlxsw_sp_acl_rule_info * rulei,struct flow_action * flow_action,struct netlink_ext_ack * extack)587aa0f5aaSJiri Pirko static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
593bc3ffb6SJiri Pirko 					 struct mlxsw_sp_flow_block *block,
607aa0f5aaSJiri Pirko 					 struct mlxsw_sp_acl_rule_info *rulei,
6173867881SPablo Neira Ayuso 					 struct flow_action *flow_action,
62ad7769caSNir Dotan 					 struct netlink_ext_ack *extack)
637aa0f5aaSJiri Pirko {
6473867881SPablo Neira Ayuso 	const struct flow_action_entry *act;
6552feb8b5SDanielle Ratson 	int mirror_act_count = 0;
66af11e818SIdo Schimmel 	int police_act_count = 0;
6745aad0b7SIdo Schimmel 	int sample_act_count = 0;
68244cd96aSCong Wang 	int err, i;
697aa0f5aaSJiri Pirko 
7073867881SPablo Neira Ayuso 	if (!flow_action_has_entries(flow_action))
717aa0f5aaSJiri Pirko 		return 0;
7253eca1f3SJakub Kicinski 	if (!flow_action_mixed_hw_stats_check(flow_action, extack))
733632f6d3SJiri Pirko 		return -EOPNOTSUPP;
747aa0f5aaSJiri Pirko 
75c4afd0c8SJiri Pirko 	act = flow_action_first_entry_get(flow_action);
76060b6381SEdward Cree 	if (act->hw_stats & FLOW_ACTION_HW_STATS_DISABLED) {
77060b6381SEdward Cree 		/* Nothing to do */
78060b6381SEdward Cree 	} else if (act->hw_stats & FLOW_ACTION_HW_STATS_IMMEDIATE) {
797c1b8eb1SArkadi Sharshevsky 		/* Count action is inserted first */
80ad7769caSNir Dotan 		err = mlxsw_sp_acl_rulei_act_count(mlxsw_sp, rulei, extack);
817c1b8eb1SArkadi Sharshevsky 		if (err)
827c1b8eb1SArkadi Sharshevsky 			return err;
83060b6381SEdward Cree 	} else {
84c4afd0c8SJiri Pirko 		NL_SET_ERR_MSG_MOD(extack, "Unsupported action HW stats type");
85c4afd0c8SJiri Pirko 		return -EOPNOTSUPP;
86c4afd0c8SJiri Pirko 	}
877c1b8eb1SArkadi Sharshevsky 
8873867881SPablo Neira Ayuso 	flow_action_for_each(i, act, flow_action) {
8973867881SPablo Neira Ayuso 		switch (act->id) {
9073867881SPablo Neira Ayuso 		case FLOW_ACTION_ACCEPT:
9149bae2f3SJiri Pirko 			err = mlxsw_sp_acl_rulei_act_terminate(rulei);
9227c203cdSNir Dotan 			if (err) {
9327c203cdSNir Dotan 				NL_SET_ERR_MSG_MOD(extack, "Cannot append terminate action");
94b2925957SJiri Pirko 				return err;
9527c203cdSNir Dotan 			}
9673867881SPablo Neira Ayuso 			break;
9786272d33SJiri Pirko 		case FLOW_ACTION_DROP: {
9886272d33SJiri Pirko 			bool ingress;
9986272d33SJiri Pirko 
1003bc3ffb6SJiri Pirko 			if (mlxsw_sp_flow_block_is_mixed_bound(block)) {
10186272d33SJiri Pirko 				NL_SET_ERR_MSG_MOD(extack, "Drop action is not supported when block is bound to ingress and egress");
10286272d33SJiri Pirko 				return -EOPNOTSUPP;
10386272d33SJiri Pirko 			}
1043bc3ffb6SJiri Pirko 			ingress = mlxsw_sp_flow_block_is_ingress_bound(block);
1056d19d2bdSJiri Pirko 			err = mlxsw_sp_acl_rulei_act_drop(rulei, ingress,
106db4b4902SPaul Blakey 							  act->user_cookie, extack);
10727c203cdSNir Dotan 			if (err) {
10827c203cdSNir Dotan 				NL_SET_ERR_MSG_MOD(extack, "Cannot append drop action");
1097aa0f5aaSJiri Pirko 				return err;
11027c203cdSNir Dotan 			}
11186272d33SJiri Pirko 
11286272d33SJiri Pirko 			/* Forbid block with this rulei to be bound
11386272d33SJiri Pirko 			 * to ingress/egress in future. Ingress rule is
11486272d33SJiri Pirko 			 * a blocker for egress and vice versa.
11586272d33SJiri Pirko 			 */
11686272d33SJiri Pirko 			if (ingress)
11786272d33SJiri Pirko 				rulei->egress_bind_blocker = 1;
11886272d33SJiri Pirko 			else
11986272d33SJiri Pirko 				rulei->ingress_bind_blocker = 1;
12086272d33SJiri Pirko 			}
12173867881SPablo Neira Ayuso 			break;
12273867881SPablo Neira Ayuso 		case FLOW_ACTION_TRAP:
123bd5ddba5SJiri Pirko 			err = mlxsw_sp_acl_rulei_act_trap(rulei);
12427c203cdSNir Dotan 			if (err) {
12527c203cdSNir Dotan 				NL_SET_ERR_MSG_MOD(extack, "Cannot append trap action");
126bd5ddba5SJiri Pirko 				return err;
12727c203cdSNir Dotan 			}
12873867881SPablo Neira Ayuso 			break;
12973867881SPablo Neira Ayuso 		case FLOW_ACTION_GOTO: {
13073867881SPablo Neira Ayuso 			u32 chain_index = act->chain_index;
1310ede6ba2SJiri Pirko 			struct mlxsw_sp_acl_ruleset *ruleset;
1320ede6ba2SJiri Pirko 			u16 group_id;
1330ede6ba2SJiri Pirko 
1343aaff323SJiri Pirko 			ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, block,
1350ede6ba2SJiri Pirko 							      chain_index,
1360ede6ba2SJiri Pirko 							      MLXSW_SP_ACL_PROFILE_FLOWER);
1370ede6ba2SJiri Pirko 			if (IS_ERR(ruleset))
1380ede6ba2SJiri Pirko 				return PTR_ERR(ruleset);
1390ede6ba2SJiri Pirko 
1400ede6ba2SJiri Pirko 			group_id = mlxsw_sp_acl_ruleset_group_id(ruleset);
1412a52a8c6SJiri Pirko 			err = mlxsw_sp_acl_rulei_act_jump(rulei, group_id);
14227c203cdSNir Dotan 			if (err) {
14327c203cdSNir Dotan 				NL_SET_ERR_MSG_MOD(extack, "Cannot append jump action");
1442a52a8c6SJiri Pirko 				return err;
14527c203cdSNir Dotan 			}
14673867881SPablo Neira Ayuso 			}
14773867881SPablo Neira Ayuso 			break;
14873867881SPablo Neira Ayuso 		case FLOW_ACTION_REDIRECT: {
1497aa0f5aaSJiri Pirko 			struct net_device *out_dev;
150a1107487SIdo Schimmel 			struct mlxsw_sp_fid *fid;
151a1107487SIdo Schimmel 			u16 fid_index;
1527aa0f5aaSJiri Pirko 
1533bc3ffb6SJiri Pirko 			if (mlxsw_sp_flow_block_is_egress_bound(block)) {
154185556f0SJiri Pirko 				NL_SET_ERR_MSG_MOD(extack, "Redirect action is not supported on egress");
155185556f0SJiri Pirko 				return -EOPNOTSUPP;
156185556f0SJiri Pirko 			}
157185556f0SJiri Pirko 
158c9588e28SJiri Pirko 			/* Forbid block with this rulei to be bound
159c9588e28SJiri Pirko 			 * to egress in future.
160c9588e28SJiri Pirko 			 */
161c9588e28SJiri Pirko 			rulei->egress_bind_blocker = 1;
162c9588e28SJiri Pirko 
163*0433670eSIdo Schimmel 			/* Ignore learning and security lookup as redirection
164*0433670eSIdo Schimmel 			 * using ingress filters happens before the bridge.
165*0433670eSIdo Schimmel 			 */
166*0433670eSIdo Schimmel 			err = mlxsw_sp_acl_rulei_act_ignore(mlxsw_sp, rulei,
167*0433670eSIdo Schimmel 							    true, true);
168*0433670eSIdo Schimmel 			if (err) {
169*0433670eSIdo Schimmel 				NL_SET_ERR_MSG_MOD(extack, "Cannot append ignore action");
170*0433670eSIdo Schimmel 				return err;
171*0433670eSIdo Schimmel 			}
172*0433670eSIdo Schimmel 
173a1107487SIdo Schimmel 			fid = mlxsw_sp_acl_dummy_fid(mlxsw_sp);
174a1107487SIdo Schimmel 			fid_index = mlxsw_sp_fid_index(fid);
175cedbb8b2SJiri Pirko 			err = mlxsw_sp_acl_rulei_act_fid_set(mlxsw_sp, rulei,
176ad7769caSNir Dotan 							     fid_index, extack);
177cedbb8b2SJiri Pirko 			if (err)
178cedbb8b2SJiri Pirko 				return err;
179cedbb8b2SJiri Pirko 
18073867881SPablo Neira Ayuso 			out_dev = act->dev;
1817aa0f5aaSJiri Pirko 			err = mlxsw_sp_acl_rulei_act_fwd(mlxsw_sp, rulei,
182ad7769caSNir Dotan 							 out_dev, extack);
1837aa0f5aaSJiri Pirko 			if (err)
1847aa0f5aaSJiri Pirko 				return err;
18573867881SPablo Neira Ayuso 			}
18673867881SPablo Neira Ayuso 			break;
18773867881SPablo Neira Ayuso 		case FLOW_ACTION_MIRRED: {
18873867881SPablo Neira Ayuso 			struct net_device *out_dev = act->dev;
189d0d13c18SArkadi Sharshevsky 
19052feb8b5SDanielle Ratson 			if (mirror_act_count++) {
19152feb8b5SDanielle Ratson 				NL_SET_ERR_MSG_MOD(extack, "Multiple mirror actions per rule are not supported");
19252feb8b5SDanielle Ratson 				return -EOPNOTSUPP;
19352feb8b5SDanielle Ratson 			}
19452feb8b5SDanielle Ratson 
195d0d13c18SArkadi Sharshevsky 			err = mlxsw_sp_acl_rulei_act_mirror(mlxsw_sp, rulei,
196ad7769caSNir Dotan 							    block, out_dev,
197ad7769caSNir Dotan 							    extack);
198d0d13c18SArkadi Sharshevsky 			if (err)
199d0d13c18SArkadi Sharshevsky 				return err;
20073867881SPablo Neira Ayuso 			}
20173867881SPablo Neira Ayuso 			break;
202384c2f74SIdo Schimmel 		case FLOW_ACTION_VLAN_MANGLE: {
20373867881SPablo Neira Ayuso 			u16 proto = be16_to_cpu(act->vlan.proto);
20473867881SPablo Neira Ayuso 			u8 prio = act->vlan.prio;
20573867881SPablo Neira Ayuso 			u16 vid = act->vlan.vid;
206a150201aSPetr Machata 
207ccfc5693SPetr Machata 			err = mlxsw_sp_acl_rulei_act_vlan(mlxsw_sp, rulei,
20873867881SPablo Neira Ayuso 							  act->id, vid,
209ad7769caSNir Dotan 							  proto, prio, extack);
210ccfc5693SPetr Machata 			if (err)
211ccfc5693SPetr Machata 				return err;
212ccfc5693SPetr Machata 			break;
21373867881SPablo Neira Ayuso 			}
214463957e3SPetr Machata 		case FLOW_ACTION_PRIORITY:
2150be0ae14SPetr Machata 			err = mlxsw_sp_acl_rulei_act_priority(mlxsw_sp, rulei,
216463957e3SPetr Machata 							      act->priority,
217463957e3SPetr Machata 							      extack);
2180be0ae14SPetr Machata 			if (err)
2190be0ae14SPetr Machata 				return err;
2200be0ae14SPetr Machata 			break;
2219b4b16bbSPetr Machata 		case FLOW_ACTION_MANGLE: {
2229b4b16bbSPetr Machata 			enum flow_action_mangle_base htype = act->mangle.htype;
2239b4b16bbSPetr Machata 			__be32 be_mask = (__force __be32) act->mangle.mask;
2249b4b16bbSPetr Machata 			__be32 be_val = (__force __be32) act->mangle.val;
2259b4b16bbSPetr Machata 			u32 offset = act->mangle.offset;
2269b4b16bbSPetr Machata 			u32 mask = be32_to_cpu(be_mask);
2279b4b16bbSPetr Machata 			u32 val = be32_to_cpu(be_val);
2289b4b16bbSPetr Machata 
2299b4b16bbSPetr Machata 			err = mlxsw_sp_acl_rulei_act_mangle(mlxsw_sp, rulei,
2309b4b16bbSPetr Machata 							    htype, offset,
2319b4b16bbSPetr Machata 							    mask, val, extack);
2329b4b16bbSPetr Machata 			if (err)
2339b4b16bbSPetr Machata 				return err;
2349b4b16bbSPetr Machata 			break;
2359b4b16bbSPetr Machata 			}
236af11e818SIdo Schimmel 		case FLOW_ACTION_POLICE: {
237af11e818SIdo Schimmel 			u32 burst;
238af11e818SIdo Schimmel 
239af11e818SIdo Schimmel 			if (police_act_count++) {
240af11e818SIdo Schimmel 				NL_SET_ERR_MSG_MOD(extack, "Multiple police actions per rule are not supported");
241af11e818SIdo Schimmel 				return -EOPNOTSUPP;
242af11e818SIdo Schimmel 			}
243af11e818SIdo Schimmel 
244d97b4b10SJianbo Liu 			err = mlxsw_sp_policer_validate(flow_action, act, extack);
245d97b4b10SJianbo Liu 			if (err)
246d97b4b10SJianbo Liu 				return err;
2476a56e199SBaowen Zheng 
248af11e818SIdo Schimmel 			/* The kernel might adjust the requested burst size so
249af11e818SIdo Schimmel 			 * that it is not exactly a power of two. Re-adjust it
250af11e818SIdo Schimmel 			 * here since the hardware only supports burst sizes
251af11e818SIdo Schimmel 			 * that are a power of two.
252af11e818SIdo Schimmel 			 */
253af11e818SIdo Schimmel 			burst = roundup_pow_of_two(act->police.burst);
254af11e818SIdo Schimmel 			err = mlxsw_sp_acl_rulei_act_police(mlxsw_sp, rulei,
2555a995900SBaowen Zheng 							    act->hw_index,
256af11e818SIdo Schimmel 							    act->police.rate_bytes_ps,
257af11e818SIdo Schimmel 							    burst, extack);
258af11e818SIdo Schimmel 			if (err)
259af11e818SIdo Schimmel 				return err;
260af11e818SIdo Schimmel 			break;
261af11e818SIdo Schimmel 			}
26245aad0b7SIdo Schimmel 		case FLOW_ACTION_SAMPLE: {
26345aad0b7SIdo Schimmel 			if (sample_act_count++) {
26445aad0b7SIdo Schimmel 				NL_SET_ERR_MSG_MOD(extack, "Multiple sample actions per rule are not supported");
26545aad0b7SIdo Schimmel 				return -EOPNOTSUPP;
26645aad0b7SIdo Schimmel 			}
26745aad0b7SIdo Schimmel 
26845aad0b7SIdo Schimmel 			err = mlxsw_sp_acl_rulei_act_sample(mlxsw_sp, rulei,
26945aad0b7SIdo Schimmel 							    block,
27045aad0b7SIdo Schimmel 							    act->sample.psample_group,
27145aad0b7SIdo Schimmel 							    act->sample.rate,
27245aad0b7SIdo Schimmel 							    act->sample.trunc_size,
27345aad0b7SIdo Schimmel 							    act->sample.truncate,
27445aad0b7SIdo Schimmel 							    extack);
27545aad0b7SIdo Schimmel 			if (err)
27645aad0b7SIdo Schimmel 				return err;
27745aad0b7SIdo Schimmel 			break;
27845aad0b7SIdo Schimmel 			}
27973867881SPablo Neira Ayuso 		default:
28027c203cdSNir Dotan 			NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
2817aa0f5aaSJiri Pirko 			dev_err(mlxsw_sp->bus_info->dev, "Unsupported action\n");
2827aa0f5aaSJiri Pirko 			return -EOPNOTSUPP;
2837aa0f5aaSJiri Pirko 		}
2847aa0f5aaSJiri Pirko 	}
285463e1ab8SDanielle Ratson 
286463e1ab8SDanielle Ratson 	if (rulei->ipv6_valid) {
287463e1ab8SDanielle Ratson 		NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
288463e1ab8SDanielle Ratson 		return -EOPNOTSUPP;
289463e1ab8SDanielle Ratson 	}
290463e1ab8SDanielle Ratson 
2917aa0f5aaSJiri Pirko 	return 0;
2927aa0f5aaSJiri Pirko }
2937aa0f5aaSJiri Pirko 
294d04e2650SIdo Schimmel static int
mlxsw_sp_flower_parse_meta_iif(struct mlxsw_sp_acl_rule_info * rulei,const struct mlxsw_sp_flow_block * block,const struct flow_match_meta * match,struct netlink_ext_ack * extack)295d04e2650SIdo Schimmel mlxsw_sp_flower_parse_meta_iif(struct mlxsw_sp_acl_rule_info *rulei,
296d04e2650SIdo Schimmel 			       const struct mlxsw_sp_flow_block *block,
297d04e2650SIdo Schimmel 			       const struct flow_match_meta *match,
298d04e2650SIdo Schimmel 			       struct netlink_ext_ack *extack)
299d04e2650SIdo Schimmel {
300d04e2650SIdo Schimmel 	struct mlxsw_sp_port *mlxsw_sp_port;
301d04e2650SIdo Schimmel 	struct net_device *ingress_dev;
302d04e2650SIdo Schimmel 
3030b9cd74bSIdo Schimmel 	if (!match->mask->ingress_ifindex)
3040b9cd74bSIdo Schimmel 		return 0;
3050b9cd74bSIdo Schimmel 
306d04e2650SIdo Schimmel 	if (match->mask->ingress_ifindex != 0xFFFFFFFF) {
307d04e2650SIdo Schimmel 		NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask");
308d04e2650SIdo Schimmel 		return -EINVAL;
309d04e2650SIdo Schimmel 	}
310d04e2650SIdo Schimmel 
311d04e2650SIdo Schimmel 	ingress_dev = __dev_get_by_index(block->net,
312d04e2650SIdo Schimmel 					 match->key->ingress_ifindex);
313d04e2650SIdo Schimmel 	if (!ingress_dev) {
314d04e2650SIdo Schimmel 		NL_SET_ERR_MSG_MOD(extack, "Can't find specified ingress port to match on");
315d04e2650SIdo Schimmel 		return -EINVAL;
316d04e2650SIdo Schimmel 	}
317d04e2650SIdo Schimmel 
318d04e2650SIdo Schimmel 	if (!mlxsw_sp_port_dev_check(ingress_dev)) {
319d04e2650SIdo Schimmel 		NL_SET_ERR_MSG_MOD(extack, "Can't match on non-mlxsw ingress port");
320d04e2650SIdo Schimmel 		return -EINVAL;
321d04e2650SIdo Schimmel 	}
322d04e2650SIdo Schimmel 
323d04e2650SIdo Schimmel 	mlxsw_sp_port = netdev_priv(ingress_dev);
324d04e2650SIdo Schimmel 	if (mlxsw_sp_port->mlxsw_sp != block->mlxsw_sp) {
325d04e2650SIdo Schimmel 		NL_SET_ERR_MSG_MOD(extack, "Can't match on a port from different device");
326d04e2650SIdo Schimmel 		return -EINVAL;
327d04e2650SIdo Schimmel 	}
328d04e2650SIdo Schimmel 
329d04e2650SIdo Schimmel 	mlxsw_sp_acl_rulei_keymask_u32(rulei,
330d04e2650SIdo Schimmel 				       MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
331d04e2650SIdo Schimmel 				       mlxsw_sp_port->local_port,
332d04e2650SIdo Schimmel 				       0xFFFFFFFF);
333d04e2650SIdo Schimmel 
334d04e2650SIdo Schimmel 	return 0;
335d04e2650SIdo Schimmel }
336d04e2650SIdo Schimmel 
mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f,struct mlxsw_sp_flow_block * block)3370c1f391dSJiri Pirko static int mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info *rulei,
338f9e30088SPablo Neira Ayuso 				      struct flow_cls_offload *f,
3393bc3ffb6SJiri Pirko 				      struct mlxsw_sp_flow_block *block)
3400c1f391dSJiri Pirko {
341f9e30088SPablo Neira Ayuso 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
3420c1f391dSJiri Pirko 	struct flow_match_meta match;
3430c1f391dSJiri Pirko 
3440c1f391dSJiri Pirko 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META))
3450c1f391dSJiri Pirko 		return 0;
3460c1f391dSJiri Pirko 
3470c1f391dSJiri Pirko 	flow_rule_match_meta(rule, &match);
348f4356947SIdo Schimmel 
349caa4c58aSIdo Schimmel 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_FDB_MISS,
350caa4c58aSIdo Schimmel 				       match.key->l2_miss, match.mask->l2_miss);
351f4356947SIdo Schimmel 
352d04e2650SIdo Schimmel 	return mlxsw_sp_flower_parse_meta_iif(rulei, block, &match,
353d04e2650SIdo Schimmel 					      f->common.extack);
3540c1f391dSJiri Pirko }
3550c1f391dSJiri Pirko 
mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f)3567aa0f5aaSJiri Pirko static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei,
357f9e30088SPablo Neira Ayuso 				       struct flow_cls_offload *f)
3587aa0f5aaSJiri Pirko {
3598f256622SPablo Neira Ayuso 	struct flow_match_ipv4_addrs match;
3608f256622SPablo Neira Ayuso 
3618f256622SPablo Neira Ayuso 	flow_rule_match_ipv4_addrs(f->rule, &match);
3627aa0f5aaSJiri Pirko 
363c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
3648f256622SPablo Neira Ayuso 				       (char *) &match.key->src,
3658f256622SPablo Neira Ayuso 				       (char *) &match.mask->src, 4);
366c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_0_31,
3678f256622SPablo Neira Ayuso 				       (char *) &match.key->dst,
3688f256622SPablo Neira Ayuso 				       (char *) &match.mask->dst, 4);
3697aa0f5aaSJiri Pirko }
3707aa0f5aaSJiri Pirko 
mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f)3717aa0f5aaSJiri Pirko static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei,
372f9e30088SPablo Neira Ayuso 				       struct flow_cls_offload *f)
3737aa0f5aaSJiri Pirko {
3748f256622SPablo Neira Ayuso 	struct flow_match_ipv6_addrs match;
3758f256622SPablo Neira Ayuso 
3768f256622SPablo Neira Ayuso 	flow_rule_match_ipv6_addrs(f->rule, &match);
3777aa0f5aaSJiri Pirko 
378c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_96_127,
3798f256622SPablo Neira Ayuso 				       &match.key->src.s6_addr[0x0],
3808f256622SPablo Neira Ayuso 				       &match.mask->src.s6_addr[0x0], 4);
381c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_64_95,
3828f256622SPablo Neira Ayuso 				       &match.key->src.s6_addr[0x4],
3838f256622SPablo Neira Ayuso 				       &match.mask->src.s6_addr[0x4], 4);
384c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_32_63,
3858f256622SPablo Neira Ayuso 				       &match.key->src.s6_addr[0x8],
3868f256622SPablo Neira Ayuso 				       &match.mask->src.s6_addr[0x8], 4);
387c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
3888f256622SPablo Neira Ayuso 				       &match.key->src.s6_addr[0xC],
3898f256622SPablo Neira Ayuso 				       &match.mask->src.s6_addr[0xC], 4);
390c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_96_127,
3918f256622SPablo Neira Ayuso 				       &match.key->dst.s6_addr[0x0],
3928f256622SPablo Neira Ayuso 				       &match.mask->dst.s6_addr[0x0], 4);
393c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_64_95,
3948f256622SPablo Neira Ayuso 				       &match.key->dst.s6_addr[0x4],
3958f256622SPablo Neira Ayuso 				       &match.mask->dst.s6_addr[0x4], 4);
396c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_32_63,
3978f256622SPablo Neira Ayuso 				       &match.key->dst.s6_addr[0x8],
3988f256622SPablo Neira Ayuso 				       &match.mask->dst.s6_addr[0x8], 4);
399c43ea06dSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_0_31,
4008f256622SPablo Neira Ayuso 				       &match.key->dst.s6_addr[0xC],
4018f256622SPablo Neira Ayuso 				       &match.mask->dst.s6_addr[0xC], 4);
4027aa0f5aaSJiri Pirko }
4037aa0f5aaSJiri Pirko 
mlxsw_sp_flower_parse_ports(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f,u8 ip_proto)4047aa0f5aaSJiri Pirko static int mlxsw_sp_flower_parse_ports(struct mlxsw_sp *mlxsw_sp,
4057aa0f5aaSJiri Pirko 				       struct mlxsw_sp_acl_rule_info *rulei,
406f9e30088SPablo Neira Ayuso 				       struct flow_cls_offload *f,
4077aa0f5aaSJiri Pirko 				       u8 ip_proto)
4087aa0f5aaSJiri Pirko {
409f9e30088SPablo Neira Ayuso 	const struct flow_rule *rule = flow_cls_offload_flow_rule(f);
4108f256622SPablo Neira Ayuso 	struct flow_match_ports match;
4117aa0f5aaSJiri Pirko 
4128f256622SPablo Neira Ayuso 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS))
4137aa0f5aaSJiri Pirko 		return 0;
4147aa0f5aaSJiri Pirko 
4157aa0f5aaSJiri Pirko 	if (ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) {
41627c203cdSNir Dotan 		NL_SET_ERR_MSG_MOD(f->common.extack, "Only UDP and TCP keys are supported");
4177aa0f5aaSJiri Pirko 		dev_err(mlxsw_sp->bus_info->dev, "Only UDP and TCP keys are supported\n");
4187aa0f5aaSJiri Pirko 		return -EINVAL;
4197aa0f5aaSJiri Pirko 	}
4207aa0f5aaSJiri Pirko 
4218f256622SPablo Neira Ayuso 	flow_rule_match_ports(rule, &match);
4227aa0f5aaSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_DST_L4_PORT,
4238f256622SPablo Neira Ayuso 				       ntohs(match.key->dst),
4248f256622SPablo Neira Ayuso 				       ntohs(match.mask->dst));
4257aa0f5aaSJiri Pirko 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_SRC_L4_PORT,
4268f256622SPablo Neira Ayuso 				       ntohs(match.key->src),
4278f256622SPablo Neira Ayuso 				       ntohs(match.mask->src));
4287aa0f5aaSJiri Pirko 	return 0;
4297aa0f5aaSJiri Pirko }
4307aa0f5aaSJiri Pirko 
431fe22f741SIdo Schimmel static int
mlxsw_sp_flower_parse_ports_range(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f,u8 ip_proto)432fe22f741SIdo Schimmel mlxsw_sp_flower_parse_ports_range(struct mlxsw_sp *mlxsw_sp,
433fe22f741SIdo Schimmel 				  struct mlxsw_sp_acl_rule_info *rulei,
434fe22f741SIdo Schimmel 				  struct flow_cls_offload *f, u8 ip_proto)
435fe22f741SIdo Schimmel {
436fe22f741SIdo Schimmel 	const struct flow_rule *rule = flow_cls_offload_flow_rule(f);
437fe22f741SIdo Schimmel 	struct flow_match_ports_range match;
438fe22f741SIdo Schimmel 	u32 key_mask_value = 0;
439fe22f741SIdo Schimmel 
440fe22f741SIdo Schimmel 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS_RANGE))
441fe22f741SIdo Schimmel 		return 0;
442fe22f741SIdo Schimmel 
443fe22f741SIdo Schimmel 	if (ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) {
444fe22f741SIdo Schimmel 		NL_SET_ERR_MSG_MOD(f->common.extack, "Only UDP and TCP keys are supported");
445fe22f741SIdo Schimmel 		return -EINVAL;
446fe22f741SIdo Schimmel 	}
447fe22f741SIdo Schimmel 
448fe22f741SIdo Schimmel 	flow_rule_match_ports_range(rule, &match);
449fe22f741SIdo Schimmel 
450fe22f741SIdo Schimmel 	if (match.mask->tp_min.src) {
451fe22f741SIdo Schimmel 		struct mlxsw_sp_port_range range = {
452fe22f741SIdo Schimmel 			.min = ntohs(match.key->tp_min.src),
453fe22f741SIdo Schimmel 			.max = ntohs(match.key->tp_max.src),
454fe22f741SIdo Schimmel 			.source = true,
455fe22f741SIdo Schimmel 		};
456fe22f741SIdo Schimmel 		u8 prr_index;
457fe22f741SIdo Schimmel 		int err;
458fe22f741SIdo Schimmel 
459fe22f741SIdo Schimmel 		err = mlxsw_sp_port_range_reg_get(mlxsw_sp, &range,
460fe22f741SIdo Schimmel 						  f->common.extack, &prr_index);
461fe22f741SIdo Schimmel 		if (err)
462fe22f741SIdo Schimmel 			return err;
463fe22f741SIdo Schimmel 
464fe22f741SIdo Schimmel 		rulei->src_port_range_reg_index = prr_index;
465fe22f741SIdo Schimmel 		rulei->src_port_range_reg_valid = true;
466fe22f741SIdo Schimmel 		key_mask_value |= BIT(prr_index);
467fe22f741SIdo Schimmel 	}
468fe22f741SIdo Schimmel 
469fe22f741SIdo Schimmel 	if (match.mask->tp_min.dst) {
470fe22f741SIdo Schimmel 		struct mlxsw_sp_port_range range = {
471fe22f741SIdo Schimmel 			.min = ntohs(match.key->tp_min.dst),
472fe22f741SIdo Schimmel 			.max = ntohs(match.key->tp_max.dst),
473fe22f741SIdo Schimmel 		};
474fe22f741SIdo Schimmel 		u8 prr_index;
475fe22f741SIdo Schimmel 		int err;
476fe22f741SIdo Schimmel 
477fe22f741SIdo Schimmel 		err = mlxsw_sp_port_range_reg_get(mlxsw_sp, &range,
478fe22f741SIdo Schimmel 						  f->common.extack, &prr_index);
479fe22f741SIdo Schimmel 		if (err)
480fe22f741SIdo Schimmel 			return err;
481fe22f741SIdo Schimmel 
482fe22f741SIdo Schimmel 		rulei->dst_port_range_reg_index = prr_index;
483fe22f741SIdo Schimmel 		rulei->dst_port_range_reg_valid = true;
484fe22f741SIdo Schimmel 		key_mask_value |= BIT(prr_index);
485fe22f741SIdo Schimmel 	}
486fe22f741SIdo Schimmel 
487fe22f741SIdo Schimmel 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_L4_PORT_RANGE,
488fe22f741SIdo Schimmel 				       key_mask_value, key_mask_value);
489fe22f741SIdo Schimmel 
490fe22f741SIdo Schimmel 	return 0;
491fe22f741SIdo Schimmel }
492fe22f741SIdo Schimmel 
mlxsw_sp_flower_parse_tcp(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f,u8 ip_proto)4938a41d845SJiri Pirko static int mlxsw_sp_flower_parse_tcp(struct mlxsw_sp *mlxsw_sp,
4948a41d845SJiri Pirko 				     struct mlxsw_sp_acl_rule_info *rulei,
495f9e30088SPablo Neira Ayuso 				     struct flow_cls_offload *f,
4968a41d845SJiri Pirko 				     u8 ip_proto)
4978a41d845SJiri Pirko {
498f9e30088SPablo Neira Ayuso 	const struct flow_rule *rule = flow_cls_offload_flow_rule(f);
4998f256622SPablo Neira Ayuso 	struct flow_match_tcp match;
5008a41d845SJiri Pirko 
5018f256622SPablo Neira Ayuso 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP))
5028a41d845SJiri Pirko 		return 0;
5038a41d845SJiri Pirko 
5048a41d845SJiri Pirko 	if (ip_proto != IPPROTO_TCP) {
50527c203cdSNir Dotan 		NL_SET_ERR_MSG_MOD(f->common.extack, "TCP keys supported only for TCP");
5068a41d845SJiri Pirko 		dev_err(mlxsw_sp->bus_info->dev, "TCP keys supported only for TCP\n");
5078a41d845SJiri Pirko 		return -EINVAL;
5088a41d845SJiri Pirko 	}
5098a41d845SJiri Pirko 
5108f256622SPablo Neira Ayuso 	flow_rule_match_tcp(rule, &match);
5118f256622SPablo Neira Ayuso 
5127079676dSJiri Pirko 	if (match.mask->flags & htons(0x0E00)) {
5137079676dSJiri Pirko 		NL_SET_ERR_MSG_MOD(f->common.extack, "TCP flags match not supported on reserved bits");
5147079676dSJiri Pirko 		dev_err(mlxsw_sp->bus_info->dev, "TCP flags match not supported on reserved bits\n");
5157079676dSJiri Pirko 		return -EINVAL;
5167079676dSJiri Pirko 	}
5177079676dSJiri Pirko 
5188a41d845SJiri Pirko 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_TCP_FLAGS,
5198f256622SPablo Neira Ayuso 				       ntohs(match.key->flags),
5208f256622SPablo Neira Ayuso 				       ntohs(match.mask->flags));
5218a41d845SJiri Pirko 	return 0;
5228a41d845SJiri Pirko }
5238a41d845SJiri Pirko 
mlxsw_sp_flower_parse_ip(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f,u16 n_proto)524fcbca821SOr Gerlitz static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
525fcbca821SOr Gerlitz 				    struct mlxsw_sp_acl_rule_info *rulei,
526f9e30088SPablo Neira Ayuso 				    struct flow_cls_offload *f,
527fcbca821SOr Gerlitz 				    u16 n_proto)
528fcbca821SOr Gerlitz {
529f9e30088SPablo Neira Ayuso 	const struct flow_rule *rule = flow_cls_offload_flow_rule(f);
5308f256622SPablo Neira Ayuso 	struct flow_match_ip match;
531fcbca821SOr Gerlitz 
5328f256622SPablo Neira Ayuso 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP))
533fcbca821SOr Gerlitz 		return 0;
534fcbca821SOr Gerlitz 
535fcbca821SOr Gerlitz 	if (n_proto != ETH_P_IP && n_proto != ETH_P_IPV6) {
53627c203cdSNir Dotan 		NL_SET_ERR_MSG_MOD(f->common.extack, "IP keys supported only for IPv4/6");
537fcbca821SOr Gerlitz 		dev_err(mlxsw_sp->bus_info->dev, "IP keys supported only for IPv4/6\n");
538fcbca821SOr Gerlitz 		return -EINVAL;
539fcbca821SOr Gerlitz 	}
540fcbca821SOr Gerlitz 
5418f256622SPablo Neira Ayuso 	flow_rule_match_ip(rule, &match);
5428f256622SPablo Neira Ayuso 
543fcbca821SOr Gerlitz 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_TTL_,
5448f256622SPablo Neira Ayuso 				       match.key->ttl, match.mask->ttl);
54587996f91SOr Gerlitz 
54687996f91SOr Gerlitz 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_ECN,
5478f256622SPablo Neira Ayuso 				       match.key->tos & 0x3,
5488f256622SPablo Neira Ayuso 				       match.mask->tos & 0x3);
54987996f91SOr Gerlitz 
55087996f91SOr Gerlitz 	mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_DSCP,
551e49f9adfSJiri Pirko 				       match.key->tos >> 2,
552e49f9adfSJiri Pirko 				       match.mask->tos >> 2);
55387996f91SOr Gerlitz 
554fcbca821SOr Gerlitz 	return 0;
555fcbca821SOr Gerlitz }
556fcbca821SOr Gerlitz 
mlxsw_sp_flower_parse(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct mlxsw_sp_acl_rule_info * rulei,struct flow_cls_offload * f)5577aa0f5aaSJiri Pirko static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
5583bc3ffb6SJiri Pirko 				 struct mlxsw_sp_flow_block *block,
5597aa0f5aaSJiri Pirko 				 struct mlxsw_sp_acl_rule_info *rulei,
560f9e30088SPablo Neira Ayuso 				 struct flow_cls_offload *f)
5617aa0f5aaSJiri Pirko {
562f9e30088SPablo Neira Ayuso 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
5638f256622SPablo Neira Ayuso 	struct flow_dissector *dissector = rule->match.dissector;
564fcbca821SOr Gerlitz 	u16 n_proto_mask = 0;
565fcbca821SOr Gerlitz 	u16 n_proto_key = 0;
5667aa0f5aaSJiri Pirko 	u16 addr_type = 0;
5677aa0f5aaSJiri Pirko 	u8 ip_proto = 0;
5687aa0f5aaSJiri Pirko 	int err;
5697aa0f5aaSJiri Pirko 
5708f256622SPablo Neira Ayuso 	if (dissector->used_keys &
5712b3082c6SRatheesh Kannoth 	    ~(BIT_ULL(FLOW_DISSECTOR_KEY_META) |
5722b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_CONTROL) |
5732b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_BASIC) |
5742b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
5752b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
5762b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
5772b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
5782b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_PORTS_RANGE) |
5792b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_TCP) |
5802b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_IP) |
5812b3082c6SRatheesh Kannoth 	      BIT_ULL(FLOW_DISSECTOR_KEY_VLAN))) {
5827aa0f5aaSJiri Pirko 		dev_err(mlxsw_sp->bus_info->dev, "Unsupported key\n");
58327c203cdSNir Dotan 		NL_SET_ERR_MSG_MOD(f->common.extack, "Unsupported key");
5847aa0f5aaSJiri Pirko 		return -EOPNOTSUPP;
5857aa0f5aaSJiri Pirko 	}
5867aa0f5aaSJiri Pirko 
587d7c1c8d2SJiri Pirko 	mlxsw_sp_acl_rulei_priority(rulei, f->common.prio);
5887aa0f5aaSJiri Pirko 
5890c1f391dSJiri Pirko 	err = mlxsw_sp_flower_parse_meta(rulei, f, block);
5900c1f391dSJiri Pirko 	if (err)
5910c1f391dSJiri Pirko 		return err;
5920c1f391dSJiri Pirko 
5938f256622SPablo Neira Ayuso 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
5948f256622SPablo Neira Ayuso 		struct flow_match_control match;
5958f256622SPablo Neira Ayuso 
5968f256622SPablo Neira Ayuso 		flow_rule_match_control(rule, &match);
5978f256622SPablo Neira Ayuso 		addr_type = match.key->addr_type;
5987aa0f5aaSJiri Pirko 	}
5997aa0f5aaSJiri Pirko 
6008f256622SPablo Neira Ayuso 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
6018f256622SPablo Neira Ayuso 		struct flow_match_basic match;
6028f256622SPablo Neira Ayuso 
6038f256622SPablo Neira Ayuso 		flow_rule_match_basic(rule, &match);
6048f256622SPablo Neira Ayuso 		n_proto_key = ntohs(match.key->n_proto);
6058f256622SPablo Neira Ayuso 		n_proto_mask = ntohs(match.mask->n_proto);
606dc371700SJiri Pirko 
607dc371700SJiri Pirko 		if (n_proto_key == ETH_P_ALL) {
608dc371700SJiri Pirko 			n_proto_key = 0;
609dc371700SJiri Pirko 			n_proto_mask = 0;
610dc371700SJiri Pirko 		}
6117aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_u32(rulei,
6127aa0f5aaSJiri Pirko 					       MLXSW_AFK_ELEMENT_ETHERTYPE,
613dc371700SJiri Pirko 					       n_proto_key, n_proto_mask);
614dc371700SJiri Pirko 
6158f256622SPablo Neira Ayuso 		ip_proto = match.key->ip_proto;
6167aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_u32(rulei,
6177aa0f5aaSJiri Pirko 					       MLXSW_AFK_ELEMENT_IP_PROTO,
6188f256622SPablo Neira Ayuso 					       match.key->ip_proto,
6198f256622SPablo Neira Ayuso 					       match.mask->ip_proto);
6207aa0f5aaSJiri Pirko 	}
6217aa0f5aaSJiri Pirko 
6228f256622SPablo Neira Ayuso 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
6238f256622SPablo Neira Ayuso 		struct flow_match_eth_addrs match;
6247aa0f5aaSJiri Pirko 
6258f256622SPablo Neira Ayuso 		flow_rule_match_eth_addrs(rule, &match);
6267aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_buf(rulei,
627c43ea06dSJiri Pirko 					       MLXSW_AFK_ELEMENT_DMAC_32_47,
6288f256622SPablo Neira Ayuso 					       match.key->dst,
6298f256622SPablo Neira Ayuso 					       match.mask->dst, 2);
6307aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_buf(rulei,
631c43ea06dSJiri Pirko 					       MLXSW_AFK_ELEMENT_DMAC_0_31,
6328f256622SPablo Neira Ayuso 					       match.key->dst + 2,
6338f256622SPablo Neira Ayuso 					       match.mask->dst + 2, 4);
634c43ea06dSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_buf(rulei,
635c43ea06dSJiri Pirko 					       MLXSW_AFK_ELEMENT_SMAC_32_47,
6368f256622SPablo Neira Ayuso 					       match.key->src,
6378f256622SPablo Neira Ayuso 					       match.mask->src, 2);
638c43ea06dSJiri Pirko 		mlxsw_sp_acl_rulei_keymask_buf(rulei,
639c43ea06dSJiri Pirko 					       MLXSW_AFK_ELEMENT_SMAC_0_31,
6408f256622SPablo Neira Ayuso 					       match.key->src + 2,
6418f256622SPablo Neira Ayuso 					       match.mask->src + 2, 4);
6427aa0f5aaSJiri Pirko 	}
6437aa0f5aaSJiri Pirko 
6448f256622SPablo Neira Ayuso 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
6458f256622SPablo Neira Ayuso 		struct flow_match_vlan match;
646903fcf73SNir Dotan 
6478f256622SPablo Neira Ayuso 		flow_rule_match_vlan(rule, &match);
64870ec72d5SAmit Cohen 		if (mlxsw_sp_flow_block_is_egress_bound(block) &&
64970ec72d5SAmit Cohen 		    match.mask->vlan_id) {
650903fcf73SNir Dotan 			NL_SET_ERR_MSG_MOD(f->common.extack, "vlan_id key is not supported on egress");
651903fcf73SNir Dotan 			return -EOPNOTSUPP;
652903fcf73SNir Dotan 		}
653c9588e28SJiri Pirko 
654c9588e28SJiri Pirko 		/* Forbid block with this rulei to be bound
655c9588e28SJiri Pirko 		 * to egress in future.
656c9588e28SJiri Pirko 		 */
657c9588e28SJiri Pirko 		rulei->egress_bind_blocker = 1;
658c9588e28SJiri Pirko 
6598f256622SPablo Neira Ayuso 		if (match.mask->vlan_id != 0)
6609caab08aSPetr Machata 			mlxsw_sp_acl_rulei_keymask_u32(rulei,
6619caab08aSPetr Machata 						       MLXSW_AFK_ELEMENT_VID,
6628f256622SPablo Neira Ayuso 						       match.key->vlan_id,
6638f256622SPablo Neira Ayuso 						       match.mask->vlan_id);
6648f256622SPablo Neira Ayuso 		if (match.mask->vlan_priority != 0)
6659caab08aSPetr Machata 			mlxsw_sp_acl_rulei_keymask_u32(rulei,
6669caab08aSPetr Machata 						       MLXSW_AFK_ELEMENT_PCP,
6678f256622SPablo Neira Ayuso 						       match.key->vlan_priority,
6688f256622SPablo Neira Ayuso 						       match.mask->vlan_priority);
6699caab08aSPetr Machata 	}
6709caab08aSPetr Machata 
6717aa0f5aaSJiri Pirko 	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS)
6727aa0f5aaSJiri Pirko 		mlxsw_sp_flower_parse_ipv4(rulei, f);
6737aa0f5aaSJiri Pirko 
6747aa0f5aaSJiri Pirko 	if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS)
6757aa0f5aaSJiri Pirko 		mlxsw_sp_flower_parse_ipv6(rulei, f);
6767aa0f5aaSJiri Pirko 
6777aa0f5aaSJiri Pirko 	err = mlxsw_sp_flower_parse_ports(mlxsw_sp, rulei, f, ip_proto);
6787aa0f5aaSJiri Pirko 	if (err)
6797aa0f5aaSJiri Pirko 		return err;
680fe22f741SIdo Schimmel 
681fe22f741SIdo Schimmel 	err = mlxsw_sp_flower_parse_ports_range(mlxsw_sp, rulei, f, ip_proto);
682fe22f741SIdo Schimmel 	if (err)
683fe22f741SIdo Schimmel 		return err;
684fe22f741SIdo Schimmel 
6858a41d845SJiri Pirko 	err = mlxsw_sp_flower_parse_tcp(mlxsw_sp, rulei, f, ip_proto);
6868a41d845SJiri Pirko 	if (err)
6878a41d845SJiri Pirko 		return err;
6887aa0f5aaSJiri Pirko 
689fcbca821SOr Gerlitz 	err = mlxsw_sp_flower_parse_ip(mlxsw_sp, rulei, f, n_proto_key & n_proto_mask);
690fcbca821SOr Gerlitz 	if (err)
691fcbca821SOr Gerlitz 		return err;
692fcbca821SOr Gerlitz 
69373867881SPablo Neira Ayuso 	return mlxsw_sp_flower_parse_actions(mlxsw_sp, block, rulei,
69473867881SPablo Neira Ayuso 					     &f->rule->action,
695ad7769caSNir Dotan 					     f->common.extack);
6967aa0f5aaSJiri Pirko }
6977aa0f5aaSJiri Pirko 
mlxsw_sp_flower_mall_prio_check(struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)69867ed68fcSJiri Pirko static int mlxsw_sp_flower_mall_prio_check(struct mlxsw_sp_flow_block *block,
69967ed68fcSJiri Pirko 					   struct flow_cls_offload *f)
70067ed68fcSJiri Pirko {
70167ed68fcSJiri Pirko 	bool ingress = mlxsw_sp_flow_block_is_ingress_bound(block);
70267ed68fcSJiri Pirko 	unsigned int mall_min_prio;
70367ed68fcSJiri Pirko 	unsigned int mall_max_prio;
70467ed68fcSJiri Pirko 	int err;
70567ed68fcSJiri Pirko 
70667ed68fcSJiri Pirko 	err = mlxsw_sp_mall_prio_get(block, f->common.chain_index,
70767ed68fcSJiri Pirko 				     &mall_min_prio, &mall_max_prio);
70867ed68fcSJiri Pirko 	if (err) {
70967ed68fcSJiri Pirko 		if (err == -ENOENT)
71067ed68fcSJiri Pirko 			/* No matchall filters installed on this chain. */
71167ed68fcSJiri Pirko 			return 0;
71267ed68fcSJiri Pirko 		NL_SET_ERR_MSG(f->common.extack, "Failed to get matchall priorities");
71367ed68fcSJiri Pirko 		return err;
71467ed68fcSJiri Pirko 	}
71567ed68fcSJiri Pirko 	if (ingress && f->common.prio <= mall_min_prio) {
71667ed68fcSJiri Pirko 		NL_SET_ERR_MSG(f->common.extack, "Failed to add in front of existing matchall rules");
71767ed68fcSJiri Pirko 		return -EOPNOTSUPP;
71867ed68fcSJiri Pirko 	}
71967ed68fcSJiri Pirko 	if (!ingress && f->common.prio >= mall_max_prio) {
72067ed68fcSJiri Pirko 		NL_SET_ERR_MSG(f->common.extack, "Failed to add behind of existing matchall rules");
72167ed68fcSJiri Pirko 		return -EOPNOTSUPP;
72267ed68fcSJiri Pirko 	}
72367ed68fcSJiri Pirko 	return 0;
72467ed68fcSJiri Pirko }
72567ed68fcSJiri Pirko 
mlxsw_sp_flower_replace(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)7263aaff323SJiri Pirko int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
7273bc3ffb6SJiri Pirko 			    struct mlxsw_sp_flow_block *block,
728f9e30088SPablo Neira Ayuso 			    struct flow_cls_offload *f)
7297aa0f5aaSJiri Pirko {
7307aa0f5aaSJiri Pirko 	struct mlxsw_sp_acl_rule_info *rulei;
7317aa0f5aaSJiri Pirko 	struct mlxsw_sp_acl_ruleset *ruleset;
7327aa0f5aaSJiri Pirko 	struct mlxsw_sp_acl_rule *rule;
7337aa0f5aaSJiri Pirko 	int err;
7347aa0f5aaSJiri Pirko 
73567ed68fcSJiri Pirko 	err = mlxsw_sp_flower_mall_prio_check(block, f);
73667ed68fcSJiri Pirko 	if (err)
73767ed68fcSJiri Pirko 		return err;
73867ed68fcSJiri Pirko 
7393aaff323SJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
74045b62742SJiri Pirko 					   f->common.chain_index,
741e2f2a1fdSJiri Pirko 					   MLXSW_SP_ACL_PROFILE_FLOWER, NULL);
7427aa0f5aaSJiri Pirko 	if (IS_ERR(ruleset))
7437aa0f5aaSJiri Pirko 		return PTR_ERR(ruleset);
7447aa0f5aaSJiri Pirko 
745c20580c2SNir Dotan 	rule = mlxsw_sp_acl_rule_create(mlxsw_sp, ruleset, f->cookie, NULL,
746ad7769caSNir Dotan 					f->common.extack);
7477aa0f5aaSJiri Pirko 	if (IS_ERR(rule)) {
7487aa0f5aaSJiri Pirko 		err = PTR_ERR(rule);
7497aa0f5aaSJiri Pirko 		goto err_rule_create;
7507aa0f5aaSJiri Pirko 	}
7517aa0f5aaSJiri Pirko 
7527aa0f5aaSJiri Pirko 	rulei = mlxsw_sp_acl_rule_rulei(rule);
7533aaff323SJiri Pirko 	err = mlxsw_sp_flower_parse(mlxsw_sp, block, rulei, f);
7547aa0f5aaSJiri Pirko 	if (err)
7557aa0f5aaSJiri Pirko 		goto err_flower_parse;
7567aa0f5aaSJiri Pirko 
7577aa0f5aaSJiri Pirko 	err = mlxsw_sp_acl_rulei_commit(rulei);
7587aa0f5aaSJiri Pirko 	if (err)
7597aa0f5aaSJiri Pirko 		goto err_rulei_commit;
7607aa0f5aaSJiri Pirko 
7617aa0f5aaSJiri Pirko 	err = mlxsw_sp_acl_rule_add(mlxsw_sp, rule);
7627aa0f5aaSJiri Pirko 	if (err)
7637aa0f5aaSJiri Pirko 		goto err_rule_add;
7647aa0f5aaSJiri Pirko 
7657aa0f5aaSJiri Pirko 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
7667aa0f5aaSJiri Pirko 	return 0;
7677aa0f5aaSJiri Pirko 
7687aa0f5aaSJiri Pirko err_rule_add:
7697aa0f5aaSJiri Pirko err_rulei_commit:
7707aa0f5aaSJiri Pirko err_flower_parse:
7717aa0f5aaSJiri Pirko 	mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule);
7727aa0f5aaSJiri Pirko err_rule_create:
7737aa0f5aaSJiri Pirko 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
7747aa0f5aaSJiri Pirko 	return err;
7757aa0f5aaSJiri Pirko }
7767aa0f5aaSJiri Pirko 
mlxsw_sp_flower_destroy(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)7773aaff323SJiri Pirko void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp,
7783bc3ffb6SJiri Pirko 			     struct mlxsw_sp_flow_block *block,
779f9e30088SPablo Neira Ayuso 			     struct flow_cls_offload *f)
7807aa0f5aaSJiri Pirko {
7817aa0f5aaSJiri Pirko 	struct mlxsw_sp_acl_ruleset *ruleset;
7827aa0f5aaSJiri Pirko 	struct mlxsw_sp_acl_rule *rule;
7837aa0f5aaSJiri Pirko 
7843aaff323SJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
7853aaff323SJiri Pirko 					   f->common.chain_index,
786e2f2a1fdSJiri Pirko 					   MLXSW_SP_ACL_PROFILE_FLOWER, NULL);
787713c43b3SJiri Pirko 	if (IS_ERR(ruleset))
7887aa0f5aaSJiri Pirko 		return;
7897aa0f5aaSJiri Pirko 
7907aa0f5aaSJiri Pirko 	rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie);
791713c43b3SJiri Pirko 	if (rule) {
7927aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rule_del(mlxsw_sp, rule);
7937aa0f5aaSJiri Pirko 		mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule);
7947aa0f5aaSJiri Pirko 	}
7957aa0f5aaSJiri Pirko 
7967aa0f5aaSJiri Pirko 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
7977aa0f5aaSJiri Pirko }
7987c1b8eb1SArkadi Sharshevsky 
mlxsw_sp_flower_stats(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)7993aaff323SJiri Pirko int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
8003bc3ffb6SJiri Pirko 			  struct mlxsw_sp_flow_block *block,
801f9e30088SPablo Neira Ayuso 			  struct flow_cls_offload *f)
8027c1b8eb1SArkadi Sharshevsky {
80393a129ebSJiri Pirko 	enum flow_action_hw_stats used_hw_stats = FLOW_ACTION_HW_STATS_DISABLED;
8047c1b8eb1SArkadi Sharshevsky 	struct mlxsw_sp_acl_ruleset *ruleset;
8057c1b8eb1SArkadi Sharshevsky 	struct mlxsw_sp_acl_rule *rule;
8067c1b8eb1SArkadi Sharshevsky 	u64 packets;
8077c1b8eb1SArkadi Sharshevsky 	u64 lastuse;
8087c1b8eb1SArkadi Sharshevsky 	u64 bytes;
809af11e818SIdo Schimmel 	u64 drops;
8107c1b8eb1SArkadi Sharshevsky 	int err;
8117c1b8eb1SArkadi Sharshevsky 
8123aaff323SJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
8133aaff323SJiri Pirko 					   f->common.chain_index,
814e2f2a1fdSJiri Pirko 					   MLXSW_SP_ACL_PROFILE_FLOWER, NULL);
8157c1b8eb1SArkadi Sharshevsky 	if (WARN_ON(IS_ERR(ruleset)))
8167c1b8eb1SArkadi Sharshevsky 		return -EINVAL;
8177c1b8eb1SArkadi Sharshevsky 
8187c1b8eb1SArkadi Sharshevsky 	rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie);
8197c1b8eb1SArkadi Sharshevsky 	if (!rule)
8207c1b8eb1SArkadi Sharshevsky 		return -EINVAL;
8217c1b8eb1SArkadi Sharshevsky 
822c7cd4c9bSColin Ian King 	err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes,
823af11e818SIdo Schimmel 					  &drops, &lastuse, &used_hw_stats);
8247c1b8eb1SArkadi Sharshevsky 	if (err)
8257c1b8eb1SArkadi Sharshevsky 		goto err_rule_get_stats;
8267c1b8eb1SArkadi Sharshevsky 
827af11e818SIdo Schimmel 	flow_stats_update(&f->stats, bytes, packets, drops, lastuse,
828af11e818SIdo Schimmel 			  used_hw_stats);
8297c1b8eb1SArkadi Sharshevsky 
8307c1b8eb1SArkadi Sharshevsky 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
8317c1b8eb1SArkadi Sharshevsky 	return 0;
8327c1b8eb1SArkadi Sharshevsky 
8337c1b8eb1SArkadi Sharshevsky err_rule_get_stats:
8347c1b8eb1SArkadi Sharshevsky 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
8357c1b8eb1SArkadi Sharshevsky 	return err;
8367c1b8eb1SArkadi Sharshevsky }
837e2f2a1fdSJiri Pirko 
mlxsw_sp_flower_tmplt_create(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)838e2f2a1fdSJiri Pirko int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp,
8393bc3ffb6SJiri Pirko 				 struct mlxsw_sp_flow_block *block,
840f9e30088SPablo Neira Ayuso 				 struct flow_cls_offload *f)
841e2f2a1fdSJiri Pirko {
842e2f2a1fdSJiri Pirko 	struct mlxsw_sp_acl_ruleset *ruleset;
843e2f2a1fdSJiri Pirko 	struct mlxsw_sp_acl_rule_info rulei;
844e2f2a1fdSJiri Pirko 	int err;
845e2f2a1fdSJiri Pirko 
846e2f2a1fdSJiri Pirko 	memset(&rulei, 0, sizeof(rulei));
847e2f2a1fdSJiri Pirko 	err = mlxsw_sp_flower_parse(mlxsw_sp, block, &rulei, f);
848e2f2a1fdSJiri Pirko 	if (err)
849e2f2a1fdSJiri Pirko 		return err;
850e2f2a1fdSJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
851e2f2a1fdSJiri Pirko 					   f->common.chain_index,
852e2f2a1fdSJiri Pirko 					   MLXSW_SP_ACL_PROFILE_FLOWER,
853e2f2a1fdSJiri Pirko 					   &rulei.values.elusage);
854cd16e5b2SYueHaibing 
855e2f2a1fdSJiri Pirko 	/* keep the reference to the ruleset */
856cd16e5b2SYueHaibing 	return PTR_ERR_OR_ZERO(ruleset);
857e2f2a1fdSJiri Pirko }
858e2f2a1fdSJiri Pirko 
mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,struct flow_cls_offload * f)859e2f2a1fdSJiri Pirko void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
8603bc3ffb6SJiri Pirko 				   struct mlxsw_sp_flow_block *block,
861f9e30088SPablo Neira Ayuso 				   struct flow_cls_offload *f)
862e2f2a1fdSJiri Pirko {
863e2f2a1fdSJiri Pirko 	struct mlxsw_sp_acl_ruleset *ruleset;
864e2f2a1fdSJiri Pirko 
865e2f2a1fdSJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
866e2f2a1fdSJiri Pirko 					   f->common.chain_index,
867e2f2a1fdSJiri Pirko 					   MLXSW_SP_ACL_PROFILE_FLOWER, NULL);
868e2f2a1fdSJiri Pirko 	if (IS_ERR(ruleset))
869e2f2a1fdSJiri Pirko 		return;
870e2f2a1fdSJiri Pirko 	/* put the reference to the ruleset kept in create */
871e2f2a1fdSJiri Pirko 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
872e2f2a1fdSJiri Pirko 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
873e2f2a1fdSJiri Pirko }
874593bb843SJiri Pirko 
mlxsw_sp_flower_prio_get(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_flow_block * block,u32 chain_index,unsigned int * p_min_prio,unsigned int * p_max_prio)875593bb843SJiri Pirko int mlxsw_sp_flower_prio_get(struct mlxsw_sp *mlxsw_sp,
876593bb843SJiri Pirko 			     struct mlxsw_sp_flow_block *block,
877593bb843SJiri Pirko 			     u32 chain_index, unsigned int *p_min_prio,
878593bb843SJiri Pirko 			     unsigned int *p_max_prio)
879593bb843SJiri Pirko {
880593bb843SJiri Pirko 	struct mlxsw_sp_acl_ruleset *ruleset;
881593bb843SJiri Pirko 
882593bb843SJiri Pirko 	ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, block,
883593bb843SJiri Pirko 					      chain_index,
884593bb843SJiri Pirko 					      MLXSW_SP_ACL_PROFILE_FLOWER);
885593bb843SJiri Pirko 	if (IS_ERR(ruleset))
886593bb843SJiri Pirko 		/* In case there are no flower rules, the caller
887593bb843SJiri Pirko 		 * receives -ENOENT to indicate there is no need
888593bb843SJiri Pirko 		 * to check the priorities.
889593bb843SJiri Pirko 		 */
890593bb843SJiri Pirko 		return PTR_ERR(ruleset);
891593bb843SJiri Pirko 	mlxsw_sp_acl_ruleset_prio_get(ruleset, p_min_prio, p_max_prio);
892593bb843SJiri Pirko 	return 0;
893593bb843SJiri Pirko }
894