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

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

cfg80211/mac80211: add mesh join/leave commands



Instead of tying mesh activity to interface up,
add join and leave commands for mesh. Since we
must be backward compatible, let cfg80211 handle
joining a mesh if a mesh ID was pre-configured
when the device goes up.

Note that this therefore must modify mac80211 as
well since mac80211 needs to lose the logic to
start the mesh on interface up.

We now allow querying mesh parameters before the
mesh is connected, which simply returns defaults.
Setting them (internally renamed to "update") is
only allowed while connected. Specify them with
the new mesh join command instead where needed.

In mac80211, beaconing must now also follow the
mesh enabled/not enabled state, which is done
by testing the mesh ID.

Signed-off-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 bd90fdcc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -394,6 +394,11 @@
 *
 * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
 *
 * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial
 *	mesh config parameters may be given.
 * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
 *	network is determined by the network interface.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -500,6 +505,9 @@ enum nl80211_commands {

	NL80211_CMD_FRAME_WAIT_CANCEL,

	NL80211_CMD_JOIN_MESH,
	NL80211_CMD_LEAVE_MESH,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
+29 −9
Original line number Diff line number Diff line
@@ -258,13 +258,9 @@ struct ieee80211_supported_band {

/**
 * struct vif_params - describes virtual interface parameters
 * @mesh_id: mesh ID to use
 * @mesh_id_len: length of the mesh ID
 * @use_4addr: use 4-address frames
 */
struct vif_params {
       u8 *mesh_id;
       int mesh_id_len;
       int use_4addr;
};

@@ -615,6 +611,11 @@ struct bss_parameters {
	int ap_isolate;
};

/*
 * struct mesh_config - 802.11s mesh configuration
 *
 * These parameters can be changed while the mesh is active.
 */
struct mesh_config {
	/* Timeouts in ms */
	/* Mesh plink management parameters */
@@ -637,6 +638,18 @@ struct mesh_config {
	u8  dot11MeshHWMPRootMode;
};

/**
 * struct mesh_setup - 802.11s mesh setup configuration
 * @mesh_id: the mesh ID
 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
 *
 * These parameters are fixed when the mesh is created.
 */
struct mesh_setup {
	const u8 *mesh_id;
	u8 mesh_id_len;
};

/**
 * struct ieee80211_txq_params - TX queue parameters
 * @queue: TX queue identifier (NL80211_TXQ_Q_*)
@@ -1078,7 +1091,7 @@ struct cfg80211_pmksa {
 *
 * @get_mesh_params: Put the current mesh parameters into *params
 *
 * @set_mesh_params: Set mesh parameters.
 * @update_mesh_params: Update mesh parameters on a running mesh.
 *	The mask is a bitfield which tells us which parameters to
 *	set, and which to leave alone.
 *
@@ -1229,9 +1242,14 @@ struct cfg80211_ops {
	int	(*get_mesh_params)(struct wiphy *wiphy,
				struct net_device *dev,
				struct mesh_config *conf);
	int	(*set_mesh_params)(struct wiphy *wiphy,
				struct net_device *dev,
				const struct mesh_config *nconf, u32 mask);
	int	(*update_mesh_params)(struct wiphy *wiphy,
				      struct net_device *dev, u32 mask,
				      const struct mesh_config *nconf);
	int	(*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
			     const struct mesh_config *conf,
			     const struct mesh_setup *setup);
	int	(*leave_mesh)(struct wiphy *wiphy, struct net_device *dev);

	int	(*change_bss)(struct wiphy *wiphy, struct net_device *dev,
			      struct bss_parameters *params);

@@ -1647,6 +1665,8 @@ struct cfg80211_cached_keys;
 * @bssid: (private) Used by the internal configuration code
 * @ssid: (private) Used by the internal configuration code
 * @ssid_len: (private) Used by the internal configuration code
 * @mesh_id_len: (private) Used by the internal configuration code
 * @mesh_id_up_len: (private) Used by the internal configuration code
 * @wext: (private) Used by the internal wireless extensions compat code
 * @use_4addr: indicates 4addr mode is used on this interface, must be
 *	set by driver (if supported) on add_interface BEFORE registering the
@@ -1676,7 +1696,7 @@ struct wireless_dev {

	/* currently used for IBSS and SME - might be rearranged later */
	u8 ssid[IEEE80211_MAX_SSID_LEN];
	u8 ssid_len;
	u8 ssid_len, mesh_id_len, mesh_id_up_len;
	enum {
		CFG80211_SME_IDLE,
		CFG80211_SME_CONNECTING,
+30 −9
Original line number Diff line number Diff line
@@ -60,11 +60,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
	if (ret)
		return ret;

	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
		ieee80211_sdata_set_mesh_id(sdata,
					    params->mesh_id_len,
					    params->mesh_id);

	if (type == NL80211_IFTYPE_AP_VLAN &&
	    params && params->use_4addr == 0)
		rcu_assign_pointer(sdata->u.vlan.sta, NULL);
@@ -1003,9 +998,9 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
	return (mask >> (parm-1)) & 0x1;
}

static int ieee80211_set_mesh_params(struct wiphy *wiphy,
				struct net_device *dev,
				const struct mesh_config *nconf, u32 mask)
static int ieee80211_update_mesh_params(struct wiphy *wiphy,
					struct net_device *dev, u32 mask,
					const struct mesh_config *nconf)
{
	struct mesh_config *conf;
	struct ieee80211_sub_if_data *sdata;
@@ -1056,6 +1051,30 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
	return 0;
}

static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
			       const struct mesh_config *conf,
			       const struct mesh_setup *setup)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;

	memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config));
	ifmsh->mesh_id_len = setup->mesh_id_len;
	memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);

	ieee80211_start_mesh(sdata);

	return 0;
}

