Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6335698e authored by Benjamin Beichler's avatar Benjamin Beichler Committed by Johannes Berg
Browse files

mac80211_hwsim: add generation count for netlink dump operation



Make the dump operation aware of changes on radio list and corresponding
inconsistent dumps. Changed variable name for better understanding.

Signed-off-by: default avatarBenjamin Beichler <benjamin.beichler@uni-rostock.de>
[compress ternary operator]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 301b0404
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -493,6 +493,7 @@ static LIST_HEAD(hwsim_radios);
static struct workqueue_struct *hwsim_wq;
static struct rhashtable hwsim_radios_rht;
static int hwsim_radio_idx;
static int hwsim_radios_generation = 1;

static struct platform_driver mac80211_hwsim_driver = {
	.driver = {
@@ -2807,6 +2808,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
	}

	list_add_tail(&data->list, &hwsim_radios);
	hwsim_radios_generation++;
	spin_unlock_bh(&hwsim_radio_lock);

	if (idx > 0)
@@ -3277,6 +3279,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
		list_del(&data->list);
		rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
				       hwsim_rht_params);
		hwsim_radios_generation++;
		spin_unlock_bh(&hwsim_radio_lock);
		mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
					 info);
@@ -3333,17 +3336,19 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
static int hwsim_dump_radio_nl(struct sk_buff *skb,
			       struct netlink_callback *cb)
{
	int idx = cb->args[0];
	int last_idx = cb->args[0];
	struct mac80211_hwsim_data *data = NULL;
	int res;
	int res = 0;
	void *hdr;

	spin_lock_bh(&hwsim_radio_lock);
	cb->seq = hwsim_radios_generation;

	if (idx == hwsim_radio_idx)
	if (last_idx >= hwsim_radio_idx-1)
		goto done;

	list_for_each_entry(data, &hwsim_radios, list) {
		if (data->idx < idx)
		if (data->idx <= last_idx)
			continue;

		if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
@@ -3356,14 +3361,25 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
		if (res < 0)
			break;

		idx = data->idx + 1;
		last_idx = data->idx;
	}

	cb->args[0] = idx;
	cb->args[0] = last_idx;

	/* list changed, but no new element sent, set interrupted flag */
	if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
		hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
				  cb->nlh->nlmsg_seq, &hwsim_genl_family,
				  NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
		if (!hdr)
			res = -EMSGSIZE;
		genl_dump_check_consistent(cb, hdr);
		genlmsg_end(skb, hdr);
	}

done:
	spin_unlock_bh(&hwsim_radio_lock);
	return skb->len;
	return res ?: skb->len;
}

/* Generic Netlink operations array */
@@ -3421,6 +3437,7 @@ static void destroy_radio(struct work_struct *work)
	struct mac80211_hwsim_data *data =
		container_of(work, struct mac80211_hwsim_data, destroy_work);

	hwsim_radios_generation++;
	mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
}