Skip to contentSkip to conversation

Mesh fixes and improvements

PATCH In review Javier Cardona 4 participants 22 messages Aug 8, 2009 – Aug 10, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

[Resent with proper patch numbering...]

This series includes some fixes, testing aids and improvements to the mesh stack. It is important to note that the patch "Use-3-address-format-for-mesh-broadcast-frames" breaks compatibility with previous versions. This is unavoidable and will keep happening as new versions of the 802.11s drafts are produced.

Also, I'm not sure if "Simulate-transmission-losses-on-plinks-to-..." should be merged upstream, but we find it really useful to test mesh configurations. Please comment if you have different opinions on its adequacy or implementation.

Cheers,

Javier

#1 lore raw

PATCH 1/8 mac80211: Improve dequeing from mpath frame queue.

From: Andrey Yurovsky <[email protected]>

Also, fix typo in comment.

---
 net/mac80211/mesh.h      |    2 +-
 net/mac80211/mesh_hwmp.c |    6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)
net/mac80211/mesh.h +1 -1
index ce53881..6aaf1ec 100644
@@ -61,7 +61,7 @@ enum mesh_path_flags {
  * 	retry
  * @discovery_retries: number of discovery retries
  * @flags: mesh path flags, as specified on &enum mesh_path_flags
- * @state_lock: mesh pat state lock
+ * @state_lock: mesh path state lock
  *
  *
  * The combination of dst and sdata is unique in the mesh path table. Since the
net/mac80211/mesh_hwmp.c +2 -4
index e1a763e..b54c21c 100644
@@ -810,10 +810,8 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 		}
 
 		if (skb_queue_len(&mpath->frame_queue) >=
-				MESH_FRAME_QUEUE_LEN) {
-			skb_to_free = mpath->frame_queue.next;
-			skb_unlink(skb_to_free, &mpath->frame_queue);
-		}
+				MESH_FRAME_QUEUE_LEN)
+			skb_to_free = skb_dequeue(&mpath->frame_queue);
 
 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 		skb_queue_tail(&mpath->frame_queue, skb);
Signature · 1 line
1.5.4.3
#2 lore raw

PATCH 2/8 mac80211: Use correct sign for mesh active path refresh.

From: Andrey Yurovsky <[email protected]>

On locally originated traffic, we refresh active paths after a timeout. The decision to do this was using the wrong sign and therefore the refresh timer was triggered for every frame.

---
 net/mac80211/mesh_hwmp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/mac80211/mesh_hwmp.c +1 -1
