Re: [PATCH net-next v21 13/13] virtio_net: Add get ethtool flow rules ops
"Michael S. Tsirkin" <[email protected]> Mon, 3 Aug 2026 12:37:49 -0400
| Newsgroups | dev.linux.lists.virtualization,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 03, 2026 at 05:07:21PM +0300, Shahar Shitrit wrote: > From: Daniel Jurgens <[email protected]> > > - Get total number of rules. There's no user interface for this. For what? Isn't this ETHTOOL_GRXCLSRLCNT ? > It is > used to allocate an appropriately sized buffer for getting all the > rules. > > - Get specific rule > $ ethtool -u ens9 rule 0 > Filter: 0 > Rule Type: UDP over IPv4 > Src IP addr: 0.0.0.0 mask: 255.255.255.255 > Dest IP addr: 192.168.5.2 mask: 0.0.0.0 > TOS: 0x0 mask: 0xff > Src port: 0 mask: 0xffff > Dest port: 4321 mask: 0x0 > Action: Direct to queue 16 > > - Get all rules: > $ ethtool -u ens9 > 31 RX rings available > Total 2 rules > > Filter: 0 > Rule Type: UDP over IPv4 > Src IP addr: 0.0.0.0 mask: 255.255.255.255 > Dest IP addr: 192.168.5.2 mask: 0.0.0.0 > ... > > Filter: 1 > Flow Type: Raw Ethernet > Src MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF > Dest MAC addr: 08:11:22:33:44:54 mask: 00:00:00:00:00:00 > > Signed-off-by: Daniel Jurgens <[email protected]> > Reviewed-by: Parav Pandit <[email protected]> > Reviewed-by: Xuan Zhuo <[email protected]> > Signed-off-by: Shahar Shitrit <[email protected]> > --- > drivers/net/virtio_net.c | 75 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 75 insertions(+) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 236887c7976d..3d5eb716361a 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -6552,6 +6552,58 @@ static int virtnet_ethtool_flow_remove(struct virtnet_ff *ff, int location) > return err; > } > > +static int virtnet_ethtool_get_flow_count(struct virtnet_ff *ff, > + struct ethtool_rxnfc *info) > +{ > + if (!ff->ff_supported) > + return -EOPNOTSUPP; > + > + info->rule_cnt = ff->ethtool.num_rules; > + info->data = le32_to_cpu(ff->ff_caps->rules_limit) | RX_CLS_LOC_SPECIAL; maybe check rules_per_group_limit too? they are all in 1 group .. > + > + return 0; > +} > + > +static int virtnet_ethtool_get_flow(struct virtnet_ff *ff, > + struct ethtool_rxnfc *info) > +{ > + struct virtnet_ethtool_rule *eth_rule; > + > + if (!ff->ff_supported) > + return -EOPNOTSUPP; > + > + eth_rule = xa_load(&ff->ethtool.rules, info->fs.location); > + if (!eth_rule) > + return -ENOENT; > + > + info->fs = eth_rule->flow_spec; > + > + return 0; > +} > + > +static int > +virtnet_ethtool_get_all_flows(struct virtnet_ff *ff, > + struct ethtool_rxnfc *info, u32 *rule_locs) > +{ > + struct virtnet_ethtool_rule *eth_rule; > + unsigned long i = 0; > + int idx = 0; > + > + if (!ff->ff_supported) > + return -EOPNOTSUPP; > + > + xa_for_each(&ff->ethtool.rules, i, eth_rule) { > + if (idx == info->rule_cnt) > + return -EMSGSIZE; > + rule_locs[idx++] = i; > + } > + > + info->data = le32_to_cpu(ff->ff_caps->rules_limit); > + info->rule_cnt = idx; > + > + return 0; > +} > + > static size_t get_mask_size(u16 type) > { > switch (type) { > @@ -6570,6 +6622,28 @@ static size_t get_mask_size(u16 type) > return 0; > } > > +static int virtnet_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, u32 *rule_locs) > +{ > + struct virtnet_info *vi = netdev_priv(dev); > + int rc; > + > + switch (info->cmd) { > + case ETHTOOL_GRXCLSRLCNT: > + rc = virtnet_ethtool_get_flow_count(&vi->ff, info); > + break; > + case ETHTOOL_GRXCLSRULE: > + rc = virtnet_ethtool_get_flow(&vi->ff, info); > + break; > + case ETHTOOL_GRXCLSRLALL: > + rc = virtnet_ethtool_get_all_flows(&vi->ff, info, rule_locs); > + break; > + default: > + rc = -EOPNOTSUPP; > + } > + > + return rc; > +} > + > static int virtnet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info) > { > struct virtnet_info *vi = netdev_priv(dev); > @@ -6611,6 +6685,7 @@ static const struct ethtool_ops virtnet_ethtool_ops = { > .get_rxfh_fields = virtnet_get_hashflow, > .set_rxfh_fields = virtnet_set_hashflow, > .get_rx_ring_count = virtnet_get_rx_ring_count, > + .get_rxnfc = virtnet_get_rxnfc, > .set_rxnfc = virtnet_set_rxnfc, > }; > > -- > 2.49.0