@@ -74,6 +74,7 @@ struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl)
74
74
struct mlxsw_sp_acl_ruleset_ht_key {
75
75
struct net_device * dev ; /* dev this ruleset is bound to */
76
76
bool ingress ;
77
+ u32 chain_index ;
77
78
const struct mlxsw_sp_acl_profile_ops * ops ;
78
79
};
79
80
@@ -163,21 +164,29 @@ static void mlxsw_sp_acl_ruleset_destroy(struct mlxsw_sp *mlxsw_sp,
163
164
164
165
static int mlxsw_sp_acl_ruleset_bind (struct mlxsw_sp * mlxsw_sp ,
165
166
struct mlxsw_sp_acl_ruleset * ruleset ,
166
- struct net_device * dev , bool ingress )
167
+ struct net_device * dev , bool ingress ,
168
+ u32 chain_index )
167
169
{
168
170
const struct mlxsw_sp_acl_profile_ops * ops = ruleset -> ht_key .ops ;
169
171
struct mlxsw_sp_acl * acl = mlxsw_sp -> acl ;
170
172
int err ;
171
173
172
174
ruleset -> ht_key .dev = dev ;
173
175
ruleset -> ht_key .ingress = ingress ;
176
+ ruleset -> ht_key .chain_index = chain_index ;
174
177
err = rhashtable_insert_fast (& acl -> ruleset_ht , & ruleset -> ht_node ,
175
178
mlxsw_sp_acl_ruleset_ht_params );
176
179
if (err )
177
180
return err ;
178
- err = ops -> ruleset_bind (mlxsw_sp , ruleset -> priv , dev , ingress );
179
- if (err )
180
- goto err_ops_ruleset_bind ;
181
+ if (!ruleset -> ht_key .chain_index ) {
182
+ /* We only need ruleset with chain index 0, the implicit one,
183
+ * to be directly bound to device. The rest of the rulesets
184
+ * are bound by "Goto action set".
185
+ */
186
+ err = ops -> ruleset_bind (mlxsw_sp , ruleset -> priv , dev , ingress );
187
+ if (err )
188
+ goto err_ops_ruleset_bind ;
189
+ }
181
190
return 0 ;
182
191
183
192
err_ops_ruleset_bind :
@@ -192,7 +201,8 @@ static void mlxsw_sp_acl_ruleset_unbind(struct mlxsw_sp *mlxsw_sp,
192
201
const struct mlxsw_sp_acl_profile_ops * ops = ruleset -> ht_key .ops ;
193
202
struct mlxsw_sp_acl * acl = mlxsw_sp -> acl ;
194
203
195
- ops -> ruleset_unbind (mlxsw_sp , ruleset -> priv );
204
+ if (!ruleset -> ht_key .chain_index )
205
+ ops -> ruleset_unbind (mlxsw_sp , ruleset -> priv );
196
206
rhashtable_remove_fast (& acl -> ruleset_ht , & ruleset -> ht_node ,
197
207
mlxsw_sp_acl_ruleset_ht_params );
198
208
}
@@ -212,8 +222,8 @@ static void mlxsw_sp_acl_ruleset_ref_dec(struct mlxsw_sp *mlxsw_sp,
212
222
}
213
223
214
224
struct mlxsw_sp_acl_ruleset *
215
- mlxsw_sp_acl_ruleset_get (struct mlxsw_sp * mlxsw_sp ,
216
- struct net_device * dev , bool ingress ,
225
+ mlxsw_sp_acl_ruleset_get (struct mlxsw_sp * mlxsw_sp , struct net_device * dev ,
226
+ bool ingress , u32 chain_index ,
217
227
enum mlxsw_sp_acl_profile profile )
218
228
{
219
229
const struct mlxsw_sp_acl_profile_ops * ops ;
@@ -229,6 +239,7 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
229
239
memset (& ht_key , 0 , sizeof (ht_key ));
230
240
ht_key .dev = dev ;
231
241
ht_key .ingress = ingress ;
242
+ ht_key .chain_index = chain_index ;
232
243
ht_key .ops = ops ;
233
244
ruleset = rhashtable_lookup_fast (& acl -> ruleset_ht , & ht_key ,
234
245
mlxsw_sp_acl_ruleset_ht_params );
@@ -239,7 +250,8 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
239
250
ruleset = mlxsw_sp_acl_ruleset_create (mlxsw_sp , ops );
240
251
if (IS_ERR (ruleset ))
241
252
return ruleset ;
242
- err = mlxsw_sp_acl_ruleset_bind (mlxsw_sp , ruleset , dev , ingress );
253
+ err = mlxsw_sp_acl_ruleset_bind (mlxsw_sp , ruleset , dev ,
254
+ ingress , chain_index );
243
255
if (err )
244
256
goto err_ruleset_bind ;
245
257
return ruleset ;
0 commit comments