index b54c21c..1cd1e72 100644
@@ -791,7 +791,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 	}
 
 	if (mpath->flags & MESH_PATH_ACTIVE) {
-		if (time_after(jiffies, mpath->exp_time -
+		if (time_after(jiffies, mpath->exp_time +
 			msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
 				&& !memcmp(sdata->dev->dev_addr, hdr->addr4,
 					   ETH_ALEN)
Signature · 1 line
1.5.4.3
#3 lore raw

PATCH 3/8 mac80211: Simulate transmission losses on plinks to aid in testing mesh metrics.

This enables us to specify a simulated loss probability per mesh peer link. Useful to simulate and test different mesh topologies and test different mesh metrics.

The simulated loss rate setting can be configured as a plink action. The intended use is:

iw dev mesh station set <MAC> plink_action loss 25

---
 include/linux/nl80211.h   |    4 +++
 include/net/cfg80211.h    |    4 +++
 net/mac80211/cfg.c        |    6 +++++
 net/mac80211/mesh.c       |    1 +
 net/mac80211/mesh.h       |    1 +
 net/mac80211/mesh_hwmp.c  |    1 +
 net/mac80211/mesh_plink.c |    6 +++++
 net/mac80211/sta_info.h   |    1 +
 net/mac80211/tx.c         |   54 +++++++++++++++++++++++++++++++++++++++++++-
 net/wireless/nl80211.c    |    9 +++++++
 10 files changed, 85 insertions(+), 2 deletions(-)
include/linux/nl80211.h +4 -0
index a8d71ed..3de615b 100644
@@ -713,6 +713,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_KEYS,
 
 	NL80211_ATTR_PID,
+	NL80211_ATTR_SIM_LOSS,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -1198,6 +1199,8 @@ enum nl80211_mntr_flags {
  *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
+ * @NL80211_MESHCONF_SIM_LOSS_RATE: simulated loss rate at this MP.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -1215,6 +1218,7 @@ enum nl80211_meshconf_params {
 	NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
 	NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
 	NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+	NL80211_MESHCONF_SIM_LOSS_RATE,
 
 	/* keep last */
 	__NL80211_MESHCONF_ATTR_AFTER_LAST,
include/net/cfg80211.h +4 -0
index d5756c9..6bc5957 100644
@@ -265,6 +265,7 @@ enum plink_actions {
 	PLINK_ACTION_INVALID,
 	PLINK_ACTION_OPEN,
 	PLINK_ACTION_BLOCK,
+	PLINK_ACTION_LOSS,
 };
 
 /**
@@ -282,6 +283,7 @@ enum plink_actions {
  *	(bitmask of BIT(NL80211_STA_FLAG_...))
  * @listen_interval: listen interval or -1 for no change
  * @aid: AID or zero for no change
+ * @sim_loss_rate: simulated TX probable loss percentage
  */
 struct station_parameters {
 	u8 *supported_rates;
@@ -292,6 +294,7 @@ struct station_parameters {
 	u8 supported_rates_len;
 	u8 plink_action;
 	struct ieee80211_ht_cap *ht_capa;
+	u8 sim_loss_rate;
 };
 
 /**
@@ -508,6 +511,7 @@ struct mesh_config {
 	u32 dot11MeshHWMPactivePathTimeout;
 	u16 dot11MeshHWMPpreqMinInterval;
 	u16 dot11MeshHWMPnetDiameterTraversalTime;
+	u8 dot11MeshSimLossRate;
 };
 
 /**
net/mac80211/cfg.c +6 -0
index 5608f6c..8067f66 100644
@@ -693,6 +693,9 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 		case PLINK_ACTION_BLOCK:
 			mesh_plink_block(sta);
 			break;
+		case PLINK_ACTION_LOSS:
+			mesh_plink_sim_loss(sta, params->sim_loss_rate);
+			break;
 		}
 	}
 }
@@ -1043,6 +1046,9 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
 			   mask))
 		conf->dot11MeshHWMPnetDiameterTraversalTime =
 			nconf->dot11MeshHWMPnetDiameterTraversalTime;
+	if (_chg_mesh_attr(NL80211_MESHCONF_SIM_LOSS_RATE, mask))
+		conf->dot11MeshSimLossRate =
+			nconf->dot11MeshSimLossRate;
 	return 0;
 }
 
net/mac80211/mesh.c +1 -0
index 8c068e2..d9292a9 100644
@@ -653,6 +653,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 		MESH_PATH_REFRESH_TIME;
 	ifmsh->mshcfg.min_discovery_timeout =
 		MESH_MIN_DISCOVERY_TIMEOUT;
+	ifmsh->mshcfg.dot11MeshSimLossRate = 0;
 	ifmsh->accepting_plinks = true;
 	ifmsh->preq_id = 0;
 	ifmsh->dsn = 0;
net/mac80211/mesh.h +1 -0
index 6aaf1ec..8e70dae 100644
@@ -238,6 +238,7 @@ void mesh_plink_broken(struct sta_info *sta);
 void mesh_plink_deactivate(struct sta_info *sta);
 int mesh_plink_open(struct sta_info *sta);
 void mesh_plink_block(struct sta_info *sta);
+void mesh_plink_sim_loss(struct sta_info *sta, u8 rate);
 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_mgmt *mgmt, size_t len,
 			 struct ieee80211_rx_status *rx_status);
net/mac80211/mesh_hwmp.c +1 -0
index 1cd1e72..b4309b2 100644
@@ -272,6 +272,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 	}
 
 	last_hop_metric = airtime_link_metric_get(local, sta);
+	printk("XXX: last_hop_metric = %d\n", last_hop_metric);
 	/* Update and check originator routing info */
 	fresh_info = true;
 
net/mac80211/mesh_plink.c +6 -0
index cb14253..7c49c95 100644
@@ -382,6 +382,12 @@ void mesh_plink_block(struct sta_info *sta)
 	spin_unlock_bh(&sta->lock);
 }
 
+void mesh_plink_sim_loss(struct sta_info *sta, u8 rate)
+{
+	spin_lock_bh(&sta->lock);
+	sta->plink_sim_loss = rate;
+	spin_unlock_bh(&sta->lock);
+}
 
 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
 			 size_t len, struct ieee80211_rx_status *rx_status)
net/mac80211/sta_info.h +1 -0
index ccc3adf..a248a8b 100644
@@ -294,6 +294,7 @@ struct sta_info {
 	bool ignore_plink_timer;
 	bool plink_timer_was_running;
 	enum plink_state plink_state;
+	u8 plink_sim_loss;
 	u32 plink_timeout;
 	struct timer_list plink_timer;
 #endif
net/mac80211/tx.c +52 -2

84 lines not on this page · raw message

net/wireless/nl80211.c +9 -0
index 667a87d..1dfe8ea 100644
@@ -1878,6 +1878,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 		params.plink_action =
 		    nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
 
+	if (info->attrs[NL80211_ATTR_SIM_LOSS])
+		params.sim_loss_rate =
+			nla_get_u8(info->attrs[NL80211_ATTR_SIM_LOSS]);
+
 	rtnl_lock();
 
 	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
@@ -2619,6 +2623,8 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 			cur_params.dot11MeshHWMPpreqMinInterval);
 	NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
 			cur_params.dot11MeshHWMPnetDiameterTraversalTime);
+	NLA_PUT_U8(msg, NL80211_MESHCONF_SIM_LOSS_RATE,
+			cur_params.dot11MeshSimLossRate);
 	nla_nest_end(msg, pinfoattr);
 	genlmsg_end(msg, hdr);
 	err = genlmsg_reply(msg, info);
@@ -2661,6 +2667,7 @@ nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
 	[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
 	[NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
+	[NL80211_MESHCONF_SIM_LOSS_RATE] = { .type = NLA_U8 },
 };
 
 static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
@@ -2729,6 +2736,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
 			dot11MeshHWMPnetDiameterTraversalTime,
 			mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
 			nla_get_u16);
+	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshSimLossRate,
+			mask, NL80211_MESHCONF_SIM_LOSS_RATE, nla_get_u8);
 
 	/* Apply changes */
 	err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
Signature · 1 line
1.5.4.3
#4 lore raw

PATCH 4/8 mac80211: Use 3-address format for mesh broadcast frames.

The 11s task group recently changed the frame mesh multicast/broadcast frame format to use 3-address. This was done to avoid interactions with widely deployed lazy-WDS access points.

---
 net/mac80211/mesh.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++---
 net/mac80211/mesh.h |    5 +++-
 net/mac80211/rx.c   |   45 ++++++++++++++++++++++-------------
 net/mac80211/tx.c   |   64 +++++++++++++++++++++++++++------------------------
 net/wireless/util.c |   16 +++++++++---
 5 files changed, 136 insertions(+), 56 deletions(-)
net/mac80211/mesh.c +58 -4
index d9292a9..5202d7c 100644
@@ -399,21 +399,75 @@ endgrow:
 }
 
 /**
+ * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
+ * @hdr:    	802.11 frame header
+ * @fc:		frame control field
+ * @meshda:	destination address in the mesh
+ * @meshsa:	source address address in the mesh.  Same as TA, as frame is
+ *              locally originated.
+ *
+ * Return the length of the 802.11 (does not include a mesh control header)
+ */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char
+		*meshda, char *meshsa) {
+	if (is_multicast_ether_addr(meshda)) {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
+		/* DA TA SA */
+		memcpy(hdr->addr1, meshda, ETH_ALEN);
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshsa, ETH_ALEN);
+		return 24;
+	} else {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
+				IEEE80211_FCTL_TODS);
+		/* RA TA DA SA */
+		memset(hdr->addr1, 0, ETH_ALEN);   /* RA is resolved later */
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshda, ETH_ALEN);
+		memcpy(hdr->addr4, meshsa, ETH_ALEN);
+		return 30;
+	}
+}
+
+/**
  * ieee80211_new_mesh_header - create a new mesh header
  * @meshhdr:    uninitialized mesh header
  * @sdata:	mesh interface to be used
+ * @addr4:	addr4 of the mesh frame (1st in ae header)
+ *              may be NULL
+ * @addr5:	addr5 of the mesh frame (1st or 2nd in ae header)
+ *              may be NULL unless addr6 is present
+ * @addr6:	addr6 of the mesh frame (2nd or 3rd in ae header)
+ * 		may be NULL unless addr5 is present
  *
  * Return the header length.
  */
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata)
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6)
 {
-	meshhdr->flags = 0;
+	int aelen = 0;
+	memset(meshhdr, 0, sizeof(meshhdr));
 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
 	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
 	sdata->u.mesh.mesh_seqnum++;
-
-	return 6;
+	if (addr4) {
+		meshhdr->flags |= MESH_FLAGS_AE_A4;
+		aelen += ETH_ALEN;
+		memcpy(meshhdr->eaddr1, addr4, ETH_ALEN);
+	}
+	if (addr5 && addr6) {
+		meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
+		aelen += 2 * ETH_ALEN;
+		if (!addr4) {
+			memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
+		} else {
+			memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
+		}
+	}
+	return 6 + aelen;
 }
 
 static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
