linux/net/mac80211/mesh.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008 open80211s Ltd.
   3 * Authors:    Luis Carlos Cobo <luisca@cozybit.com>
   4 *             Javier Cardona <javier@cozybit.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#ifndef IEEE80211S_H
  12#define IEEE80211S_H
  13
  14#include <linux/types.h>
  15#include <linux/jhash.h>
  16#include <asm/unaligned.h>
  17#include "ieee80211_i.h"
  18
  19
  20/* Data structures */
  21
  22/**
  23 * enum mesh_path_flags - mac80211 mesh path flags
  24 *
  25 *
  26 *
  27 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
  28 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
  29 * @MESH_PATH_DSN_VALID: the mesh path contains a valid destination sequence
  30 *      number
  31 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be
  32 *      modified
  33 * @MESH_PATH_RESOLVED: the mesh path can has been resolved
  34 *
  35 * MESH_PATH_RESOLVED is used by the mesh path timer to
  36 * decide when to stop or cancel the mesh path discovery.
  37 */
  38enum mesh_path_flags {
  39        MESH_PATH_ACTIVE =      BIT(0),
  40        MESH_PATH_RESOLVING =   BIT(1),
  41        MESH_PATH_DSN_VALID =   BIT(2),
  42        MESH_PATH_FIXED =       BIT(3),
  43        MESH_PATH_RESOLVED =    BIT(4),
  44};
  45
  46/**
  47 * struct mesh_path - mac80211 mesh path structure
  48 *
  49 * @dst: mesh path destination mac address
  50 * @sdata: mesh subif
  51 * @next_hop: mesh neighbor to which frames for this destination will be
  52 *      forwarded
  53 * @timer: mesh path discovery timer
  54 * @frame_queue: pending queue for frames sent to this destination while the
  55 *      path is unresolved
  56 * @dsn: destination sequence number of the destination
  57 * @metric: current metric to this destination
  58 * @hop_count: hops to destination
  59 * @exp_time: in jiffies, when the path will expire or when it expired
  60 * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
  61 *      retry
  62 * @discovery_retries: number of discovery retries
  63 * @flags: mesh path flags, as specified on &enum mesh_path_flags
  64 * @state_lock: mesh pat state lock
  65 *
  66 *
  67 * The combination of dst and sdata is unique in the mesh path table. Since the
  68 * next_hop STA is only protected by RCU as well, deleting the STA must also
  69 * remove/substitute the mesh_path structure and wait until that is no longer
  70 * reachable before destroying the STA completely.
  71 */
  72struct mesh_path {
  73        u8 dst[ETH_ALEN];
  74        u8 mpp[ETH_ALEN];       /* used for MPP or MAP */
  75        struct ieee80211_sub_if_data *sdata;
  76        struct sta_info *next_hop;
  77        struct timer_list timer;
  78        struct sk_buff_head frame_queue;
  79        struct rcu_head rcu;
  80        u32 dsn;
  81        u32 metric;
  82        u8 hop_count;
  83        unsigned long exp_time;
  84        u32 discovery_timeout;
  85        u8 discovery_retries;
  86        enum mesh_path_flags flags;
  87        spinlock_t state_lock;
  88};
  89
  90/**
  91 * struct mesh_table
  92 *
  93 * @hash_buckets: array of hash buckets of the table
  94 * @hashwlock: array of locks to protect write operations, one per bucket
  95 * @hash_mask: 2^size_order - 1, used to compute hash idx
  96 * @hash_rnd: random value used for hash computations
  97 * @entries: number of entries in the table
  98 * @free_node: function to free nodes of the table
  99 * @copy_node: fuction to copy nodes of the table
 100 * @size_order: determines size of the table, there will be 2^size_order hash
 101 *      buckets
 102 * @mean_chain_len: maximum average length for the hash buckets' list, if it is
 103 *      reached, the table will grow
 104 */
 105struct mesh_table {
 106        /* Number of buckets will be 2^N */
 107        struct hlist_head *hash_buckets;
 108        spinlock_t *hashwlock;          /* One per bucket, for add/del */
 109        unsigned int hash_mask;         /* (2^size_order) - 1 */
 110        __u32 hash_rnd;                 /* Used for hash generation */
 111        atomic_t entries;               /* Up to MAX_MESH_NEIGHBOURS */
 112        void (*free_node) (struct hlist_node *p, bool free_leafs);
 113        int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
 114        int size_order;
 115        int mean_chain_len;
 116};
 117
 118/* Recent multicast cache */
 119/* RMC_BUCKETS must be a power of 2, maximum 256 */
 120#define RMC_BUCKETS             256
 121#define RMC_QUEUE_MAX_LEN       4
 122#define RMC_TIMEOUT             (3 * HZ)
 123
 124/**
 125 * struct rmc_entry - entry in the Recent Multicast Cache
 126 *
 127 * @seqnum: mesh sequence number of the frame
 128 * @exp_time: expiration time of the entry, in jiffies
 129 * @sa: source address of the frame
 130 *
 131 * The Recent Multicast Cache keeps track of the latest multicast frames that
 132 * have been received by a mesh interface and discards received multicast frames
 133 * that are found in the cache.
 134 */
 135struct rmc_entry {
 136        struct list_head list;
 137        u32 seqnum;
 138        unsigned long exp_time;
 139        u8 sa[ETH_ALEN];
 140};
 141
 142struct mesh_rmc {
 143        struct rmc_entry bucket[RMC_BUCKETS];
 144        u32 idx_mask;
 145};
 146
 147
 148/*
 149 * MESH_CFG_COMP_LEN Includes:
 150 *      - Active path selection protocol ID.
 151 *      - Active path selection metric ID.
 152 *      - Congestion control mode identifier.
 153 *      - Channel precedence.
 154 * Does not include mesh capabilities, which may vary across nodes in the same
 155 * mesh
 156 */
 157#define MESH_CFG_CMP_LEN        (IEEE80211_MESH_CONFIG_LEN - 2)
 158
 159/* Default values, timeouts in ms */
 160#define MESH_TTL                5
 161#define MESH_MAX_RETR           3
 162#define MESH_RET_T              100
 163#define MESH_CONF_T             100
 164#define MESH_HOLD_T             100
 165
 166#define MESH_PATH_TIMEOUT       5000
 167/* Minimum interval between two consecutive PREQs originated by the same
 168 * interface
 169 */
 170#define MESH_PREQ_MIN_INT       10
 171#define MESH_DIAM_TRAVERSAL_TIME 50
 172/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their
 173 * expiration
 174 */
 175#define MESH_PATH_REFRESH_TIME                  1000
 176#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
 177
 178#define MESH_MAX_PREQ_RETRIES 4
 179#define MESH_PATH_EXPIRE (600 * HZ)
 180
 181/* Default maximum number of established plinks per interface */
 182#define MESH_MAX_ESTAB_PLINKS   32
 183
 184/* Default maximum number of plinks per interface */
 185#define MESH_MAX_PLINKS         256
 186
 187/* Maximum number of paths per interface */
 188#define MESH_MAX_MPATHS         1024
 189
 190/* Pending ANA approval */
 191#define PLINK_CATEGORY          30
 192#define MESH_PATH_SEL_CATEGORY  32
 193
 194/* Mesh Header Flags */
 195#define IEEE80211S_FLAGS_AE     0x3
 196
 197/* Public interfaces */
 198/* Various */
 199int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
 200int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
 201                struct ieee80211_sub_if_data *sdata);
 202int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
 203                struct ieee80211_sub_if_data *sdata);
 204bool mesh_matches_local(struct ieee802_11_elems *ie,
 205                struct ieee80211_sub_if_data *sdata);
 206void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
 207void mesh_mgmt_ies_add(struct sk_buff *skb,
 208                struct ieee80211_sub_if_data *sdata);
 209void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
 210int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
 211void ieee80211s_init(void);
 212void ieee80211s_stop(void);
 213void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
 214ieee80211_rx_result
 215ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 216                       struct ieee80211_rx_status *rx_status);
 217void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
 218void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 219
 220/* Mesh paths */
 221int mesh_nexthop_lookup(struct sk_buff *skb,
 222                struct ieee80211_sub_if_data *sdata);
 223void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
 224struct mesh_path *mesh_path_lookup(u8 *dst,
 225                struct ieee80211_sub_if_data *sdata);
 226struct mesh_path *mpp_path_lookup(u8 *dst,
 227                                  struct ieee80211_sub_if_data *sdata);
 228int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata);
 229struct mesh_path *mesh_path_lookup_by_idx(int idx,
 230                struct ieee80211_sub_if_data *sdata);
 231void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
 232void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
 233void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
 234void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
 235                struct ieee80211_mgmt *mgmt, size_t len);
 236int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
 237/* Mesh plinks */
 238void mesh_neighbour_update(u8 *hw_addr, u32 rates,
 239                struct ieee80211_sub_if_data *sdata, bool add);
 240bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
 241void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
 242void mesh_plink_broken(struct sta_info *sta);
 243void mesh_plink_deactivate(struct sta_info *sta);
 244int mesh_plink_open(struct sta_info *sta);
 245void mesh_plink_block(struct sta_info *sta);
 246void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 247                         struct ieee80211_mgmt *mgmt, size_t len,
 248                         struct ieee80211_rx_status *rx_status);
 249
 250/* Private interfaces */
 251/* Mesh tables */
 252struct mesh_table *mesh_table_alloc(int size_order);
 253void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
 254struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
 255u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
 256                struct mesh_table *tbl);
 257/* Mesh paths */
 258int mesh_path_error_tx(u8 *dest, __le32 dest_dsn, u8 *ra,
 259                struct ieee80211_sub_if_data *sdata);
 260void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
 261void mesh_path_flush_pending(struct mesh_path *mpath);
 262void mesh_path_tx_pending(struct mesh_path *mpath);
 263int mesh_pathtbl_init(void);
 264void mesh_pathtbl_unregister(void);
 265int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata);
 266void mesh_path_timer(unsigned long data);
 267void mesh_path_flush_by_nexthop(struct sta_info *sta);
 268void mesh_path_discard_frame(struct sk_buff *skb,
 269                struct ieee80211_sub_if_data *sdata);
 270
 271#ifdef CONFIG_MAC80211_MESH
 272extern int mesh_allocated;
 273
 274static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
 275{
 276        return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
 277               atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
 278}
 279
 280static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata)
 281{
 282        return (min_t(long, mesh_plink_free_count(sdata),
 283                   MESH_MAX_PLINKS - sdata->local->num_sta)) > 0;
 284}
 285
 286static inline void mesh_path_activate(struct mesh_path *mpath)
 287{
 288        mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
 289}
 290
 291#define for_each_mesh_entry(x, p, node, i) \
 292        for (i = 0; i <= x->hash_mask; i++) \
 293                hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
 294
 295void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
 296
 297#else
 298#define mesh_allocated  0
 299static inline void
 300ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
 301#endif
 302
 303#endif /* IEEE80211S_H */
 304