Messages in this thread Patch in this message | | | From | Florian Fainelli <> | Subject | [PATCH net-next 2/5] net: ethtool: Add validation for WAKE_FILTER | Date | Wed, 25 Oct 2023 10:32:57 -0700 |
| |
A driver implementing WAKE_FILTER must first install at least one rule with RX_CLS_FLOW_WAKE for WAKE_FILTER to be effective. Iterate over RXNFC rules to validate that condition while trying to enable WAKE_FILTER.
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> --- net/ethtool/common.c | 42 ++++++++++++++++++++++++++++++++++++++++++ net/ethtool/common.h | 3 +++ net/ethtool/ioctl.c | 3 +++ net/ethtool/wol.c | 3 +++ 4 files changed, 51 insertions(+)
diff --git a/net/ethtool/common.c b/net/ethtool/common.c index 143dae872fb2..bab901b35731 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -742,3 +742,45 @@ ethtool_forced_speed_maps_init(struct ethtool_forced_speed_map *maps, u32 size) } } EXPORT_SYMBOL_GPL(ethtool_forced_speed_maps_init); + +static int __ethtool_check_rxnfc_wake_filter(struct ethtool_rxnfc *rule_info, + void *priv) +{ + bool *verdict = priv; + + if (rule_info->fs.ring_cookie == RX_CLS_FLOW_WAKE) { + *verdict = true; + return 1; + } + + return 0; +} + +/** + * ethtool_dev_check_wake_filter: Tests if a network device can use the + * WAKE_FILTER Wake-on-LAN option. + * @dev: network device to test + * @wol: %ethtool_wolinfo structure with Wake-on-LAN configuration + * + * Returns true if there is no support for %WAKE_FILTER, no support + * for RXNFC ethtool operations, or if there is at least one WAKE_FILTER + * installed. + */ +bool ethtool_dev_check_wake_filter(struct net_device *dev, + const struct ethtool_wolinfo *wol) +{ + bool verdict = false; + int ret; + + if (!(wol->wolopts & WAKE_FILTER)) + return true; + + if (!dev->ethtool_ops->get_rxnfc || + !dev->ethtool_ops->set_rxnfc) + return true; + + ret = __ethtool_for_each_rxnfc(dev, __ethtool_check_rxnfc_wake_filter, + &verdict); + + return ret < 0 ? false : verdict; +} diff --git a/net/ethtool/common.h b/net/ethtool/common.h index 28b8aaaf9bcb..6cd3286d5038 100644 --- a/net/ethtool/common.h +++ b/net/ethtool/common.h @@ -56,4 +56,7 @@ int ethtool_get_module_eeprom_call(struct net_device *dev, bool __ethtool_dev_mm_supported(struct net_device *dev); +bool ethtool_dev_check_wake_filter(struct net_device *dev, + const struct ethtool_wolinfo *wol); + #endif /* _ETHTOOL_COMMON_H */ diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 0b0ce4f81c01..954446185158 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1457,6 +1457,9 @@ static int ethtool_set_wol(struct net_device *dev, char __user *useraddr) !memcmp(wol.sopass, cur_wol.sopass, sizeof(wol.sopass))) return 0; + if (!ethtool_dev_check_wake_filter(dev, &wol)) + return -EOPNOTSUPP; + ret = dev->ethtool_ops->set_wol(dev, &wol); if (ret) return ret; diff --git a/net/ethtool/wol.c b/net/ethtool/wol.c index 0ed56c9ac1bc..65fbe743a070 100644 --- a/net/ethtool/wol.c +++ b/net/ethtool/wol.c @@ -132,6 +132,9 @@ ethnl_set_wol(struct ethnl_req_info *req_info, struct genl_info *info) tb[ETHTOOL_A_WOL_SOPASS], &mod); } + if (!ethtool_dev_check_wake_filter(dev, &wol)) + return -EOPNOTSUPP; + if (!mod) return 0; ret = dev->ethtool_ops->set_wol(dev, &wol); -- 2.34.1 [unhandled content-type:application/pkcs7-signature] | |