net/mac80211/mesh.h +4 -1
index 8e70dae..6cb3db8 100644
@@ -193,8 +193,11 @@ struct mesh_rmc {
 
 /* Public interfaces */
 /* Various */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
+		char *da, char *sa);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata);
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
 		struct ieee80211_sub_if_data *sdata);
 bool mesh_matches_local(struct ieee802_11_elems *ie,
net/mac80211/rx.c +28 -17

90 lines not on this page · raw message

net/mac80211/tx.c +34 -30

95 lines not on this page · raw message

net/wireless/util.c +12 -4
index ba387d8..693275a 100644
@@ -274,11 +274,11 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
 	switch (ae) {
 	case 0:
 		return 6;
-	case 1:
+	case MESH_FLAGS_AE_A4:
 		return 12;
-	case 2:
+	case MESH_FLAGS_AE_A5_A6:
 		return 18;
-	case 3:
+	case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
 		return 24;
 	default:
 		return 6;
@@ -333,10 +333,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
 		}
 		break;
 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
-		if (iftype != NL80211_IFTYPE_STATION ||
+		if ((iftype != NL80211_IFTYPE_STATION &&
+		    iftype != NL80211_IFTYPE_MESH_POINT) ||
 		    (is_multicast_ether_addr(dst) &&
 		     !compare_ether_addr(src, addr)))
 			return -1;
+		if (iftype == NL80211_IFTYPE_MESH_POINT) {
+			struct ieee80211s_hdr *meshdr =
+				(struct ieee80211s_hdr *) (skb->data + hdrlen);
+			hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+			if (meshdr->flags & MESH_FLAGS_AE_A4)
+				memcpy(src, meshdr->eaddr1, ETH_ALEN);
+		}
 		break;
 	case cpu_to_le16(0):
 		if (iftype != NL80211_IFTYPE_ADHOC)
Signature · 1 line
1.5.4.3
#5 lore raw

PATCH 5/8 mac80211: Update the station failed frames average when minstrel is used.

The fail_avg value is used to compute the mesh metric, and was only being set by the pid rate control module. This fixes the mesh path selection mechanism for cards that use mistrel for rate control.

---
 net/mac80211/rc80211_minstrel.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
net/mac80211/rc80211_minstrel.c +9 -1
index 7c51429..3ea9740 100644
@@ -155,12 +155,16 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 		   struct sk_buff *skb)
 {
 	struct minstrel_sta_info *mi = priv_sta;
+	struct minstrel_priv *mp = (struct minstrel_priv *)priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_rate *ar = info->status.rates;
+	struct ieee80211_local *local = hw_to_local(mp->hw);
+	struct sta_info *si;
 	int i, ndx;
 	int success;
 
 	success = !!(info->flags & IEEE80211_TX_STAT_ACK);
+	si = sta_info_get(local, sta->addr);
 
 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
 		if (ar[i].idx < 0)
@@ -172,8 +176,12 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
 		mi->r[ndx].attempts += ar[i].count;
 
-		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
+		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) {
 			mi->r[ndx].success += success;
+			if (si)
+				si->fail_avg = (18050 - mi->r[ndx].probability)
+					/ 180;
+		}
 	}
 
 	if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
