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

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

mac80211: split off mesh handling entirely



This patch splits off mesh handling from the STA/IBSS.
Unfortunately it increases mesh code size a bit, but I
think it makes things clearer. The patch also reduces
per-interface run-time memory usage.

Also clean up a few places where ifdef is not required.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7c950695
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -116,7 +116,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
		return ret;
		return ret;


	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
		ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
		ieee80211_sdata_set_mesh_id(sdata,
					    params->mesh_id_len,
					    params->mesh_id_len,
					    params->mesh_id);
					    params->mesh_id);


+19 −19
Original line number Original line Diff line number Diff line
@@ -207,37 +207,37 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);


#ifdef CONFIG_MAC80211_MESH
#ifdef CONFIG_MAC80211_MESH
/* Mesh stats attributes */
/* Mesh stats attributes */
IEEE80211_IF_FILE(fwded_frames, u.sta.mshstats.fwded_frames, DEC);
IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
IEEE80211_IF_FILE(dropped_frames_ttl, u.sta.mshstats.dropped_frames_ttl, DEC);
IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
IEEE80211_IF_FILE(dropped_frames_no_route,
IEEE80211_IF_FILE(dropped_frames_no_route,
		u.sta.mshstats.dropped_frames_no_route, DEC);
		u.mesh.mshstats.dropped_frames_no_route, DEC);
IEEE80211_IF_FILE(estab_plinks, u.sta.mshstats.estab_plinks, ATOMIC);
IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);


/* Mesh parameters */
/* Mesh parameters */
IEEE80211_IF_WFILE(dot11MeshMaxRetries,
IEEE80211_IF_WFILE(dot11MeshMaxRetries,
		u.sta.mshcfg.dot11MeshMaxRetries, DEC, u8);
		u.mesh.mshcfg.dot11MeshMaxRetries, DEC, u8);
IEEE80211_IF_WFILE(dot11MeshRetryTimeout,
IEEE80211_IF_WFILE(dot11MeshRetryTimeout,
		u.sta.mshcfg.dot11MeshRetryTimeout, DEC, u16);
		u.mesh.mshcfg.dot11MeshRetryTimeout, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshConfirmTimeout,
IEEE80211_IF_WFILE(dot11MeshConfirmTimeout,
		u.sta.mshcfg.dot11MeshConfirmTimeout, DEC, u16);
		u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshHoldingTimeout,
IEEE80211_IF_WFILE(dot11MeshHoldingTimeout,
		u.sta.mshcfg.dot11MeshHoldingTimeout, DEC, u16);
		u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshTTL, u.sta.mshcfg.dot11MeshTTL, DEC, u8);
IEEE80211_IF_WFILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC, u8);
IEEE80211_IF_WFILE(auto_open_plinks, u.sta.mshcfg.auto_open_plinks, DEC, u8);
IEEE80211_IF_WFILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC, u8);
IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks,
IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks,
		u.sta.mshcfg.dot11MeshMaxPeerLinks, DEC, u16);
		u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout,
IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout,
		u.sta.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32);
		u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32);
IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval,
IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval,
		u.sta.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16);
		u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime,
IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime,
		u.sta.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16);
		u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16);
IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries,
IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries,
		u.sta.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8);
		u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8);
IEEE80211_IF_WFILE(path_refresh_time,
IEEE80211_IF_WFILE(path_refresh_time,
		u.sta.mshcfg.path_refresh_time, DEC, u32);
		u.mesh.mshcfg.path_refresh_time, DEC, u32);
IEEE80211_IF_WFILE(min_discovery_timeout,
IEEE80211_IF_WFILE(min_discovery_timeout,
		u.sta.mshcfg.min_discovery_timeout, DEC, u16);
		u.mesh.mshcfg.min_discovery_timeout, DEC, u16);
#endif
#endif




@@ -350,7 +350,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
		add_mesh_stats(sdata);
		add_mesh_stats(sdata);
		add_mesh_config(sdata);
		add_mesh_config(sdata);
#endif
#endif
		/* fall through */
		break;
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_IBSS:
	case IEEE80211_IF_TYPE_IBSS:
		add_sta_files(sdata);
		add_sta_files(sdata);
@@ -487,7 +487,7 @@ static void del_files(struct ieee80211_sub_if_data *sdata)
		del_mesh_stats(sdata);
		del_mesh_stats(sdata);
		del_mesh_config(sdata);
		del_mesh_config(sdata);
#endif
#endif
		/* fall through */
		break;
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_IBSS:
	case IEEE80211_IF_TYPE_IBSS:
		del_sta_files(sdata);
		del_sta_files(sdata);
+54 −47
Original line number Original line Diff line number Diff line
@@ -308,7 +308,6 @@ enum ieee80211_sta_mlme_state {
	IEEE80211_STA_MLME_ASSOCIATED,
	IEEE80211_STA_MLME_ASSOCIATED,
	IEEE80211_STA_MLME_IBSS_SEARCH,
	IEEE80211_STA_MLME_IBSS_SEARCH,
	IEEE80211_STA_MLME_IBSS_JOINED,
	IEEE80211_STA_MLME_IBSS_JOINED,
	IEEE80211_STA_MLME_MESH_UP
};
};


