Message ID | 20230302160310.923349-5-jaewan@google.com |
---|---|
State | Superseded |
Headers | show |
Series | mac80211_hwsim: Add PMSR support | expand |
On Thu, Mar 02, 2023 at 04:03:09PM +0000, Jaewan Kim wrote: > PMSR (a.k.a. peer measurement) is generalized measurement between two > devices with Wi-Fi support. And currently FTM (a.k.a. fine time > measurement or flight time measurement) is the one and only measurement. > > Add necessary functionalities for mac80211_hwsim to abort previous PMSR > request. The abortion request is sent to the wmedium where the PMSR request > is actually handled. > > In detail, add new mac80211_hwsim command HWSIM_CMD_ABORT_PMSR. When > mac80211_hwsim receives the PMSR abortion request via > ieee80211_ops.abort_pmsr, the received cfg80211_pmsr_request is resent to > the wmediumd with command HWSIM_CMD_ABORT_PMSR and attribute > HWSIM_ATTR_PMSR_REQUEST. The attribute is formatted as the same way as > nl80211_pmsr_start() expects. > > Signed-off-by: Jaewan Kim <jaewan@google.com> > --- > V7->V8: Rewrote commit msg > V7: Initial commit (split from previously large patch) > --- > drivers/net/wireless/mac80211_hwsim.c | 61 +++++++++++++++++++++++++++ > drivers/net/wireless/mac80211_hwsim.h | 2 + > 2 files changed, 63 insertions(+) > > diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c > index 691b83140d57..0d92a7e51057 100644 > --- a/drivers/net/wireless/mac80211_hwsim.c > +++ b/drivers/net/wireless/mac80211_hwsim.c > @@ -3343,6 +3343,66 @@ static int mac80211_hwsim_start_pmsr(struct ieee80211_hw *hw, > return err; > } > > +static void mac80211_hwsim_abort_pmsr(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + struct cfg80211_pmsr_request *request) > +{ > + struct mac80211_hwsim_data *data = hw->priv; > + u32 _portid = READ_ONCE(data->wmediumd); > + struct sk_buff *skb = NULL; > + int err = 0; > + void *msg_head; > + struct nlattr *pmsr; > + > + if (!_portid && !hwsim_virtio_enabled) > + return; > + > + mutex_lock(&data->mutex); > + > + if (data->pmsr_request != request) { > + err = -EINVAL; > + goto out_err; > + } > + > + if (err) > + return; How can this occur? And if it does, isn't the lock leaked? > + > + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); > + if (!skb) > + return; I think the mutex needs to be unlocked here in this error path. > + > + msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, HWSIM_CMD_ABORT_PMSR); > + > + if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, data->addresses[1].addr)) In the current scheme, I think err needs to be set here. > + goto out_err; > + > + pmsr = nla_nest_start(skb, HWSIM_ATTR_PMSR_REQUEST); > + if (!pmsr) { > + err = -ENOMEM; > + goto out_err; > + } > + > + err = mac80211_hwsim_send_pmsr_request(skb, request); > + if (err) I think this error path needs to call nla_nest_cancel(). > + goto out_err; > + > + err = nla_nest_end(skb, pmsr); > + if (err) I don't think is an error condition. > + goto out_err; > + > + genlmsg_end(skb, msg_head); > + if (hwsim_virtio_enabled) > + hwsim_tx_virtio(data, skb); > + else > + hwsim_unicast_netgroup(data, skb, _portid); > + > +out_err: > + if (err && skb) > + nlmsg_free(skb); > + > + mutex_unlock(&data->mutex); I think it might be nicer to arrange this as: goto out_unlock; err_nest_cancel: nla_nest_cancel(...); err_free: nlmsg_free(skb); out_unlock: mutex_unlock(&data->mutex); } > +} > + > #define HWSIM_COMMON_OPS \ > .tx = mac80211_hwsim_tx, \ > .wake_tx_queue = ieee80211_handle_wake_tx_queue, \ > @@ -3367,6 +3427,7 @@ static int mac80211_hwsim_start_pmsr(struct ieee80211_hw *hw, > .get_et_stats = mac80211_hwsim_get_et_stats, \ > .get_et_strings = mac80211_hwsim_get_et_strings, \ > .start_pmsr = mac80211_hwsim_start_pmsr, \ > + .abort_pmsr = mac80211_hwsim_abort_pmsr, > > #define HWSIM_NON_MLO_OPS \ > .sta_add = mac80211_hwsim_sta_add, \ ...
On Mon, Mar 06, 2023 at 06:37:14PM +0100, Simon Horman wrote: > On Thu, Mar 02, 2023 at 04:03:09PM +0000, Jaewan Kim wrote: > > PMSR (a.k.a. peer measurement) is generalized measurement between two > > devices with Wi-Fi support. And currently FTM (a.k.a. fine time > > measurement or flight time measurement) is the one and only measurement. > > > > Add necessary functionalities for mac80211_hwsim to abort previous PMSR > > request. The abortion request is sent to the wmedium where the PMSR request > > is actually handled. > > > > In detail, add new mac80211_hwsim command HWSIM_CMD_ABORT_PMSR. When > > mac80211_hwsim receives the PMSR abortion request via > > ieee80211_ops.abort_pmsr, the received cfg80211_pmsr_request is resent to > > the wmediumd with command HWSIM_CMD_ABORT_PMSR and attribute > > HWSIM_ATTR_PMSR_REQUEST. The attribute is formatted as the same way as > > nl80211_pmsr_start() expects. ... > > + goto out_err; > > + > > + pmsr = nla_nest_start(skb, HWSIM_ATTR_PMSR_REQUEST); > > + if (!pmsr) { > > + err = -ENOMEM; > > + goto out_err; > > + } > > + > > + err = mac80211_hwsim_send_pmsr_request(skb, request); > > + if (err) > > I think this error path needs to call nla_nest_cancel(). As per Johannes's comment elsewhere, I now realise this is not necessary as the skb is destroyed. ...
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 691b83140d57..0d92a7e51057 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3343,6 +3343,66 @@ static int mac80211_hwsim_start_pmsr(struct ieee80211_hw *hw, return err; } +static void mac80211_hwsim_abort_pmsr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *request) +{ + struct mac80211_hwsim_data *data = hw->priv; + u32 _portid = READ_ONCE(data->wmediumd); + struct sk_buff *skb = NULL; + int err = 0; + void *msg_head; + struct nlattr *pmsr; + + if (!_portid && !hwsim_virtio_enabled) + return; + + mutex_lock(&data->mutex); + + if (data->pmsr_request != request) { + err = -EINVAL; + goto out_err; + } + + if (err) + return; + + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return; + + msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, HWSIM_CMD_ABORT_PMSR); + + if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, data->addresses[1].addr)) + goto out_err; + + pmsr = nla_nest_start(skb, HWSIM_ATTR_PMSR_REQUEST); + if (!pmsr) { + err = -ENOMEM; + goto out_err; + } + + err = mac80211_hwsim_send_pmsr_request(skb, request); + if (err) + goto out_err; + + err = nla_nest_end(skb, pmsr); + if (err) + goto out_err; + + genlmsg_end(skb, msg_head); + if (hwsim_virtio_enabled) + hwsim_tx_virtio(data, skb); + else + hwsim_unicast_netgroup(data, skb, _portid); + +out_err: + if (err && skb) + nlmsg_free(skb); + + mutex_unlock(&data->mutex); +} + #define HWSIM_COMMON_OPS \ .tx = mac80211_hwsim_tx, \ .wake_tx_queue = ieee80211_handle_wake_tx_queue, \ @@ -3367,6 +3427,7 @@ static int mac80211_hwsim_start_pmsr(struct ieee80211_hw *hw, .get_et_stats = mac80211_hwsim_get_et_stats, \ .get_et_strings = mac80211_hwsim_get_et_strings, \ .start_pmsr = mac80211_hwsim_start_pmsr, \ + .abort_pmsr = mac80211_hwsim_abort_pmsr, #define HWSIM_NON_MLO_OPS \ .sta_add = mac80211_hwsim_sta_add, \ diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 98e586a56582..383f3e39c911 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -83,6 +83,7 @@ enum hwsim_tx_control_flags { * are the same as to @HWSIM_CMD_ADD_MAC_ADDR. * @HWSIM_CMD_START_PMSR: request to start peer measurement with the * %HWSIM_ATTR_PMSR_REQUEST. + * @HWSIM_CMD_ABORT_PMSR: abort previously sent peer measurement * @__HWSIM_CMD_MAX: enum limit */ enum { @@ -96,6 +97,7 @@ enum { HWSIM_CMD_ADD_MAC_ADDR, HWSIM_CMD_DEL_MAC_ADDR, HWSIM_CMD_START_PMSR, + HWSIM_CMD_ABORT_PMSR, __HWSIM_CMD_MAX, }; #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
PMSR (a.k.a. peer measurement) is generalized measurement between two devices with Wi-Fi support. And currently FTM (a.k.a. fine time measurement or flight time measurement) is the one and only measurement. Add necessary functionalities for mac80211_hwsim to abort previous PMSR request. The abortion request is sent to the wmedium where the PMSR request is actually handled. In detail, add new mac80211_hwsim command HWSIM_CMD_ABORT_PMSR. When mac80211_hwsim receives the PMSR abortion request via ieee80211_ops.abort_pmsr, the received cfg80211_pmsr_request is resent to the wmediumd with command HWSIM_CMD_ABORT_PMSR and attribute HWSIM_ATTR_PMSR_REQUEST. The attribute is formatted as the same way as nl80211_pmsr_start() expects. Signed-off-by: Jaewan Kim <jaewan@google.com> --- V7->V8: Rewrote commit msg V7: Initial commit (split from previously large patch) --- drivers/net/wireless/mac80211_hwsim.c | 61 +++++++++++++++++++++++++++ drivers/net/wireless/mac80211_hwsim.h | 2 + 2 files changed, 63 insertions(+)