Signature · 1 line
1.5.4.3
#6 lore raw

PATCH 6/8 mac80211: Early detection of broken mesh paths when using minstrel.

---
 net/mac80211/mesh_hwmp.c        |    1 -
 net/mac80211/rc80211_minstrel.c |    8 +++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)
net/mac80211/mesh_hwmp.c +0 -1
index b4309b2..1cd1e72 100644
@@ -272,7 +272,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 	}
 
 	last_hop_metric = airtime_link_metric_get(local, sta);
-	printk("XXX: last_hop_metric = %d\n", last_hop_metric);
 	/* Update and check originator routing info */
 	fresh_info = true;
 
net/mac80211/rc80211_minstrel.c +7 -1
index 3ea9740..0071649 100644
@@ -51,6 +51,7 @@
 #include <linux/random.h>
 #include <linux/ieee80211.h>
 #include <net/mac80211.h>
+#include "mesh.h"
 #include "rate.h"
 #include "rc80211_minstrel.h"
 
@@ -178,9 +179,14 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
 		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) {
 			mi->r[ndx].success += success;
-			if (si)
+			if (si) {
 				si->fail_avg = (18050 - mi->r[ndx].probability)
 					/ 180;
+				WARN_ON(si->fail_avg > 100);
+				if (si->fail_avg == 100 &&
+					ieee80211_vif_is_mesh(&si->sdata->vif))
+					mesh_plink_broken(si);
+			}
 		}
 	}
 
Signature · 1 line
1.5.4.3
#7 lore raw

PATCH 7/8 mac80211: Assign a default mesh beaconing interval.

Incidentally, this fixes mesh beaconing in mac80211_hwsim devices.

---
 net/mac80211/mesh.c |    6 ++++--
 net/mac80211/mesh.h |    1 +
 2 files changed, 5 insertions(+), 2 deletions(-)
net/mac80211/mesh.c +4 -2
index 5202d7c..3b49d39 100644
@@ -525,9 +525,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	struct ieee80211_local *local = sdata->local;
 
 	ifmsh->housekeeping = true;
-	ieee80211_queue_work(&local->hw, &ifmsh->work);
+	queue_work(local->hw, &ifmsh->work);
+	sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
 	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