/* bitfield of allowed auth algs */
/* bitfield of allowed auth algs */
@@ -325,34 +324,6 @@ struct ieee80211_if_sta {
	size_t ssid_len;
	size_t ssid_len;
	u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
	u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
	size_t scan_ssid_len;
	size_t scan_ssid_len;
#ifdef CONFIG_MAC80211_MESH
	struct timer_list mesh_path_timer;
	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
	size_t mesh_id_len;
	/* Active Path Selection Protocol Identifier */
	u8 mesh_pp_id[4];
	/* Active Path Selection Metric Identifier */
	u8 mesh_pm_id[4];
	/* Congestion Control Mode Identifier */
	u8 mesh_cc_id[4];
	/* Local mesh Destination Sequence Number */
	u32 dsn;
	/* Last used PREQ ID */
	u32 preq_id;
	atomic_t mpaths;
	/* Timestamp of last DSN update */
	unsigned long last_dsn_update;
	/* Timestamp of last DSN sent */
	unsigned long last_preq;
	struct mesh_rmc *rmc;
	spinlock_t mesh_preq_queue_lock;
	struct mesh_preq_queue preq_queue;
	int preq_queue_len;
	struct mesh_stats mshstats;
	struct mesh_config mshcfg;
	u32 mesh_seqnum;
	bool accepting_plinks;
#endif
	u16 aid;
	u16 aid;
	u16 ap_capab, capab;
	u16 ap_capab, capab;
	u8 *extra_ie; /* to be added to the end of AssocReq */
	u8 *extra_ie; /* to be added to the end of AssocReq */
@@ -387,20 +358,47 @@ struct ieee80211_if_sta {
	int num_beacons; /* number of TXed beacon frames by this STA */
	int num_beacons; /* number of TXed beacon frames by this STA */
};
};


static inline void ieee80211_if_sta_set_mesh_id(struct ieee80211_if_sta *ifsta,
struct ieee80211_if_mesh {
						u8 mesh_id_len, u8 *mesh_id)
	struct work_struct work;
{
	struct timer_list housekeeping_timer;
#ifdef CONFIG_MAC80211_MESH
	struct timer_list mesh_path_timer;
	ifsta->mesh_id_len = mesh_id_len;
	struct sk_buff_head skb_queue;
	memcpy(ifsta->mesh_id, mesh_id, mesh_id_len);

#endif
	bool housekeeping;
}

	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
	size_t mesh_id_len;
	/* Active Path Selection Protocol Identifier */
	u8 mesh_pp_id[4];
	/* Active Path Selection Metric Identifier */
	u8 mesh_pm_id[4];
	/* Congestion Control Mode Identifier */
	u8 mesh_cc_id[4];
	/* Local mesh Destination Sequence Number */
	u32 dsn;
	/* Last used PREQ ID */
	u32 preq_id;
	atomic_t mpaths;
	/* Timestamp of last DSN update */
	unsigned long last_dsn_update;
	/* Timestamp of last DSN sent */
	unsigned long last_preq;
	struct mesh_rmc *rmc;
	spinlock_t mesh_preq_queue_lock;
	struct mesh_preq_queue preq_queue;
	int preq_queue_len;
	struct mesh_stats mshstats;
	struct mesh_config mshcfg;
	u32 mesh_seqnum;
	bool accepting_plinks;
	int num_beacons;
};


#ifdef CONFIG_MAC80211_MESH
#ifdef CONFIG_MAC80211_MESH
#define IEEE80211_IFSTA_MESH_CTR_INC(sta, name)	\
#define IEEE80211_IFSTA_MESH_CTR_INC(msh, name)	\
	do { (sta)->mshstats.name++; } while (0)
	do { (msh)->mshstats.name++; } while (0)
#else
#else
#define IEEE80211_IFSTA_MESH_CTR_INC(sta, name) \
#define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \
	do { } while (0)
	do { } while (0)
#endif
#endif


@@ -455,6 +453,9 @@ struct ieee80211_sub_if_data {
		struct ieee80211_if_wds wds;
		struct ieee80211_if_wds wds;
		struct ieee80211_if_vlan vlan;
		struct ieee80211_if_vlan vlan;
		struct ieee80211_if_sta sta;
		struct ieee80211_if_sta sta;
#ifdef CONFIG_MAC80211_MESH
		struct ieee80211_if_mesh mesh;
#endif
		u32 mntr_flags;
		u32 mntr_flags;
	} u;
	} u;


