aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2014-10-09 08:27:51 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-10-09 10:13:01 -0400
commite9ed49bf4c2c2bd4d57667f14d595864d7596ded (patch)
treec0e437c99c70f78ab3fb06e40162fe1b847dc4f6
parent0f791eb47f8222fd594e6f8a090632344ef23924 (diff)
mac80211-hwsim: Add support for HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE
Add support for new attribute HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE which can be set by the user space component. The attribute will cause the kernel to destroy all those radios that were created by a process if that process dies. The old behaviour i.e., radios are persistent is still the default. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c40
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h3
2 files changed, 40 insertions, 3 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f1a0794b33f3..6ffe07323e6e 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -412,6 +412,9 @@ struct mac80211_hwsim_data {
412 struct mac_address addresses[2]; 412 struct mac_address addresses[2];
413 int channels, idx; 413 int channels, idx;
414 bool use_chanctx; 414 bool use_chanctx;
415 bool destroy_on_close;
416 struct work_struct destroy_work;
417 u32 portid;
415 418
416 struct ieee80211_channel *tmp_chan; 419 struct ieee80211_channel *tmp_chan;
417 struct delayed_work roc_done; 420 struct delayed_work roc_done;
@@ -496,6 +499,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
496 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 }, 499 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 },
497 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG }, 500 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG },
498 [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG }, 501 [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG },
502 [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG },
499}; 503};
500 504
501static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 505static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -1947,7 +1951,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1947static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, 1951static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1948 const struct ieee80211_regdomain *regd, 1952 const struct ieee80211_regdomain *regd,
1949 bool reg_strict, bool p2p_device, 1953 bool reg_strict, bool p2p_device,
1950 bool use_chanctx) 1954 bool use_chanctx, bool destroy_on_close,
1955 u32 portid)
1951{ 1956{
1952 int err; 1957 int err;
1953 u8 addr[ETH_ALEN]; 1958 u8 addr[ETH_ALEN];
@@ -2007,6 +2012,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
2007 data->channels = channels; 2012 data->channels = channels;
2008 data->use_chanctx = use_chanctx; 2013 data->use_chanctx = use_chanctx;
2009 data->idx = idx; 2014 data->idx = idx;
2015 data->destroy_on_close = destroy_on_close;
2016 data->portid = portid;
2010 2017
2011 if (data->use_chanctx) { 2018 if (data->use_chanctx) {
2012 hw->wiphy->max_scan_ssids = 255; 2019 hw->wiphy->max_scan_ssids = 255;
@@ -2434,6 +2441,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2434 const struct ieee80211_regdomain *regd = NULL; 2441 const struct ieee80211_regdomain *regd = NULL;
2435 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; 2442 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
2436 bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; 2443 bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
2444 bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE];
2437 bool use_chanctx; 2445 bool use_chanctx;
2438 2446
2439 if (info->attrs[HWSIM_ATTR_CHANNELS]) 2447 if (info->attrs[HWSIM_ATTR_CHANNELS])
@@ -2456,7 +2464,8 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2456 } 2464 }
2457 2465
2458 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, 2466 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict,
2459 p2p_device, use_chanctx); 2467 p2p_device, use_chanctx,
2468 destroy_on_close, info->snd_portid);
2460} 2469}
2461 2470
2462static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) 2471static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
@@ -2514,6 +2523,29 @@ static const struct genl_ops hwsim_ops[] = {
2514 }, 2523 },
2515}; 2524};
2516 2525
2526static void destroy_radio(struct work_struct *work)
2527{
2528 struct mac80211_hwsim_data *data =
2529 container_of(work, struct mac80211_hwsim_data, destroy_work);
2530
2531 mac80211_hwsim_destroy_radio(data);
2532}
2533
2534static void remove_user_radios(u32 portid)
2535{
2536 struct mac80211_hwsim_data *entry, *tmp;
2537
2538 spin_lock_bh(&hwsim_radio_lock);
2539 list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) {
2540 if (entry->destroy_on_close && entry->portid == portid) {
2541 list_del(&entry->list);
2542 INIT_WORK(&entry->destroy_work, destroy_radio);
2543 schedule_work(&entry->destroy_work);
2544 }
2545 }
2546 spin_unlock_bh(&hwsim_radio_lock);
2547}
2548
2517static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, 2549static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
2518 unsigned long state, 2550 unsigned long state,
2519 void *_notify) 2551 void *_notify)
@@ -2523,6 +2555,8 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
2523 if (state != NETLINK_URELEASE) 2555 if (state != NETLINK_URELEASE)
2524 return NOTIFY_DONE; 2556 return NOTIFY_DONE;
2525 2557
2558 remove_user_radios(notify->portid);
2559
2526 if (notify->portid == wmediumd_portid) { 2560 if (notify->portid == wmediumd_portid) {
2527 printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" 2561 printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
2528 " socket, switching to perfect channel medium\n"); 2562 " socket, switching to perfect channel medium\n");
@@ -2676,7 +2710,7 @@ static int __init init_mac80211_hwsim(void)
2676 err = mac80211_hwsim_create_radio(channels, reg_alpha2, 2710 err = mac80211_hwsim_create_radio(channels, reg_alpha2,
2677 regd, reg_strict, 2711 regd, reg_strict,
2678 support_p2p_device, 2712 support_p2p_device,
2679 channels > 1); 2713 channels > 1, false, 0);
2680 if (err < 0) 2714 if (err < 0)
2681 goto out_free_radios; 2715 goto out_free_radios;
2682 } 2716 }
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index c9d0315575ba..b96d8670a703 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -111,6 +111,8 @@ enum {
111 * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO 111 * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO
112 * command to force use of channel contexts even when only a 112 * command to force use of channel contexts even when only a
113 * single channel is supported 113 * single channel is supported
114 * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO
115 * command to force radio removal when process that created the radio dies
114 * @__HWSIM_ATTR_MAX: enum limit 116 * @__HWSIM_ATTR_MAX: enum limit
115 */ 117 */
116 118
@@ -132,6 +134,7 @@ enum {
132 HWSIM_ATTR_REG_STRICT_REG, 134 HWSIM_ATTR_REG_STRICT_REG,
133 HWSIM_ATTR_SUPPORT_P2P_DEVICE, 135 HWSIM_ATTR_SUPPORT_P2P_DEVICE,
134 HWSIM_ATTR_USE_CHANCTX, 136 HWSIM_ATTR_USE_CHANCTX,
137 HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE,
135 __HWSIM_ATTR_MAX, 138 __HWSIM_ATTR_MAX,
136}; 139};
137#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 140#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)