-						BSS_CHANGED_BEACON_ENABLED);
+						BSS_CHANGED_BEACON_ENABLED |
+						BSS_CHANGED_BEACON_INT);
 }
 
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
net/mac80211/mesh.h +1 -0
index 6cb3db8..b6ea100 100644
@@ -174,6 +174,7 @@ struct mesh_rmc {
  */
 #define MESH_PATH_REFRESH_TIME			1000
 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
+#define MESH_DEFAULT_BEACON_INTERVAL		1000 	/* in 1024 us units */
 
 #define MESH_MAX_PREQ_RETRIES 4
 #define MESH_PATH_EXPIRE (600 * HZ)
Signature · 1 line
1.5.4.3
#8 lore raw

PATCH 8/8 mac80211: Moved mpath and mpp growth to mesh workqueue.

This prevents calling rcu_synchronize from within the tx path. Also, re-enable mesh in Kconfig

---
 net/mac80211/Kconfig        |    1 -
 net/mac80211/ieee80211_i.h  |    2 +-
 net/mac80211/mesh.c         |   75 +++-------------------
 net/mac80211/mesh.h         |   20 ++++++-
 net/mac80211/mesh_pathtbl.c |  146 ++++++++++++++++++++++++++++++++-----------
 5 files changed, 139 insertions(+), 105 deletions(-)
net/mac80211/Kconfig +0 -1
index 7dd77b6..9b4fcbc 100644
@@ -66,7 +66,6 @@ endmenu
 config MAC80211_MESH
 	bool "Enable mac80211 mesh networking (pre-802.11s) support"
 	depends on MAC80211 && EXPERIMENTAL
-	depends on BROKEN
 	---help---
 	 This options enables support of Draft 802.11s mesh networking.
 	 The implementation is based on Draft 1.08 of the Mesh Networking
net/mac80211/ieee80211_i.h +1 -1
index d6bd7dd..a6abc7d 100644
@@ -355,7 +355,7 @@ struct ieee80211_if_mesh {
 
 	unsigned long timers_running;
 
-	bool housekeeping;
+	unsigned long wrkq_flags;
 
 	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
 	size_t mesh_id_len;
net/mac80211/mesh.c +9 -66

111 lines not on this page · raw message

net/mac80211/mesh.h +19 -1
index b6ea100..fd4031f 100644
@@ -44,6 +44,23 @@ enum mesh_path_flags {
 };
 
 /**
+ * enum mesh_deferred_task_flags - mac80211 mesh deferred tasks
+ *
+ *
+ *
+ * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
+ * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
+ * to grow.
+ * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
+ * grow
+ */
+enum mesh_deferred_task_flags {
+	MESH_WORK_HOUSEKEEPING,
+	MESH_WORK_GROW_MPATH_TABLE,
+	MESH_WORK_GROW_MPP_TABLE,
+};
+
+/**
  * struct mesh_path - mac80211 mesh path structure
  *
  * @dst: mesh path destination mac address
@@ -251,7 +268,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 /* Mesh tables */
 struct mesh_table *mesh_table_alloc(int size_order);
 void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
-struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
+void mesh_mpath_table_grow(void);
+void mesh_mpp_table_grow(void);
 u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
 		struct mesh_table *tbl);
 /* Mesh paths */
net/mac80211/mesh_pathtbl.c +110 -36

209 lines not on this page · raw message

Signature · 1 line
1.5.4.3
#9 lore raw

Re: [PATCH 3/8] mac80211: Simulate transmission losses on plinks to aid in testing mesh metrics.

In reply to Javier Cardona
Quoted 8 lines · Javier Cardona

This enables us to specify a simulated loss probability per mesh peer link. Useful to simulate and test different mesh topologies and test different mesh metrics.

The simulated loss rate setting can be configured as a plink action. The intended use is:

iw dev mesh station set <MAC> plink_action loss 25

I really would not like to see debug functionality in nl80211 just to simplify the maintenance. Debugging belongs to debugfs or somewhere else.

Disclaimer: I know nothing about mesh and I may have misunderstood something.

Signature · 1 line
Kalle Valo
maintainer
#10 lore raw

Re: [PATCH 3/8] mac80211: Simulate transmission losses on plinks to aid in testing mesh metrics.

Quoted 6 lines · Kalle Valo
Quoted 4 lines · Javier Cardona

This enables us to specify a simulated loss probability per mesh peer link. Useful to simulate and test different mesh topologies and test different mesh metrics.

Quoted 8 lines
Quoted 4 lines

The simulated loss rate setting can be configured as a plink action. The intended use is:

iw dev mesh station set <MAC> plink_action loss 25

I really would not like to see debug functionality in nl80211 just to simplify the maintenance. Debugging belongs to debugfs or somewhere else.

I agree, and I also don't think it belongs into mac80211. I think this is a good case for actually finally writing the userspace frame forwarding for hwsim, so you can simulate _anything_ with simple userspace programs.

johannes

maintainer
#11 lore raw
In reply to Javier Cardona
Quoted 7 lines · Javier Cardona

[Resent with proper patch numbering...]

This series includes some fixes, testing aids and improvements to the mesh stack. It is important to note that the patch "Use-3-address-format-for-mesh-broadcast-frames" breaks compatibility with previous versions. This is unavoidable and will keep happening as new versions of the 802.11s drafts are produced.

That's ok, can you update the Kconfig though to indicate which draft it's compatible with? It says 1.08 right now.

Quoted 4 lines

Also, I'm not sure if "Simulate-transmission-losses-on-plinks-to-..." should be merged upstream, but we find it really useful to test mesh configurations. Please comment if you have different opinions on its adequacy or implementation.

As I said elsewhere in this thread I don't think that should be in, especially not, as Kalle points out, using nl80211.

All the other patches look ok on a cursory look, I just wish you'd write more detailed changelog entries.

johannes

#12 lore raw

Johannes,

Thanks for the review.

Quoted 8 lines · Johannes Berg
Quoted 5 lines

This series includes some fixes, testing aids and improvements to the mesh stack.  It is important to note that the patch "Use-3-address-format-for-mesh-broadcast-frames" breaks compatibility with previous versions.  This is unavoidable and will keep happening as new versions of the 802.11s drafts are produced.

That's ok, can you update the Kconfig though to indicate which draft it's compatible with? It says 1.08 right now.

Unfortunately I don't think it is fully compatible to one particular version. Furthermore, compliance with a Draft is not really
achievable: a vast number of identifiers (reason codes, element ids, status codes, ...) are not defined until the standard is ratified.

This particular change to the broadcast frame format was introduced between D2.03 and D2.08. Without it mesh networks will badly interact with widely deployed lazy WDS APs. It is not purely an interoperability issue with other mesh implementations but a requirement to achieve harmonious coexistence with deployed systems. I don't think we should hold this change back until closer compliance to a given draft version is implemented.

I'll still be happy to change the Kconfig, but bumping the version number to, say D2.08, might be misleading. I guess we should be more verbose in the Kconfig description.

Quoted 7 lines
Quoted 4 lines

Also, I'm not sure if "Simulate-transmission-losses-on-plinks-to-..." should be merged upstream, but we find it really useful to test mesh configurations. Please comment if you have different opinions on its adequacy or implementation.

As I said elsewhere in this thread I don't think that should be in, especially not, as Kalle points out, using nl80211.

Understood. I'll withdraw that patch and regenerate the series...

Quoted 2 lines

All the other patches look ok on a cursory look, I just wish you'd write more detailed changelog entries.

... with more changelogs.

Cheers,

Javier

#13 lore raw
Quoted 10 lines · Javier Cardona
Quoted 7 lines · Johannes Berg
Quoted 4 lines

Also, I'm not sure if "Simulate-transmission-losses-on-plinks-to-..." should be merged upstream, but we find it really useful to test mesh configurations. Please comment if you have different opinions on its adequacy or implementation.

As I said elsewhere in this thread I don't think that should be in, especially not, as Kalle points out, using nl80211.

Understood. I'll withdraw that patch and regenerate the series...

Dropping the series based on the above comment...

Signature · 2 lines
John W. Linville		Someday the world will need a hero, and you
[email protected]			might be all we have.  Be ready.
#14 lore raw

Mesh fixes and improvements [v2]

[v2]

Withdraw "Simulate-transmission-losses-on-plinks-to-...". Add detail to changelogs and Kconfig.
Changed queue_work -> ieee80211_queue_work

[v1]

This series includes some fixes, testing aids and improvements to the mesh stack. It is important to note that the patch "Use-3-address-format-for-mesh-broadcast-frames" breaks compatibility with previous versions. This is unavoidable and will keep happening as new versions of the 802.11s drafts are produced.

Also, I'm not sure if "Simulate-transmission-losses-on-plinks-to-..." should be merged upstream, but we find it really useful to test mesh configurations. Please comment if you have different opinions on its adequacy or implementation.

Cheers,

Javier

 include/linux/nl80211.h         |    4 +
 include/net/cfg80211.h          |    4 +
 net/mac80211/Kconfig            |    8 +-
 net/mac80211/cfg.c              |    6 ++
 net/mac80211/ieee80211_i.h      |    2 +-
 net/mac80211/mesh.c             |  136 ++++++++++++++++++------------------
 net/mac80211/mesh.h             |   29 +++++++-
 net/mac80211/mesh_hwmp.c        |    9 +--
 net/mac80211/mesh_pathtbl.c     |  146 +++++++++++++++++++++++++++++----------
 net/mac80211/mesh_plink.c       |    6 ++
 net/mac80211/rc80211_minstrel.c |   16 ++++-
 net/mac80211/rx.c               |   45 ++++++++-----
 net/mac80211/sta_info.h         |    1 +
 net/mac80211/tx.c               |  118 +++++++++++++++++++++++---------
 net/wireless/nl80211.c          |    9 +++
 net/wireless/util.c             |   16 +++-
 16 files changed, 384 insertions(+), 171 deletions(-)
#15 lore raw

PATCH 1/7 mac80211: Improve dequeing from mpath frame queue.

Also, fix typo in comment.

---
 net/mac80211/mesh.h      |    2 +-
 net/mac80211/mesh_hwmp.c |    6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)