@@ -548,6 +549,19 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
	return container_of(p, struct ieee80211_sub_if_data, vif);
	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 {
enum {
	IEEE80211_RX_MSG	= 1,
	IEEE80211_RX_MSG	= 1,
	IEEE80211_TX_STATUS_MSG	= 2,
	IEEE80211_TX_STATUS_MSG	= 2,
@@ -935,13 +949,6 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
void ieee80211_rx_bss_put(struct ieee80211_local *local,
void ieee80211_rx_bss_put(struct ieee80211_local *local,
			  struct ieee80211_sta_bss *bss);
			  struct ieee80211_sta_bss *bss);


#ifdef CONFIG_MAC80211_MESH
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
#else
static inline void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
{}
#endif

/* interface handling */
/* interface handling */
void ieee80211_if_setup(struct net_device *dev);
void ieee80211_if_setup(struct net_device *dev);
int ieee80211_if_add(struct ieee80211_local *local, const char *name,
int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+6 −7
Original line number Original line Diff line number Diff line
@@ -54,10 +54,9 @@ static void ieee80211_teardown_sdata(struct net_device *dev)


		break;
		break;
	case IEEE80211_IF_TYPE_MESH_POINT:
	case IEEE80211_IF_TYPE_MESH_POINT:
		/* Allow compiler to elide mesh_rmc_free call. */
		if (ieee80211_vif_is_mesh(&sdata->vif))
		if (ieee80211_vif_is_mesh(&sdata->vif))
			mesh_rmc_free(sdata);
			mesh_rmc_free(sdata);
		/* fall through */
		break;
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_IBSS:
	case IEEE80211_IF_TYPE_IBSS:
		kfree(sdata->u.sta.extra_ie);
		kfree(sdata->u.sta.extra_ie);
@@ -100,7 +99,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
		skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
		skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
		INIT_LIST_HEAD(&sdata->u.ap.vlans);
		INIT_LIST_HEAD(&sdata->u.ap.vlans);
		break;
		break;
	case IEEE80211_IF_TYPE_MESH_POINT:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_IBSS:
	case IEEE80211_IF_TYPE_IBSS:
		ifsta = &sdata->u.sta;
		ifsta = &sdata->u.sta;
@@ -117,7 +115,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
			IEEE80211_STA_AUTO_CHANNEL_SEL;
			IEEE80211_STA_AUTO_CHANNEL_SEL;
		if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
		if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
			ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
			ifsta->flags |= IEEE80211_STA_WMM_ENABLED;

		break;
	case IEEE80211_IF_TYPE_MESH_POINT:
		if (ieee80211_vif_is_mesh(&sdata->vif))
		if (ieee80211_vif_is_mesh(&sdata->vif))
			ieee80211_mesh_init_sdata(sdata);
			ieee80211_mesh_init_sdata(sdata);
		break;
		break;
@@ -225,7 +224,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,


	if (ieee80211_vif_is_mesh(&sdata->vif) &&
	if (ieee80211_vif_is_mesh(&sdata->vif) &&
	    params && params->mesh_id_len)
	    params && params->mesh_id_len)
		ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
		ieee80211_sdata_set_mesh_id(sdata,
					    params->mesh_id_len,
					    params->mesh_id_len,
					    params->mesh_id);
					    params->mesh_id);


+9 −4
Original line number Original line Diff line number Diff line
@@ -252,6 +252,8 @@ static int ieee80211_open(struct net_device *dev)
		sdata->bss = &sdata->u.ap;
		sdata->bss = &sdata->u.ap;
		break;
		break;
	case IEEE80211_IF_TYPE_MESH_POINT:
	case IEEE80211_IF_TYPE_MESH_POINT:
		if (!ieee80211_vif_is_mesh(&sdata->vif))
			break;
		/* mesh ifaces must set allmulti to forward mcast traffic */
		/* mesh ifaces must set allmulti to forward mcast traffic */
		atomic_inc(&local->iff_allmultis);
		atomic_inc(&local->iff_allmultis);
		break;
		break;
@@ -540,10 +542,6 @@ static int ieee80211_stop(struct net_device *dev)
		ieee80211_configure_filter(local);
		ieee80211_configure_filter(local);
		netif_addr_unlock_bh(local->mdev);
		netif_addr_unlock_bh(local->mdev);
		break;
		break;
	case IEEE80211_IF_TYPE_MESH_POINT:
		/* allmulti is always set on mesh ifaces */
		atomic_dec(&local->iff_allmultis);
		/* fall through */
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_STA:
	case IEEE80211_IF_TYPE_IBSS:
	case IEEE80211_IF_TYPE_IBSS:
		sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED;
		sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED;
@@ -571,6 +569,13 @@ static int ieee80211_stop(struct net_device *dev)
		sdata->u.sta.extra_ie = NULL;
		sdata->u.sta.extra_ie = NULL;
		sdata->u.sta.extra_ie_len = 0;
		sdata->u.sta.extra_ie_len = 0;
		/* fall through */
		/* fall through */
	case IEEE80211_IF_TYPE_MESH_POINT:
		if (ieee80211_vif_is_mesh(&sdata->vif)) {
			/* allmulti is always set on mesh ifaces */
			atomic_dec(&local->iff_allmultis);
			ieee80211_stop_mesh(sdata);
		}
		/* fall through */
	default:
	default:
		conf.vif = &sdata->vif;
		conf.vif = &sdata->vif;
		conf.type = sdata->vif.type;
		conf.type = sdata->vif.type;
Loading