Skip to content

Commit 36aae2e

Browse files
egcarrilanguy11
authored andcommitted
idpf: fix issue with ethtool -n command display
When ethtool -n is executed on an interface to display the flow steering rules, "rxclass: Unknown flow type" error is generated. The flow steering list maintained in the driver currently stores only the location and q_index but other fields of the ethtool_rx_flow_spec are not stored. This may be enough for the virtchnl command to delete the entry. However, when the ethtool -n command is used to query the flow steering rules, the ethtool_rx_flow_spec returned is not complete causing the error below. Resolve this by storing the flow spec (fsp) when rules are added and returning the complete flow spec when rules are queried. Also, change the return value from EINVAL to ENOENT when flow steering entry is not found during query by location or when deleting an entry. Add logic to detect and reject duplicate filter entries at the same location and change logic to perform upfront validation of all error conditions before adding flow rules through virtchnl. This avoids the need for additional virtchnl delete messages when subsequent operations fail, which was missing in the original upstream code. Example: Before the fix: ethtool -n eth1 2 RX rings available Total 2 rules rxclass: Unknown flow type rxclass: Unknown flow type After the fix: ethtool -n eth1 2 RX rings available Total 2 rules Filter: 0 Rule Type: TCP over IPv4 Src IP addr: 10.0.0.1 mask: 0.0.0.0 Dest IP addr: 0.0.0.0 mask: 255.255.255.255 TOS: 0x0 mask: 0xff Src port: 0 mask: 0xffff Dest port: 0 mask: 0xffff Action: Direct to queue 0 Filter: 1 Rule Type: UDP over IPv4 Src IP addr: 10.0.0.1 mask: 0.0.0.0 Dest IP addr: 0.0.0.0 mask: 255.255.255.255 TOS: 0x0 mask: 0xff Src port: 0 mask: 0xffff Dest port: 0 mask: 0xffff Action: Direct to queue 0 Fixes: ada3e24 ("idpf: add flow steering support") Signed-off-by: Erik Gabriel Carrillo <[email protected]> Co-developed-by: Sreedevi Joshi <[email protected]> Signed-off-by: Sreedevi Joshi <[email protected]> Reviewed-by: Przemek Kitszel <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Mina Almasry <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent f9841bd commit 36aae2e

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ struct idpf_port_stats {
284284

285285
struct idpf_fsteer_fltr {
286286
struct list_head list;
287-
u32 loc;
288-
u32 q_index;
287+
struct ethtool_rx_flow_spec fs;
289288
};
290289

291290
/**

drivers/net/ethernet/intel/idpf/idpf_ethtool.c

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,15 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
5454
cmd->data = idpf_fsteer_max_rules(vport);
5555
break;
5656
case ETHTOOL_GRXCLSRULE:
57-
err = -EINVAL;
57+
err = -ENOENT;
5858
spin_lock_bh(&vport_config->flow_steer_list_lock);
5959
list_for_each_entry(f, &user_config->flow_steer_list, list)
60-
if (f->loc == cmd->fs.location) {
61-
cmd->fs.ring_cookie = f->q_index;
60+
if (f->fs.location == cmd->fs.location) {
61+
/* Avoid infoleak from padding: zero first,
62+
* then assign fields
63+
*/
64+
memset(&cmd->fs, 0, sizeof(cmd->fs));
65+
cmd->fs = f->fs;
6266
err = 0;
6367
break;
6468
}
@@ -72,7 +76,7 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
7276
err = -EMSGSIZE;
7377
break;
7478
}
75-
rule_locs[cnt] = f->loc;
79+
rule_locs[cnt] = f->fs.location;
7680
cnt++;
7781
}
7882
if (!err)
@@ -174,7 +178,7 @@ static int idpf_add_flow_steer(struct net_device *netdev,
174178
struct idpf_vport *vport;
175179
u32 flow_type, q_index;
176180
u16 num_rxq;
177-
int err;
181+
int err = 0;
178182

179183
vport = idpf_netdev_to_vport(netdev);
180184
vport_config = vport->adapter->vport_config[np->vport_idx];
@@ -200,6 +204,29 @@ static int idpf_add_flow_steer(struct net_device *netdev,
200204
if (!rule)
201205
return -ENOMEM;
202206

207+
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
208+
if (!fltr) {
209+
err = -ENOMEM;
210+
goto out_free_rule;
211+
}
212+
213+
/* detect duplicate entry and reject before adding rules */
214+
spin_lock_bh(&vport_config->flow_steer_list_lock);
215+
list_for_each_entry(f, &user_config->flow_steer_list, list) {
216+
if (f->fs.location == fsp->location) {
217+
err = -EEXIST;
218+
break;
219+
}
220+
221+
if (f->fs.location > fsp->location)
222+
break;
223+
parent = f;
224+
}
225+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
226+
227+
if (err)
228+
goto out;
229+
203230
rule->vport_id = cpu_to_le32(vport->vport_id);
204231
rule->count = cpu_to_le32(1);
205232
info = &rule->rule_info[0];
@@ -238,28 +265,20 @@ static int idpf_add_flow_steer(struct net_device *netdev,
238265
goto out;
239266
}
240267

241-
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
242-
if (!fltr) {
243-
err = -ENOMEM;
244-
goto out;
245-
}
268+
/* Save a copy of the user's flow spec so ethtool can later retrieve it */
269+
fltr->fs = *fsp;
246270

247-
fltr->loc = fsp->location;
248-
fltr->q_index = q_index;
249271
spin_lock_bh(&vport_config->flow_steer_list_lock);
250-
list_for_each_entry(f, &user_config->flow_steer_list, list) {
251-
if (f->loc >= fltr->loc)
252-
break;
253-
parent = f;
254-
}
255-
256272
parent ? list_add(&fltr->list, &parent->list) :
257273
list_add(&fltr->list, &user_config->flow_steer_list);
258274

259275
user_config->num_fsteer_fltrs++;
260276
spin_unlock_bh(&vport_config->flow_steer_list_lock);
277+
goto out_free_rule;
261278

262279
out:
280+
kfree(fltr);
281+
out_free_rule:
263282
kfree(rule);
264283
return err;
265284
}
@@ -313,14 +332,14 @@ static int idpf_del_flow_steer(struct net_device *netdev,
313332
spin_lock_bh(&vport_config->flow_steer_list_lock);
314333
list_for_each_entry_safe(f, iter,
315334
&user_config->flow_steer_list, list) {
316-
if (f->loc == fsp->location) {
335+
if (f->fs.location == fsp->location) {
317336
list_del(&f->list);
318337
kfree(f);
319338
user_config->num_fsteer_fltrs--;
320339
goto out_unlock;
321340
}
322341
}
323-
err = -EINVAL;
342+
err = -ENOENT;
324343

325344
out_unlock:
326345
spin_unlock_bh(&vport_config->flow_steer_list_lock);

0 commit comments

Comments
 (0)