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

Commit bd90fdcc authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

nl80211: refactor mesh parameter parsing



I'm going to need this in a new place later.

Tested-by: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f9e10ce4
Loading
Loading
Loading
Loading
+38 −23
Original line number Diff line number Diff line
@@ -2613,14 +2613,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
	return -ENOBUFS;
}

#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
do {\
	if (table[attr_num]) {\
		cfg.param = nla_fn(table[attr_num]); \
		mask |= (1 << (attr_num - 1)); \
	} \
} while (0);\

static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
	[NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
	[NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
@@ -2639,31 +2631,34 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
};

static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
static int nl80211_parse_mesh_params(struct genl_info *info,
				     struct mesh_config *cfg,
				     u32 *mask_out)
{
	u32 mask;
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct net_device *dev = info->user_ptr[1];
	struct mesh_config cfg;
	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
	struct nlattr *parent_attr;
	u32 mask = 0;

	parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
	if (!parent_attr)
#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
do {\
	if (table[attr_num]) {\
		cfg->param = nla_fn(table[attr_num]); \
		mask |= (1 << (attr_num - 1)); \
	} \
} while (0);\


	if (!info->attrs[NL80211_ATTR_MESH_PARAMS])
		return -EINVAL;
	if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
			parent_attr, nl80211_meshconf_params_policy))
			     info->attrs[NL80211_ATTR_MESH_PARAMS],
			     nl80211_meshconf_params_policy))
		return -EINVAL;

	if (!rdev->ops->set_mesh_params)
		return -EOPNOTSUPP;

	/* This makes sure that there aren't more than 32 mesh config
	 * parameters (otherwise our bitfield scheme would not work.) */
	BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);

	/* Fill in the params struct */
	mask = 0;
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
			mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
@@ -2703,12 +2698,32 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
			NL80211_MESHCONF_HWMP_ROOTMODE,
			nla_get_u8);

	if (mask_out)
		*mask_out = mask;
	return 0;

#undef FILL_IN_MESH_PARAM_IF_SET
}

static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
{
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct net_device *dev = info->user_ptr[1];
	struct mesh_config cfg;
	u32 mask;
	int err;

	if (!rdev->ops->set_mesh_params)
		return -EOPNOTSUPP;

	err = nl80211_parse_mesh_params(info, &cfg, &mask);
	if (err)
		return err;

	/* Apply changes */
	return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
}

#undef FILL_IN_MESH_PARAM_IF_SET

static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *msg;