Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/mac80211/mesh.h
15109 views
1
/*
2
* Copyright (c) 2008, 2009 open80211s Ltd.
3
* Authors: Luis Carlos Cobo <[email protected]>
4
* Javier Cardona <[email protected]>
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_SN_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
*/
38
enum mesh_path_flags {
39
MESH_PATH_ACTIVE = BIT(0),
40
MESH_PATH_RESOLVING = BIT(1),
41
MESH_PATH_SN_VALID = BIT(2),
42
MESH_PATH_FIXED = BIT(3),
43
MESH_PATH_RESOLVED = BIT(4),
44
};
45
46
/**
47
* enum mesh_deferred_task_flags - mac80211 mesh deferred tasks
48
*
49
*
50
*
51
* @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
52
* @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
53
* to grow.
54
* @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
55
* grow
56
* @MESH_WORK_ROOT: the mesh root station needs to send a frame
57
*/
58
enum mesh_deferred_task_flags {
59
MESH_WORK_HOUSEKEEPING,
60
MESH_WORK_GROW_MPATH_TABLE,
61
MESH_WORK_GROW_MPP_TABLE,
62
MESH_WORK_ROOT,
63
};
64
65
/**
66
* struct mesh_path - mac80211 mesh path structure
67
*
68
* @dst: mesh path destination mac address
69
* @sdata: mesh subif
70
* @next_hop: mesh neighbor to which frames for this destination will be
71
* forwarded
72
* @timer: mesh path discovery timer
73
* @frame_queue: pending queue for frames sent to this destination while the
74
* path is unresolved
75
* @sn: target sequence number
76
* @metric: current metric to this destination
77
* @hop_count: hops to destination
78
* @exp_time: in jiffies, when the path will expire or when it expired
79
* @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
80
* retry
81
* @discovery_retries: number of discovery retries
82
* @flags: mesh path flags, as specified on &enum mesh_path_flags
83
* @state_lock: mesh path state lock
84
*
85
*
86
* The combination of dst and sdata is unique in the mesh path table. Since the
87
* next_hop STA is only protected by RCU as well, deleting the STA must also
88
* remove/substitute the mesh_path structure and wait until that is no longer
89
* reachable before destroying the STA completely.
90
*/
91
struct mesh_path {
92
u8 dst[ETH_ALEN];
93
u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
94
struct ieee80211_sub_if_data *sdata;
95
struct sta_info __rcu *next_hop;
96
struct timer_list timer;
97
struct sk_buff_head frame_queue;
98
struct rcu_head rcu;
99
u32 sn;
100
u32 metric;
101
u8 hop_count;
102
unsigned long exp_time;
103
u32 discovery_timeout;
104
u8 discovery_retries;
105
enum mesh_path_flags flags;
106
spinlock_t state_lock;
107
};
108
109
/**
110
* struct mesh_table
111
*
112
* @hash_buckets: array of hash buckets of the table
113
* @hashwlock: array of locks to protect write operations, one per bucket
114
* @hash_mask: 2^size_order - 1, used to compute hash idx
115
* @hash_rnd: random value used for hash computations
116
* @entries: number of entries in the table
117
* @free_node: function to free nodes of the table
118
* @copy_node: function to copy nodes of the table
119
* @size_order: determines size of the table, there will be 2^size_order hash
120
* buckets
121
* @mean_chain_len: maximum average length for the hash buckets' list, if it is
122
* reached, the table will grow
123
* rcu_head: RCU head to free the table
124
*/
125
struct mesh_table {
126
/* Number of buckets will be 2^N */
127
struct hlist_head *hash_buckets;
128
spinlock_t *hashwlock; /* One per bucket, for add/del */
129
unsigned int hash_mask; /* (2^size_order) - 1 */
130
__u32 hash_rnd; /* Used for hash generation */
131
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
132
void (*free_node) (struct hlist_node *p, bool free_leafs);
133
int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
134
int size_order;
135
int mean_chain_len;
136
137
struct rcu_head rcu_head;
138
};
139
140
/* Recent multicast cache */
141
/* RMC_BUCKETS must be a power of 2, maximum 256 */
142
#define RMC_BUCKETS 256
143
#define RMC_QUEUE_MAX_LEN 4
144
#define RMC_TIMEOUT (3 * HZ)
145
146
/**
147
* struct rmc_entry - entry in the Recent Multicast Cache
148
*
149
* @seqnum: mesh sequence number of the frame
150
* @exp_time: expiration time of the entry, in jiffies
151
* @sa: source address of the frame
152
*
153
* The Recent Multicast Cache keeps track of the latest multicast frames that
154
* have been received by a mesh interface and discards received multicast frames
155
* that are found in the cache.
156
*/
157
struct rmc_entry {
158
struct list_head list;
159
u32 seqnum;
160
unsigned long exp_time;
161
u8 sa[ETH_ALEN];
162
};
163
164
struct mesh_rmc {
165
struct rmc_entry bucket[RMC_BUCKETS];
166
u32 idx_mask;
167
};
168
169
170
#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
171
172
#define MESH_PATH_EXPIRE (600 * HZ)
173
174
/* Default maximum number of plinks per interface */
175
#define MESH_MAX_PLINKS 256
176
177
/* Maximum number of paths per interface */
178
#define MESH_MAX_MPATHS 1024
179
180
/* Pending ANA approval */
181
#define MESH_PATH_SEL_ACTION 0
182
183
/* PERR reason codes */
184
#define PEER_RCODE_UNSPECIFIED 11
185
#define PERR_RCODE_NO_ROUTE 12
186
#define PERR_RCODE_DEST_UNREACH 13
187
188
/* Public interfaces */
189
/* Various */
190
int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
191
const u8 *da, const u8 *sa);
192
int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
193
struct ieee80211_sub_if_data *sdata, char *addr4or5,
194
char *addr6);
195
int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
196
struct ieee80211_sub_if_data *sdata);
197
bool mesh_matches_local(struct ieee802_11_elems *ie,
198
struct ieee80211_sub_if_data *sdata);
199
void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
200
void mesh_mgmt_ies_add(struct sk_buff *skb,
201
struct ieee80211_sub_if_data *sdata);
202
void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
203
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
204
void ieee80211s_init(void);
205
void ieee80211s_update_metric(struct ieee80211_local *local,
206
struct sta_info *stainfo, struct sk_buff *skb);
207
void ieee80211s_stop(void);
208
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
209
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
210
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
211
void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
212
213
/* Mesh paths */
214
int mesh_nexthop_lookup(struct sk_buff *skb,
215
struct ieee80211_sub_if_data *sdata);
216
void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
217
struct mesh_path *mesh_path_lookup(u8 *dst,
218
struct ieee80211_sub_if_data *sdata);
219
struct mesh_path *mpp_path_lookup(u8 *dst,
220
struct ieee80211_sub_if_data *sdata);
221
int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata);
222
struct mesh_path *mesh_path_lookup_by_idx(int idx,
223
struct ieee80211_sub_if_data *sdata);
224
void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
225
void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
226
void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
227
void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
228
struct ieee80211_mgmt *mgmt, size_t len);
229
int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
230
/* Mesh plinks */
231
void mesh_neighbour_update(u8 *hw_addr, u32 rates,
232
struct ieee80211_sub_if_data *sdata,
233
struct ieee802_11_elems *ie);
234
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
235
void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
236
void mesh_plink_broken(struct sta_info *sta);
237
void mesh_plink_deactivate(struct sta_info *sta);
238
int mesh_plink_open(struct sta_info *sta);
239
void mesh_plink_block(struct sta_info *sta);
240
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
241
struct ieee80211_mgmt *mgmt, size_t len,
242
struct ieee80211_rx_status *rx_status);
243
244
/* Private interfaces */
245
/* Mesh tables */
246
void mesh_mpath_table_grow(void);
247
void mesh_mpp_table_grow(void);
248
/* Mesh paths */
249
int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode,
250
const u8 *ra, struct ieee80211_sub_if_data *sdata);
251
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
252
void mesh_path_flush_pending(struct mesh_path *mpath);
253
void mesh_path_tx_pending(struct mesh_path *mpath);
254
int mesh_pathtbl_init(void);
255
void mesh_pathtbl_unregister(void);
256
int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata);
257
void mesh_path_timer(unsigned long data);
258
void mesh_path_flush_by_nexthop(struct sta_info *sta);
259
void mesh_path_discard_frame(struct sk_buff *skb,
260
struct ieee80211_sub_if_data *sdata);
261
void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
262
void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
263
void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
264
265
extern int mesh_paths_generation;
266
267
#ifdef CONFIG_MAC80211_MESH
268
extern int mesh_allocated;
269
270
static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
271
{
272
return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
273
atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
274
}
275
276
static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata)
277
{
278
return (min_t(long, mesh_plink_free_count(sdata),
279
MESH_MAX_PLINKS - sdata->local->num_sta)) > 0;
280
}
281
282
static inline void mesh_path_activate(struct mesh_path *mpath)
283
{
284
mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
285
}
286
287
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
288
{
289
return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
290
}
291
292
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
293
294
void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
295
void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata);
296
void mesh_plink_quiesce(struct sta_info *sta);
297
void mesh_plink_restart(struct sta_info *sta);
298
#else
299
#define mesh_allocated 0
300
static inline void
301
ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
302
static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
303
{}
304
static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
305
{}
306
static inline void mesh_plink_quiesce(struct sta_info *sta) {}
307
static inline void mesh_plink_restart(struct sta_info *sta) {}
308
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
309
{ return false; }
310
#endif
311
312
#endif /* IEEE80211S_H */
313
314