Mesh fixes and improvements
Subsystems (2)
[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
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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
Re: [PATCH 3/8] mac80211: Simulate transmission losses on plinks to aid in testing mesh metrics.
In reply to Javier CardonaQuoted 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_actionloss 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
Johannes Berg
maintainerRe: [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_actionloss 25I 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
Johannes Berg
maintainerQuoted 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
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
Kconfigthough 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
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.
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(-)
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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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