diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mesh.c | 43 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 4 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 60 |
3 files changed, 53 insertions, 54 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 75378e852f00..29e9980c8e60 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -287,49 +287,6 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
290 | u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) | ||
291 | { | ||
292 | /* Use last four bytes of hw addr and interface index as hash index */ | ||
293 | return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) | ||
294 | & tbl->hash_mask; | ||
295 | } | ||
296 | |||
297 | struct mesh_table *mesh_table_alloc(int size_order) | ||
298 | { | ||
299 | int i; | ||
300 | struct mesh_table *newtbl; | ||
301 | |||
302 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); | ||
303 | if (!newtbl) | ||
304 | return NULL; | ||
305 | |||
306 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * | ||
307 | (1 << size_order), GFP_KERNEL); | ||
308 | |||
309 | if (!newtbl->hash_buckets) { | ||
310 | kfree(newtbl); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
314 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * | ||
315 | (1 << size_order), GFP_KERNEL); | ||
316 | if (!newtbl->hashwlock) { | ||
317 | kfree(newtbl->hash_buckets); | ||
318 | kfree(newtbl); | ||
319 | return NULL; | ||
320 | } | ||
321 | |||
322 | newtbl->size_order = size_order; | ||
323 | newtbl->hash_mask = (1 << size_order) - 1; | ||
324 | atomic_set(&newtbl->entries, 0); | ||
325 | get_random_bytes(&newtbl->hash_rnd, | ||
326 | sizeof(newtbl->hash_rnd)); | ||
327 | for (i = 0; i <= newtbl->hash_mask; i++) | ||
328 | spin_lock_init(&newtbl->hashwlock[i]); | ||
329 | |||
330 | return newtbl; | ||
331 | } | ||
332 | |||
333 | 290 | ||
334 | static void ieee80211_mesh_path_timer(unsigned long data) | 291 | static void ieee80211_mesh_path_timer(unsigned long data) |
335 | { | 292 | { |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 10acf1cc8082..5c0c20389a1a 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -240,12 +240,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
240 | 240 | ||
241 | /* Private interfaces */ | 241 | /* Private interfaces */ |
242 | /* Mesh tables */ | 242 | /* Mesh tables */ |
243 | struct mesh_table *mesh_table_alloc(int size_order); | ||
244 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs); | ||
245 | void mesh_mpath_table_grow(void); | 243 | void mesh_mpath_table_grow(void); |
246 | void mesh_mpp_table_grow(void); | 244 | void mesh_mpp_table_grow(void); |
247 | u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, | ||
248 | struct mesh_table *tbl); | ||
249 | /* Mesh paths */ | 245 | /* Mesh paths */ |
250 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, | 246 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, |
251 | const u8 *ra, struct ieee80211_sub_if_data *sdata); | 247 | const u8 *ra, struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index c7cb3cc083df..0aa96cd6bd27 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -40,6 +40,50 @@ static struct mesh_table *mesh_paths; | |||
40 | static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ | 40 | static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ |
41 | 41 | ||
42 | int mesh_paths_generation; | 42 | int mesh_paths_generation; |
43 | |||
44 | /* This lock will have the grow table function as writer and add / delete nodes | ||
45 | * as readers. When reading the table (i.e. doing lookups) we are well protected | ||
46 | * by RCU | ||
47 | */ | ||
48 | static DEFINE_RWLOCK(pathtbl_resize_lock); | ||
49 | |||
50 | |||
51 | static struct mesh_table *mesh_table_alloc(int size_order) | ||
52 | { | ||
53 | int i; | ||
54 | struct mesh_table *newtbl; | ||
55 | |||
56 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); | ||
57 | if (!newtbl) | ||
58 | return NULL; | ||
59 | |||
60 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * | ||
61 | (1 << size_order), GFP_KERNEL); | ||
62 | |||
63 | if (!newtbl->hash_buckets) { | ||
64 | kfree(newtbl); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * | ||
69 | (1 << size_order), GFP_KERNEL); | ||
70 | if (!newtbl->hashwlock) { | ||
71 | kfree(newtbl->hash_buckets); | ||
72 | kfree(newtbl); | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
76 | newtbl->size_order = size_order; | ||
77 | newtbl->hash_mask = (1 << size_order) - 1; | ||
78 | atomic_set(&newtbl->entries, 0); | ||
79 | get_random_bytes(&newtbl->hash_rnd, | ||
80 | sizeof(newtbl->hash_rnd)); | ||
81 | for (i = 0; i <= newtbl->hash_mask; i++) | ||
82 | spin_lock_init(&newtbl->hashwlock[i]); | ||
83 | |||
84 | return newtbl; | ||
85 | } | ||
86 | |||
43 | static void __mesh_table_free(struct mesh_table *tbl) | 87 | static void __mesh_table_free(struct mesh_table *tbl) |
44 | { | 88 | { |
45 | kfree(tbl->hash_buckets); | 89 | kfree(tbl->hash_buckets); |
@@ -47,7 +91,7 @@ static void __mesh_table_free(struct mesh_table *tbl) | |||
47 | kfree(tbl); | 91 | kfree(tbl); |
48 | } | 92 | } |
49 | 93 | ||
50 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | 94 | static void mesh_table_free(struct mesh_table *tbl, bool free_leafs) |
51 | { | 95 | { |
52 | struct hlist_head *mesh_hash; | 96 | struct hlist_head *mesh_hash; |
53 | struct hlist_node *p, *q; | 97 | struct hlist_node *p, *q; |
@@ -66,7 +110,7 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
66 | } | 110 | } |
67 | 111 | ||
68 | static int mesh_table_grow(struct mesh_table *oldtbl, | 112 | static int mesh_table_grow(struct mesh_table *oldtbl, |
69 | struct mesh_table *newtbl) | 113 | struct mesh_table *newtbl) |
70 | { | 114 | { |
71 | struct hlist_head *oldhash; | 115 | struct hlist_head *oldhash; |
72 | struct hlist_node *p, *q; | 116 | struct hlist_node *p, *q; |
@@ -97,12 +141,14 @@ errcopy: | |||
97 | return -ENOMEM; | 141 | return -ENOMEM; |
98 | } | 142 | } |
99 | 143 | ||
144 | static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, | ||
145 | struct mesh_table *tbl) | ||
146 | { | ||
147 | /* Use last four bytes of hw addr and interface index as hash index */ | ||
148 | return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) | ||
149 | & tbl->hash_mask; | ||
150 | } | ||
100 | 151 | ||
101 | /* This lock will have the grow table function as writer and add / delete nodes | ||
102 | * as readers. When reading the table (i.e. doing lookups) we are well protected | ||
103 | * by RCU | ||
104 | */ | ||
105 | static DEFINE_RWLOCK(pathtbl_resize_lock); | ||
106 | 152 | ||
107 | /** | 153 | /** |
108 | * | 154 | * |