net/mac80211/mesh.h +1 -1
index ce53881..6aaf1ec 100644
@@ -61,7 +61,7 @@ enum mesh_path_flags {
  * 	retry
  * @discovery_retries: number of discovery retries
  * @flags: mesh path flags, as specified on &enum mesh_path_flags
- * @state_lock: mesh pat state lock
+ * @state_lock: mesh path state lock
  *
  *
  * The combination of dst and sdata is unique in the mesh path table. Since the
net/mac80211/mesh_hwmp.c +2 -4
index e1a763e..b54c21c 100644
@@ -810,10 +810,8 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 		}
 
 		if (skb_queue_len(&mpath->frame_queue) >=
-				MESH_FRAME_QUEUE_LEN) {
-			skb_to_free = mpath->frame_queue.next;
-			skb_unlink(skb_to_free, &mpath->frame_queue);
-		}
+				MESH_FRAME_QUEUE_LEN)
+			skb_to_free = skb_dequeue(&mpath->frame_queue);
 
 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 		skb_queue_tail(&mpath->frame_queue, skb);
Signature · 1 line
1.5.4.3
#16 lore raw

PATCH 2/7 mac80211: Use correct sign for mesh active path refresh.

From: Andrey Yurovsky <[email protected]>

On locally originated traffic, we refresh active paths after a timeout. The decision to do this was using the wrong sign and therefore the refresh timer was triggered for every frame.

---
 net/mac80211/mesh_hwmp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/mac80211/mesh_hwmp.c +1 -1
index b54c21c..1cd1e72 100644
@@ -791,7 +791,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 	}
 
 	if (mpath->flags & MESH_PATH_ACTIVE) {
-		if (time_after(jiffies, mpath->exp_time -
+		if (time_after(jiffies, mpath->exp_time +
 			msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
 				&& !memcmp(sdata->dev->dev_addr, hdr->addr4,
 					   ETH_ALEN)
Signature · 1 line
1.5.4.3
#17 lore raw

PATCH 3/7 mac80211: Use 3-address format for mesh broadcast frames.

The 11s task group recently changed the frame mesh multicast/broadcast frame format to use 3-address. This was done to avoid interactions with widely deployed lazy-WDS access points.

This patch changes the format of group addressed frames, both mesh-originated and proxied, to use the data format defined in draft D2.08 and forward. The address fields used for group addressed frames is:

In 802.11 header
ToDS:0 FromDS:1
addr1: DA (broadcast/multicast address)
addr2: TA
addr3: Mesh SA

In address extension header:
addr4: SA (only present if frame was proxied)

Note that this change breaks backward compatibility with earlier mesh stack versions.

---
 net/mac80211/mesh.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++---
 net/mac80211/mesh.h |    5 +++-
 net/mac80211/rx.c   |   45 ++++++++++++++++++++++-------------
 net/mac80211/tx.c   |   64 +++++++++++++++++++++++++++------------------------
 net/wireless/util.c |   16 +++++++++---
 5 files changed, 136 insertions(+), 56 deletions(-)
net/mac80211/mesh.c +58 -4
index 8c068e2..10d9338 100644
@@ -399,21 +399,75 @@ endgrow:
 }
 
 /**
+ * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
+ * @hdr:    	802.11 frame header
+ * @fc:		frame control field
+ * @meshda:	destination address in the mesh
+ * @meshsa:	source address address in the mesh.  Same as TA, as frame is
+ *              locally originated.
+ *
+ * Return the length of the 802.11 (does not include a mesh control header)
+ */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char
+		*meshda, char *meshsa) {
+	if (is_multicast_ether_addr(meshda)) {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
+		/* DA TA SA */
+		memcpy(hdr->addr1, meshda, ETH_ALEN);
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshsa, ETH_ALEN);
+		return 24;
+	} else {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
+				IEEE80211_FCTL_TODS);
+		/* RA TA DA SA */
+		memset(hdr->addr1, 0, ETH_ALEN);   /* RA is resolved later */
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshda, ETH_ALEN);
+		memcpy(hdr->addr4, meshsa, ETH_ALEN);
+		return 30;
+	}
+}
+
+/**
  * ieee80211_new_mesh_header - create a new mesh header
  * @meshhdr:    uninitialized mesh header
  * @sdata:	mesh interface to be used
+ * @addr4:	addr4 of the mesh frame (1st in ae header)
+ *              may be NULL
+ * @addr5:	addr5 of the mesh frame (1st or 2nd in ae header)
+ *              may be NULL unless addr6 is present
+ * @addr6:	addr6 of the mesh frame (2nd or 3rd in ae header)
+ * 		may be NULL unless addr5 is present
  *
  * Return the header length.
  */
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata)
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6)
 {
-	meshhdr->flags = 0;
+	int aelen = 0;
+	memset(meshhdr, 0, sizeof(meshhdr));
 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
 	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
 	sdata->u.mesh.mesh_seqnum++;
-
-	return 6;
+	if (addr4) {
+		meshhdr->flags |= MESH_FLAGS_AE_A4;
+		aelen += ETH_ALEN;
+		memcpy(meshhdr->eaddr1, addr4, ETH_ALEN);
+	}
+	if (addr5 && addr6) {
+		meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
+		aelen += 2 * ETH_ALEN;
+		if (!addr4) {
+			memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
+		} else {
+			memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
+		}
+	}
+	return 6 + aelen;
 }
 
 static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
