Message ID | 20231011221242.4180589-2-florian.fainelli@broadcom.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Add WAKE_MDA Wake-on-LAN option | expand |
On Wed, Oct 11, 2023 at 03:12:39PM -0700, Florian Fainelli wrote: > Allow Ethernet PHY and MAC drivers with simplified matching logic to be > waking-up on a custom MAC destination address. This is particularly > useful for Ethernet PHYs which have limited amounts of buffering but can > still wake-up on a custom MAC destination address. > > When WAKE_MDA is specified, the "sopass" field in the existing struct > ethtool_wolinfo is re-purposed to hold a custom MAC destination address > to match against. > > Example: > ethtool -s eth0 wol e mac-da 01:00:5e:00:00:fb > > Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> > --- > Documentation/networking/ethtool-netlink.rst | 7 ++++++- > include/uapi/linux/ethtool.h | 10 ++++++++-- > include/uapi/linux/ethtool_netlink.h | 1 + > net/ethtool/common.c | 1 + > net/ethtool/netlink.h | 2 +- > net/ethtool/wol.c | 21 ++++++++++++++++++++ > 6 files changed, 38 insertions(+), 4 deletions(-) > [...] > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h > index f7fba0dc87e5..8134ac8870bd 100644 > --- a/include/uapi/linux/ethtool.h > +++ b/include/uapi/linux/ethtool.h > @@ -207,12 +207,17 @@ struct ethtool_drvinfo { > * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes. > * @sopass: SecureOn(tm) password; meaningful only if %WAKE_MAGICSECURE > * is set in @wolopts. > + * @mac_da: Destination MAC address to match; meaningful only if > + * %WAKE_MDA is set in @wolopts. > */ > struct ethtool_wolinfo { > __u32 cmd; > __u32 supported; > __u32 wolopts; > - __u8 sopass[SOPASS_MAX]; > + union { > + __u8 sopass[SOPASS_MAX]; > + __u8 mac_da[ETH_ALEN]; > + }; > }; If we use the union here, we should also make sure the request cannot set both WAKE_MAGICSECURE and WAKE_MDA, otherwise the same data will be used for two different values (and interpreted in two different ways in GET requests and notifications). Another option would be keeping the existing structure for ioctl UAPI and using another structure (like we did in other cases where we needed new attributes beyond frozen ioctl structures) so that a combination of WAKE_MAGICSECURE and WAKE_MDA is possible. (It doesn't seem to make much sense to me to combine WAKE_MAGICSECURE with other bits but I can't rule out someone might want that one day.) [...] > diff --git a/net/ethtool/wol.c b/net/ethtool/wol.c > index 0ed56c9ac1bc..13dfcc9bb1e5 100644 > --- a/net/ethtool/wol.c > +++ b/net/ethtool/wol.c > @@ -12,6 +12,7 @@ struct wol_reply_data { > struct ethnl_reply_data base; > struct ethtool_wolinfo wol; > bool show_sopass; > + bool show_mac_da; > }; > > #define WOL_REPDATA(__reply_base) \ > @@ -41,6 +42,8 @@ static int wol_prepare_data(const struct ethnl_req_info *req_base, > /* do not include password in notifications */ > data->show_sopass = !genl_info_is_ntf(info) && > (data->wol.supported & WAKE_MAGICSECURE); > + data->show_mac_da = !genl_info_is_ntf(info) && > + (data->wol.supported & WAKE_MDA); > > return 0; > } The test for !genl_info_is_ntf(info) above is meant to prevent the sopass value (which is supposed to be secret) from being included in notifications which can be seen by unprivileged users. Is the MAC address to match also supposed to be secret? Michal
On 10/11/2023 4:08 PM, Michal Kubecek wrote: > On Wed, Oct 11, 2023 at 03:12:39PM -0700, Florian Fainelli wrote: >> Allow Ethernet PHY and MAC drivers with simplified matching logic to be >> waking-up on a custom MAC destination address. This is particularly >> useful for Ethernet PHYs which have limited amounts of buffering but can >> still wake-up on a custom MAC destination address. >> >> When WAKE_MDA is specified, the "sopass" field in the existing struct >> ethtool_wolinfo is re-purposed to hold a custom MAC destination address >> to match against. >> >> Example: >> ethtool -s eth0 wol e mac-da 01:00:5e:00:00:fb >> >> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> >> --- >> Documentation/networking/ethtool-netlink.rst | 7 ++++++- >> include/uapi/linux/ethtool.h | 10 ++++++++-- >> include/uapi/linux/ethtool_netlink.h | 1 + >> net/ethtool/common.c | 1 + >> net/ethtool/netlink.h | 2 +- >> net/ethtool/wol.c | 21 ++++++++++++++++++++ >> 6 files changed, 38 insertions(+), 4 deletions(-) >> > [...] >> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h >> index f7fba0dc87e5..8134ac8870bd 100644 >> --- a/include/uapi/linux/ethtool.h >> +++ b/include/uapi/linux/ethtool.h >> @@ -207,12 +207,17 @@ struct ethtool_drvinfo { >> * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes. >> * @sopass: SecureOn(tm) password; meaningful only if %WAKE_MAGICSECURE >> * is set in @wolopts. >> + * @mac_da: Destination MAC address to match; meaningful only if >> + * %WAKE_MDA is set in @wolopts. >> */ >> struct ethtool_wolinfo { >> __u32 cmd; >> __u32 supported; >> __u32 wolopts; >> - __u8 sopass[SOPASS_MAX]; >> + union { >> + __u8 sopass[SOPASS_MAX]; >> + __u8 mac_da[ETH_ALEN]; >> + }; >> }; > > If we use the union here, we should also make sure the request cannot > set both WAKE_MAGICSECURE and WAKE_MDA, otherwise the same data will be > used for two different values (and interpreted in two different ways in > GET requests and notifications). > > Another option would be keeping the existing structure for ioctl UAPI > and using another structure (like we did in other cases where we needed > new attributes beyond frozen ioctl structures) so that a combination of > WAKE_MAGICSECURE and WAKE_MDA is possible. (It doesn't seem to make much > sense to me to combine WAKE_MAGICSECURE with other bits but I can't rule > out someone might want that one day.) I am having some second thoughts about this proposed interface as I can see a few limitations: - we can only specify an exact destination MAC address to match, but the HW filter underneath is typically implemented using a match + mask so you can actually be selective about which bits you want to match on. In the use case that I have in mind we would actually want to match both multicast MAC destination addresses corresponding to mDNS over IPv4 or IPv6 - in case a MAC/PHY/switch supports multiple filters/slots we would not be able to address a specific slot in the matching logic This sort of brings me back to the original proposal which allowed this: https://lore.kernel.org/all/20230516231713.2882879-1-florian.fainelli@broadcom.com/ Andrew, what do you think? > > [...] >> diff --git a/net/ethtool/wol.c b/net/ethtool/wol.c >> index 0ed56c9ac1bc..13dfcc9bb1e5 100644 >> --- a/net/ethtool/wol.c >> +++ b/net/ethtool/wol.c >> @@ -12,6 +12,7 @@ struct wol_reply_data { >> struct ethnl_reply_data base; >> struct ethtool_wolinfo wol; >> bool show_sopass; >> + bool show_mac_da; >> }; >> >> #define WOL_REPDATA(__reply_base) \ >> @@ -41,6 +42,8 @@ static int wol_prepare_data(const struct ethnl_req_info *req_base, >> /* do not include password in notifications */ >> data->show_sopass = !genl_info_is_ntf(info) && >> (data->wol.supported & WAKE_MAGICSECURE); >> + data->show_mac_da = !genl_info_is_ntf(info) && >> + (data->wol.supported & WAKE_MDA); >> >> return 0; >> } > > The test for !genl_info_is_ntf(info) above is meant to prevent the > sopass value (which is supposed to be secret) from being included in > notifications which can be seen by unprivileged users. Is the MAC > address to match also supposed to be secret? Either way could be considered, so I erred on the side of caution.
> I am having some second thoughts about this proposed interface as I can see > a few limitations: > > - we can only specify an exact destination MAC address to match, but the HW > filter underneath is typically implemented using a match + mask so you can > actually be selective about which bits you want to match on. In the use case > that I have in mind we would actually want to match both multicast MAC > destination addresses corresponding to mDNS over IPv4 or IPv6 > > - in case a MAC/PHY/switch supports multiple filters/slots we would not be > able to address a specific slot in the matching logic > > This sort of brings me back to the original proposal which allowed this: > > https://lore.kernel.org/all/20230516231713.2882879-1-florian.fainelli@broadcom.com/ The Marvell PHY i just looked at supports upto 8 slots, and can match up to the first 128 bytes of frame data. So it does seem like a more generic and flexible interface would fit the hardware. My previous concern was discoverability of the feature. Its not part of ethtool -s eth0 wol. At minimum, i would suggest something in the --help text in the wol section and man page pointing to the alternative way to configure wol. And maybe report via the standard wol flags that the hardware has the capability to use flow-type WoL? The example you gave matched on Flow Type: Raw Ethernet. Is it possible to combine flow types? If i can match on the first 128 bytes of the frame i might want to go deeper into the frame, so want both Ethernet and IP matching? Andrew
On 10/12/23 05:45, Andrew Lunn wrote: >> I am having some second thoughts about this proposed interface as I can see >> a few limitations: >> >> - we can only specify an exact destination MAC address to match, but the HW >> filter underneath is typically implemented using a match + mask so you can >> actually be selective about which bits you want to match on. In the use case >> that I have in mind we would actually want to match both multicast MAC >> destination addresses corresponding to mDNS over IPv4 or IPv6 >> >> - in case a MAC/PHY/switch supports multiple filters/slots we would not be >> able to address a specific slot in the matching logic >> >> This sort of brings me back to the original proposal which allowed this: >> >> https://lore.kernel.org/all/20230516231713.2882879-1-florian.fainelli@broadcom.com/ > > The Marvell PHY i just looked at supports upto 8 slots, and can match > up to the first 128 bytes of frame data. So it does seem like a more > generic and flexible interface would fit the hardware. > > My previous concern was discoverability of the feature. Its not part > of ethtool -s eth0 wol. At minimum, i would suggest something in the > --help text in the wol section and man page pointing to the > alternative way to configure wol. And maybe report via the standard > wol flags that the hardware has the capability to use flow-type WoL? WAKE_FILTER is supposed to be set by the driver if it supports waking-up from a network filter. That is how you would know that the device supports waking-up from a network filter, and then you need to configure the filters with ethtool -N (rxnfc). Where this API is a good fit is that you can specify a filter location and the action (-2 = RX_CLS_FLOW_WAKE) to indicate where to install the filter and what it should do. Where it may not be such a great fit is that it is a two step process, where you need to make sure you install filter(s) plus enable WAKE_FILTER from the .set_wol() call. At the time it was proposed it felt like a reasonable way to program, without having "ethtool -s eth0 wol" gain a form of packet matching parser. Also, it does not seem to me like we need the operations to be necessarily atomic in a single call to the kernel but if we feel like this is too difficult to use, we could consider a .set_wol() call that supports being passed network filter(s). > > The example you gave matched on Flow Type: Raw Ethernet. Is it > possible to combine flow types? If i can match on the first 128 bytes > of the frame i might want to go deeper into the frame, so want both > Ethernet and IP matching? AFAICT with neither ethtool nor cls_flower you would be able to match on an arbitrary and unstructured N-bytes key + N-bytes mask. You would likely need to create two filters here, one for Ethernet, specified with the "flow-type ether" and one for each IP version... You might have a shot with the extended flow representation which provides a few bytes of raw filtering, I have not really explored that part TBH.
> > My previous concern was discoverability of the feature. Its not part > > of ethtool -s eth0 wol. At minimum, i would suggest something in the > > --help text in the wol section and man page pointing to the > > alternative way to configure wol. And maybe report via the standard > > wol flags that the hardware has the capability to use flow-type WoL? > > WAKE_FILTER is supposed to be set by the driver if it supports waking-up > from a network filter. That is how you would know that the device supports > waking-up from a network filter, and then you need to configure the filters > with ethtool -N (rxnfc). > > Where this API is a good fit is that you can specify a filter location and > the action (-2 = RX_CLS_FLOW_WAKE) to indicate where to install the filter > and what it should do. Where it may not be such a great fit is that it is a > two step process, where you need to make sure you install filter(s) plus > enable WAKE_FILTER from the .set_wol() call. > > At the time it was proposed it felt like a reasonable way to program, > without having "ethtool -s eth0 wol" gain a form of packet matching parser. > Also, it does not seem to me like we need the operations to be necessarily > atomic in a single call to the kernel but if we feel like this is too > difficult to use, we could consider a .set_wol() call that supports being > passed network filter(s). I think two step is fine. I would say anybody using rxnfc is a pretty advanced user. But we should clearly define what we expect in terms of ordering and maybe try to enforce it in the core. Can we make the rxnfc call return -EBUSY or something and an extack message if WAKE_FILTER has not been enabled first? Andrew
On 10/12/23 13:24, Andrew Lunn wrote: >>> My previous concern was discoverability of the feature. Its not part >>> of ethtool -s eth0 wol. At minimum, i would suggest something in the >>> --help text in the wol section and man page pointing to the >>> alternative way to configure wol. And maybe report via the standard >>> wol flags that the hardware has the capability to use flow-type WoL? >> >> WAKE_FILTER is supposed to be set by the driver if it supports waking-up >> from a network filter. That is how you would know that the device supports >> waking-up from a network filter, and then you need to configure the filters >> with ethtool -N (rxnfc). >> >> Where this API is a good fit is that you can specify a filter location and >> the action (-2 = RX_CLS_FLOW_WAKE) to indicate where to install the filter >> and what it should do. Where it may not be such a great fit is that it is a >> two step process, where you need to make sure you install filter(s) plus >> enable WAKE_FILTER from the .set_wol() call. >> >> At the time it was proposed it felt like a reasonable way to program, >> without having "ethtool -s eth0 wol" gain a form of packet matching parser. >> Also, it does not seem to me like we need the operations to be necessarily >> atomic in a single call to the kernel but if we feel like this is too >> difficult to use, we could consider a .set_wol() call that supports being >> passed network filter(s). > > I think two step is fine. I would say anybody using rxnfc is a pretty > advanced user. > > But we should clearly define what we expect in terms of ordering and > maybe try to enforce it in the core. Can we make the rxnfc call return > -EBUSY or something and an extack message if WAKE_FILTER has not been > enabled first? It might make sense to do it the other way around, that is you must install filters first and if none are installed by the time we enable WAKE_FILTER in .set_wol(), we error out with -EINVAL?
> > But we should clearly define what we expect in terms of ordering and > > maybe try to enforce it in the core. Can we make the rxnfc call return > > -EBUSY or something and an extack message if WAKE_FILTER has not been > > enabled first? > > It might make sense to do it the other way around, that is you must install > filters first and if none are installed by the time we enable WAKE_FILTER in > .set_wol(), we error out with -EINVAL? I was thinking the other way around would be easier for the core to enforce. When inserting an rxnfc, it can do an ethtool.get_wol(ndev) and check WAKE_FILTER is set. That seems simpler than doing a get_rxnfc() and having to look through the results and try to figure out which are for WoL? Anyway, you seem to be volunteering to implement this, so either is fine for me, so long as we do have some central enforcement. Andrew
On 10/12/23 14:18, Andrew Lunn wrote: >>> But we should clearly define what we expect in terms of ordering and >>> maybe try to enforce it in the core. Can we make the rxnfc call return >>> -EBUSY or something and an extack message if WAKE_FILTER has not been >>> enabled first? >> >> It might make sense to do it the other way around, that is you must install >> filters first and if none are installed by the time we enable WAKE_FILTER in >> .set_wol(), we error out with -EINVAL? > > I was thinking the other way around would be easier for the core to > enforce. When inserting an rxnfc, it can do an ethtool.get_wol(ndev) > and check WAKE_FILTER is set. That seems simpler than doing a > get_rxnfc() and having to look through the results and try to figure > out which are for WoL? What you propose would be simpler, but I believe it would be more logical to: - install filter(s) - set ethtool WAKE_FILTER as the latter acts as a "commit", until that point the filters are installed, but may not be effective unless WAKE_FILTER is set and gets translated into the appropriate Wake-on-LAN enable bits. Of course nothing prevents you from doing the reverse or installing filters after setting WAkE_FILTER as long as the system does not go into suspend in between, everything should be working. > > Anyway, you seem to be volunteering to implement this, so either is > fine for me, so long as we do have some central enforcement. Yes, patches will follow, thanks!
diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 2540c70952ff..b2b1191d5cec 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -708,11 +708,13 @@ Kernel response contents: ``ETHTOOL_A_WOL_HEADER`` nested reply header ``ETHTOOL_A_WOL_MODES`` bitset mask of enabled WoL modes ``ETHTOOL_A_WOL_SOPASS`` binary SecureOn(tm) password + ``ETHTOOL_A_WOL_MAC_DA`` binary Destination matching MAC address ==================================== ====== ========================== In reply, ``ETHTOOL_A_WOL_MODES`` mask consists of modes supported by the device, value of modes which are enabled. ``ETHTOOL_A_WOL_SOPASS`` is only -included in reply if ``WAKE_MAGICSECURE`` mode is supported. +included in reply if ``WAKE_MAGICSECURE`` mode is supported. ``ETHTOOL_A_WOL_MAC_DA`` +is only included in reply if ``WAKE_MDA`` mode is supported. WOL_SET @@ -726,10 +728,13 @@ Request contents: ``ETHTOOL_A_WOL_HEADER`` nested request header ``ETHTOOL_A_WOL_MODES`` bitset enabled WoL modes ``ETHTOOL_A_WOL_SOPASS`` binary SecureOn(tm) password + ``ETHTOOL_A_WOL_MAC_DA`` binary Destination matching MAC address ==================================== ====== ========================== ``ETHTOOL_A_WOL_SOPASS`` is only allowed for devices supporting ``WAKE_MAGICSECURE`` mode. +``ETHTOOL_A_WOL_MAC_DA`` is only allowed for devices supporting +``WAKE_MDA`` mode. FEATURES_GET diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index f7fba0dc87e5..8134ac8870bd 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -207,12 +207,17 @@ struct ethtool_drvinfo { * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes. * @sopass: SecureOn(tm) password; meaningful only if %WAKE_MAGICSECURE * is set in @wolopts. + * @mac_da: Destination MAC address to match; meaningful only if + * %WAKE_MDA is set in @wolopts. */ struct ethtool_wolinfo { __u32 cmd; __u32 supported; __u32 wolopts; - __u8 sopass[SOPASS_MAX]; + union { + __u8 sopass[SOPASS_MAX]; + __u8 mac_da[ETH_ALEN]; + }; }; /* for passing single values */ @@ -1989,8 +1994,9 @@ static inline int ethtool_validate_duplex(__u8 duplex) #define WAKE_MAGIC (1 << 5) #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ #define WAKE_FILTER (1 << 7) +#define WAKE_MDA (1 << 8) -#define WOL_MODE_COUNT 8 +#define WOL_MODE_COUNT 9 /* L2-L4 network traffic flow types */ #define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 73e2c10dc2cc..237a0fc68997 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -300,6 +300,7 @@ enum { ETHTOOL_A_WOL_HEADER, /* nest - _A_HEADER_* */ ETHTOOL_A_WOL_MODES, /* bitset */ ETHTOOL_A_WOL_SOPASS, /* binary */ + ETHTOOL_A_WOL_MAC_DA, /* binary */ /* add new constants above here */ __ETHTOOL_A_WOL_CNT, diff --git a/net/ethtool/common.c b/net/ethtool/common.c index f5598c5f50de..d1c837f6094c 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -405,6 +405,7 @@ const char wol_mode_names[][ETH_GSTRING_LEN] = { [const_ilog2(WAKE_MAGIC)] = "magic", [const_ilog2(WAKE_MAGICSECURE)] = "magicsecure", [const_ilog2(WAKE_FILTER)] = "filter", + [const_ilog2(WAKE_MDA)] = "mac-da", }; static_assert(ARRAY_SIZE(wol_mode_names) == WOL_MODE_COUNT); diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index 9a333a8d04c1..5958e4483ced 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -407,7 +407,7 @@ extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HE extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1]; extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1]; extern const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_HEADER + 1]; -extern const struct nla_policy ethnl_wol_set_policy[ETHTOOL_A_WOL_SOPASS + 1]; +extern const struct nla_policy ethnl_wol_set_policy[ETHTOOL_A_WOL_MAC_DA + 1]; extern const struct nla_policy ethnl_features_get_policy[ETHTOOL_A_FEATURES_HEADER + 1]; extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANTED + 1]; extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1]; diff --git a/net/ethtool/wol.c b/net/ethtool/wol.c index 0ed56c9ac1bc..13dfcc9bb1e5 100644 --- a/net/ethtool/wol.c +++ b/net/ethtool/wol.c @@ -12,6 +12,7 @@ struct wol_reply_data { struct ethnl_reply_data base; struct ethtool_wolinfo wol; bool show_sopass; + bool show_mac_da; }; #define WOL_REPDATA(__reply_base) \ @@ -41,6 +42,8 @@ static int wol_prepare_data(const struct ethnl_req_info *req_base, /* do not include password in notifications */ data->show_sopass = !genl_info_is_ntf(info) && (data->wol.supported & WAKE_MAGICSECURE); + data->show_mac_da = !genl_info_is_ntf(info) && + (data->wol.supported & WAKE_MDA); return 0; } @@ -58,6 +61,8 @@ static int wol_reply_size(const struct ethnl_req_info *req_base, return len; if (data->show_sopass) len += nla_total_size(sizeof(data->wol.sopass)); + if (data->show_mac_da) + len += nla_total_size(sizeof(data->wol.mac_da)); return len; } @@ -79,6 +84,10 @@ static int wol_fill_reply(struct sk_buff *skb, nla_put(skb, ETHTOOL_A_WOL_SOPASS, sizeof(data->wol.sopass), data->wol.sopass)) return -EMSGSIZE; + if (data->show_mac_da && + nla_put(skb, ETHTOOL_A_WOL_MAC_DA, sizeof(data->wol.mac_da), + data->wol.mac_da)) + return -EMSGSIZE; return 0; } @@ -91,6 +100,8 @@ const struct nla_policy ethnl_wol_set_policy[] = { [ETHTOOL_A_WOL_MODES] = { .type = NLA_NESTED }, [ETHTOOL_A_WOL_SOPASS] = { .type = NLA_BINARY, .len = SOPASS_MAX }, + [ETHTOOL_A_WOL_MAC_DA] = { .type = NLA_BINARY, + .len = ETH_ALEN } }; static int @@ -131,6 +142,16 @@ ethnl_set_wol(struct ethnl_req_info *req_info, struct genl_info *info) ethnl_update_binary(wol.sopass, sizeof(wol.sopass), tb[ETHTOOL_A_WOL_SOPASS], &mod); } + if (tb[ETHTOOL_A_WOL_MAC_DA]) { + if (!(wol.supported & WAKE_MDA)) { + NL_SET_ERR_MSG_ATTR(info->extack, + tb[ETHTOOL_A_WOL_MAC_DA], + "mac-da not supported, cannot set MAC"); + return -EINVAL; + } + ethnl_update_binary(wol.mac_da, sizeof(wol.mac_da), + tb[ETHTOOL_A_WOL_MAC_DA], &mod); + } if (!mod) return 0;
Allow Ethernet PHY and MAC drivers with simplified matching logic to be waking-up on a custom MAC destination address. This is particularly useful for Ethernet PHYs which have limited amounts of buffering but can still wake-up on a custom MAC destination address. When WAKE_MDA is specified, the "sopass" field in the existing struct ethtool_wolinfo is re-purposed to hold a custom MAC destination address to match against. Example: ethtool -s eth0 wol e mac-da 01:00:5e:00:00:fb Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> --- Documentation/networking/ethtool-netlink.rst | 7 ++++++- include/uapi/linux/ethtool.h | 10 ++++++++-- include/uapi/linux/ethtool_netlink.h | 1 + net/ethtool/common.c | 1 + net/ethtool/netlink.h | 2 +- net/ethtool/wol.c | 21 ++++++++++++++++++++ 6 files changed, 38 insertions(+), 4 deletions(-)