Marco,

I think that functionality is already implemented in
ieee80211_mesh_housekeeping.  We use the  sinfo->inactive_time value,
which tracks how long it has been since traffic was received from a
peer, and that includes beacons.  The
IEEE80211_MESH_PEER_INACTIVITY_LIMIT is currently set at compile time
to 30 min.

Javier



On Thu, Oct 18, 2012 at 6:54 PM,  <[email protected]> wrote:
> From: Marco Porsch <[email protected]>
>
> Currently the mesh code relies on on a graceful peer link close with a
> Mesh Peering Close frame. That causes peer links to stay in established
> state after a node just silently disappeared.
>
> This commit adds a periodic check of the last RX time of an established
> peer link. If the time since the last RX time is longer than a threshold
> (given in beacon interval units), the link is closed, just as it would be
> in case of a received Mesh Peering Close frame.
> To calculate the timeout the peer's beacon interval is recorded and used.
>
> To keep a clear separation of kernel and userspace peering routines,
> only the kernel peering routines (mesh_plink_timer, mesh_rx_plink_frame)
> employ that timer. Userspace AMPE has to implement its own timeout routine.
>
> Signed-off-by: Marco Porsch <[email protected]>
> ---
>  net/mac80211/mesh.c       |    2 +-
>  net/mac80211/mesh.h       |    5 ++++-
>  net/mac80211/mesh_plink.c |   32 ++++++++++++++++++++++++++++----
>  net/mac80211/sta_info.h   |    2 ++
>  4 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index ff0296c..6d41e5d 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -696,7 +696,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct 
> ieee80211_sub_if_data *sdata,
>
>         if (elems.mesh_id && elems.mesh_config &&
>             mesh_matches_local(sdata, &elems))
> -               mesh_neighbour_update(sdata, mgmt->sa, &elems);
> +               mesh_neighbour_update(sdata, mgmt, &elems);
>
>         if (ifmsh->sync_ops)
>                 ifmsh->sync_ops->rx_bcn_presp(sdata,
> diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
> index 25d0f17..7884f2b 100644
> --- a/net/mac80211/mesh.h
> +++ b/net/mac80211/mesh.h
> @@ -209,6 +209,9 @@ struct mesh_rmc {
>
>  #define MESH_PATH_EXPIRE (600 * HZ)
>
> +/* timeout for established peer links (in peer's beacon interval units) */
> +#define MESH_PLINK_ESTAB_TIMEOUT 14
> +
>  /* Default maximum number of plinks per interface */
>  #define MESH_MAX_PLINKS                256
>
> @@ -282,7 +285,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath);
>  int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
>  /* Mesh plinks */
>  void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
> -                          u8 *hw_addr,
> +                          struct ieee80211_mgmt *mgmt,
>                            struct ieee802_11_elems *ie);
>  bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
>  u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
> diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
> index 3ab34d8..e8f528f 100644
> --- a/net/mac80211/mesh_plink.c
> +++ b/net/mac80211/mesh_plink.c
> @@ -404,13 +404,13 @@ static struct sta_info *mesh_peer_init(struct 
> ieee80211_sub_if_data *sdata,
>  }
>
>  void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
> -                          u8 *hw_addr,
> +                          struct ieee80211_mgmt *mgmt,
>                            struct ieee802_11_elems *elems)
>  {
>         struct sta_info *sta;
>
>         rcu_read_lock();
> -       sta = mesh_peer_init(sdata, hw_addr, elems);
> +       sta = mesh_peer_init(sdata, mgmt->sa, elems);
>         if (!sta)
>                 goto out;
>
> @@ -421,6 +421,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data 
> *sdata,
>             rssi_threshold_check(sta, sdata))
>                 mesh_plink_open(sta);
>
> +       sta->beacon_interval = le16_to_cpu(mgmt->u.beacon.beacon_int);
>  out:
>         rcu_read_unlock();
>  }
> @@ -495,6 +496,27 @@ static void mesh_plink_timer(unsigned long data)
>                 mesh_plink_fsm_restart(sta);
>                 spin_unlock_bh(&sta->lock);
>                 break;
> +       case NL80211_PLINK_ESTAB:
> +               /* link loss timer */
> +               if (time_after(jiffies,
> +                              sta->last_rx + MESH_PLINK_ESTAB_TIMEOUT *
> +                              TU_TO_JIFFIES(sta->beacon_interval))) {
> +                       u32 changed = 0;
> +
> +                       mpl_dbg(sta->sdata, "Mesh peer link with %pM lost\n",
> +                               sta->sta.addr);
> +                       changed |= __mesh_plink_deactivate(sta);
> +                       sta->plink_state = NL80211_PLINK_HOLDING;
> +                       mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
> +                       spin_unlock_bh(&sta->lock);
> +                       changed |= mesh_set_ht_prot_mode(sdata);
> +                       ieee80211_bss_info_change_notify(sdata, changed);
> +               } else {
> +                       mod_plink_timer(sta,
> +                                       TU_TO_JIFFIES(sta->beacon_interval));
> +                       spin_unlock_bh(&sta->lock);
> +               }
> +               break;
>         default:
>                 spin_unlock_bh(&sta->lock);
>                 break;
> @@ -863,7 +885,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data 
> *sdata, struct ieee80211_m
>                                             sta->sta.addr, llid, plid, 0);
>                         break;
>                 case CNF_ACPT:
> -                       del_timer(&sta->plink_timer);
> +                       mod_plink_timer(sta,
> +                                       TU_TO_JIFFIES(sta->beacon_interval));
>                         sta->plink_state = NL80211_PLINK_ESTAB;
>                         spin_unlock_bh(&sta->lock);
>                         changed |= mesh_plink_inc_estab_count(sdata);
> @@ -898,7 +921,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data 
> *sdata, struct ieee80211_m
>                                             sta->sta.addr, llid, plid, 
> reason);
>                         break;
>                 case OPN_ACPT:
> -                       del_timer(&sta->plink_timer);
> +                       mod_plink_timer(sta,
> +                                       TU_TO_JIFFIES(sta->beacon_interval));
>                         sta->plink_state = NL80211_PLINK_ESTAB;
>                         spin_unlock_bh(&sta->lock);
>                         changed |= mesh_plink_inc_estab_count(sdata);
> diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
> index c88f161f..45eae7e 100644
> --- a/net/mac80211/sta_info.h
> +++ b/net/mac80211/sta_info.h
> @@ -274,6 +274,7 @@ struct sta_ampdu_mlme {
>   * @t_offset_setpoint: reference timing offset of this sta to be used when
>   *     calculating clockdrift
>   * @ch_type: peer's channel type
> + * @beacon_interval: beacon interval of this station
>   * @debugfs: debug filesystem info
>   * @dead: set to true when sta is unlinked
>   * @uploaded: set to true when sta is uploaded to the driver
> @@ -370,6 +371,7 @@ struct sta_info {
>         s64 t_offset;
>         s64 t_offset_setpoint;
>         enum nl80211_channel_type ch_type;
> +       u16 beacon_interval;
>  #endif
>
>  #ifdef CONFIG_MAC80211_DEBUGFS
> --
> 1.7.9.5
>



-- 
Javier Cardona
cozybit Inc.
http://www.cozybit.com
_______________________________________________
Devel mailing list
[email protected]
http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel

Reply via email to