net/mac80211/mesh.h +4 -1
index 6aaf1ec..2ebd74c 100644
@@ -193,8 +193,11 @@ struct mesh_rmc {
 
 /* Public interfaces */
 /* Various */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
+		char *da, char *sa);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata);
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
 		struct ieee80211_sub_if_data *sdata);
 bool mesh_matches_local(struct ieee802_11_elems *ie,
net/mac80211/rx.c +28 -17

90 lines not on this page · raw message

net/mac80211/tx.c +34 -30

95 lines not on this page · raw message

net/wireless/util.c +12 -4
index ba387d8..693275a 100644
@@ -274,11 +274,11 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
 	switch (ae) {
 	case 0:
 		return 6;
-	case 1:
+	case MESH_FLAGS_AE_A4:
 		return 12;
-	case 2:
+	case MESH_FLAGS_AE_A5_A6:
 		return 18;
-	case 3:
+	case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
 		return 24;
 	default:
 		return 6;
@@ -333,10 +333,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
 		}
 		break;
 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
-		if (iftype != NL80211_IFTYPE_STATION ||
+		if ((iftype != NL80211_IFTYPE_STATION &&
+		    iftype != NL80211_IFTYPE_MESH_POINT) ||
 		    (is_multicast_ether_addr(dst) &&
 		     !compare_ether_addr(src, addr)))
 			return -1;
+		if (iftype == NL80211_IFTYPE_MESH_POINT) {
+			struct ieee80211s_hdr *meshdr =
+				(struct ieee80211s_hdr *) (skb->data + hdrlen);
+			hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+			if (meshdr->flags & MESH_FLAGS_AE_A4)
+				memcpy(src, meshdr->eaddr1, ETH_ALEN);
+		}
 		break;
 	case cpu_to_le16(0):
 		if (iftype != NL80211_IFTYPE_ADHOC)
Signature · 1 line
1.5.4.3
#18 lore raw

PATCH 4/7 mac80211: Update the station failed frames average when minstrel is used.

The fail_avg value is used to compute the mesh metric, and was only being set by the pid rate control module. This fixes the mesh path selection mechanism for cards that use mistrel for rate control.

---
 net/mac80211/rc80211_minstrel.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
net/mac80211/rc80211_minstrel.c +9 -1
index 7c51429..3ea9740 100644
@@ -155,12 +155,16 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 		   struct sk_buff *skb)
 {
 	struct minstrel_sta_info *mi = priv_sta;
+	struct minstrel_priv *mp = (struct minstrel_priv *)priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_rate *ar = info->status.rates;
+	struct ieee80211_local *local = hw_to_local(mp->hw);
+	struct sta_info *si;
 	int i, ndx;
 	int success;
 
 	success = !!(info->flags & IEEE80211_TX_STAT_ACK);
+	si = sta_info_get(local, sta->addr);
 
 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
 		if (ar[i].idx < 0)
@@ -172,8 +176,12 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
 		mi->r[ndx].attempts += ar[i].count;
 
-		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
+		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) {
 			mi->r[ndx].success += success;
+			if (si)
+				si->fail_avg = (18050 - mi->r[ndx].probability)
+					/ 180;
+		}
 	}
 
 	if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
Signature · 1 line
1.5.4.3
#19 lore raw

PATCH 5/7 mac80211: Early detection of broken mesh paths when using minstrel.

This change triggers a path discovery as soon as the link quality degrades below a certain threshold. This results in a faster path recovery time than by simply relying on the periodic path refresh mechanism to detect broken links.

---
 net/mac80211/rc80211_minstrel.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)