static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	ieee80211_stop_mesh(sdata);

	return 0;
}
#endif

static int ieee80211_change_bss(struct wiphy *wiphy,
@@ -1760,8 +1779,10 @@ struct cfg80211_ops mac80211_config_ops = {
	.change_mpath = ieee80211_change_mpath,
	.get_mpath = ieee80211_get_mpath,
	.dump_mpath = ieee80211_dump_mpath,
	.set_mesh_params = ieee80211_set_mesh_params,
	.update_mesh_params = ieee80211_update_mesh_params,
	.get_mesh_params = ieee80211_get_mesh_params,
	.join_mesh = ieee80211_join_mesh,
	.leave_mesh = ieee80211_leave_mesh,
#endif
	.change_bss = ieee80211_change_bss,
	.set_txq_params = ieee80211_set_txq_params,
+0 −13
Original line number Diff line number Diff line
@@ -609,19 +609,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
	return container_of(p, struct ieee80211_sub_if_data, vif);
}

static inline void
ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata,
			    u8 mesh_id_len, u8 *mesh_id)
{
#ifdef CONFIG_MAC80211_MESH
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
	ifmsh->mesh_id_len = mesh_id_len;
	memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len);
#else
	WARN_ON(1);
#endif
}

enum sdata_queue_type {
	IEEE80211_SDATA_QUEUE_TYPE_FRAME	= 0,
	IEEE80211_SDATA_QUEUE_AGG_START		= 1,
+1 −13
Original line number Diff line number Diff line
@@ -268,9 +268,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
				goto err_stop;
		}

		if (ieee80211_vif_is_mesh(&sdata->vif)) {
			ieee80211_start_mesh(sdata);
		} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
		if (sdata->vif.type == NL80211_IFTYPE_AP) {
			local->fif_pspoll++;
			local->fif_probe_req++;

@@ -495,10 +493,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
		ieee80211_adjust_monitor_flags(sdata, -1);
		ieee80211_configure_filter(local);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		if (ieee80211_vif_is_mesh(&sdata->vif))
			ieee80211_stop_mesh(sdata);
		/* fall through */
	default:
		flush_work(&sdata->work);
		/*
@@ -1188,12 +1182,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
	if (ret)
		goto fail;

	if (ieee80211_vif_is_mesh(&sdata->vif) &&
	    params && params->mesh_id_len)
		ieee80211_sdata_set_mesh_id(sdata,
					    params->mesh_id_len,
					    params->mesh_id);

	mutex_lock(&local->iflist_mtx);
	list_add_tail_rcu(&sdata->list, &local->interfaces);
	mutex_unlock(&local->iflist_mtx);
Loading