net/mac80211/rc80211_minstrel.c +7 -1
index 3ea9740..0071649 100644
@@ -51,6 +51,7 @@
 #include <linux/random.h>
 #include <linux/ieee80211.h>
 #include <net/mac80211.h>
+#include "mesh.h"
 #include "rate.h"
 #include "rc80211_minstrel.h"
 
@@ -178,9 +179,14 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
 		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) {
 			mi->r[ndx].success += success;
-			if (si)
+			if (si) {
 				si->fail_avg = (18050 - mi->r[ndx].probability)
 					/ 180;
+				WARN_ON(si->fail_avg > 100);
+				if (si->fail_avg == 100 &&
+					ieee80211_vif_is_mesh(&si->sdata->vif))
+					mesh_plink_broken(si);
+			}
 		}
 	}
 
Signature · 1 line
1.5.4.3
#20 lore raw

PATCH 6/7 mac80211: Assign a default mesh beaconing interval.

The mesh stack was enabling beaconing without specifying an interval. This patch defines a default beaconing interval of 1s.

Incidentally, this fixes mesh beaconing in mac80211_hwsim devices.

---
 net/mac80211/mesh.c |    6 ++++--
 net/mac80211/mesh.h |    1 +
 2 files changed, 5 insertions(+), 2 deletions(-)
net/mac80211/mesh.c +4 -2
index 10d9338..25d0065 100644
@@ -525,9 +525,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	struct ieee80211_local *local = sdata->local;
 
 	ifmsh->housekeeping = true;
-	ieee80211_queue_work(&local->hw, &ifmsh->work);
+	queue_work(local->hw, &ifmsh->work);
+	sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
 	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
-						BSS_CHANGED_BEACON_ENABLED);
+						BSS_CHANGED_BEACON_ENABLED |
+						BSS_CHANGED_BEACON_INT);
 }
 
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
net/mac80211/mesh.h +1 -0
index 2ebd74c..4241925 100644
@@ -174,6 +174,7 @@ struct mesh_rmc {
  */
 #define MESH_PATH_REFRESH_TIME			1000
 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
+#define MESH_DEFAULT_BEACON_INTERVAL		1000 	/* in 1024 us units */
 
 #define MESH_MAX_PREQ_RETRIES 4
 #define MESH_PATH_EXPIRE (600 * HZ)
Signature · 1 line
1.5.4.3
#21 lore raw

PATCH 7/7 mac80211: Move mpath and mpp growth to mesh workqueue.

This prevents calling rcu_synchronize from within the tx path by moving the table growth code to the mesh workqueue.

Move mesh_table_free and mesh_table_grow from mesh.c to mesh_pathtbl.c and declare them static.

Also, re-enable mesh in Kconfig and update the configuration description.

---
 net/mac80211/Kconfig        |    8 +-
 net/mac80211/ieee80211_i.h  |    2 +-
 net/mac80211/mesh.c         |   77 +++--------------------
 net/mac80211/mesh.h         |   20 ++++++-
 net/mac80211/mesh_pathtbl.c |  146 ++++++++++++++++++++++++++++++++-----------
 5 files changed, 144 insertions(+), 109 deletions(-)
net/mac80211/Kconfig +4 -4
index 7dd77b6..9db4ff8 100644
@@ -66,12 +66,12 @@ endmenu
 config MAC80211_MESH
 	bool "Enable mac80211 mesh networking (pre-802.11s) support"
 	depends on MAC80211 && EXPERIMENTAL
-	depends on BROKEN
 	---help---
 	 This options enables support of Draft 802.11s mesh networking.
-	 The implementation is based on Draft 1.08 of the Mesh Networking
-	 amendment. For more information visit http://o11s.org/.
-
+	 The implementation is based on Draft 2.08 of the Mesh Networking
+	 amendment.  However, no compliance with that draft is claimed or even
+	 possible, as drafts leave a number of identifiers to be defined after
+	 ratification.  For more information visit http://o11s.org/.
 
 config MAC80211_LEDS
 	bool "Enable LED triggers"
net/mac80211/ieee80211_i.h +1 -1
index d6bd7dd..a6abc7d 100644
@@ -355,7 +355,7 @@ struct ieee80211_if_mesh {
 
 	unsigned long timers_running;
 
-	bool housekeeping;
+	unsigned long wrkq_flags;
 
 	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
 	size_t mesh_id_len;
net/mac80211/mesh.c +10 -67

113 lines not on this page · raw message

net/mac80211/mesh.h +19 -1
index 4241925..eb23fc6 100644
@@ -44,6 +44,23 @@ enum mesh_path_flags {
 };
 
 /**
+ * enum mesh_deferred_task_flags - mac80211 mesh deferred tasks
+ *
+ *
+ *
+ * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
+ * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
+ * to grow.
+ * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
+ * grow
+ */
+enum mesh_deferred_task_flags {
+	MESH_WORK_HOUSEKEEPING,
+	MESH_WORK_GROW_MPATH_TABLE,
+	MESH_WORK_GROW_MPP_TABLE,
+};
+
+/**
  * struct mesh_path - mac80211 mesh path structure
  *
  * @dst: mesh path destination mac address
@@ -250,7 +267,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 /* Mesh tables */
 struct mesh_table *mesh_table_alloc(int size_order);
 void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
-struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
+void mesh_mpath_table_grow(void);
+void mesh_mpp_table_grow(void);
 u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
 		struct mesh_table *tbl);
 /* Mesh paths */
net/mac80211/mesh_pathtbl.c +110 -36

209 lines not on this page · raw message

Signature · 1 line
1.5.4.3