aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c474
1 files changed, 252 insertions, 222 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8d15b48d1692..7b729660cbfd 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -22,43 +22,44 @@
22#include "main.h" 22#include "main.h"
23#include "translation-table.h" 23#include "translation-table.h"
24#include "soft-interface.h" 24#include "soft-interface.h"
25#include "hard-interface.h"
25#include "hash.h" 26#include "hash.h"
26#include "originator.h" 27#include "originator.h"
27 28
28static void hna_local_purge(struct work_struct *work); 29static void tt_local_purge(struct work_struct *work);
29static void _hna_global_del_orig(struct bat_priv *bat_priv, 30static void _tt_global_del_orig(struct bat_priv *bat_priv,
30 struct hna_global_entry *hna_global_entry, 31 struct tt_global_entry *tt_global_entry,
31 char *message); 32 char *message);
32 33
33/* returns 1 if they are the same mac addr */ 34/* returns 1 if they are the same mac addr */
34static int compare_lhna(struct hlist_node *node, void *data2) 35static int compare_ltt(struct hlist_node *node, void *data2)
35{ 36{
36 void *data1 = container_of(node, struct hna_local_entry, hash_entry); 37 void *data1 = container_of(node, struct tt_local_entry, hash_entry);
37 38
38 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 39 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
39} 40}
40 41
41/* returns 1 if they are the same mac addr */ 42/* returns 1 if they are the same mac addr */
42static int compare_ghna(struct hlist_node *node, void *data2) 43static int compare_gtt(struct hlist_node *node, void *data2)
43{ 44{
44 void *data1 = container_of(node, struct hna_global_entry, hash_entry); 45 void *data1 = container_of(node, struct tt_global_entry, hash_entry);
45 46
46 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 47 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
47} 48}
48 49
49static void hna_local_start_timer(struct bat_priv *bat_priv) 50static void tt_local_start_timer(struct bat_priv *bat_priv)
50{ 51{
51 INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); 52 INIT_DELAYED_WORK(&bat_priv->tt_work, tt_local_purge);
52 queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); 53 queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, 10 * HZ);
53} 54}
54 55
55static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv, 56static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
56 void *data) 57 void *data)
57{ 58{
58 struct hashtable_t *hash = bat_priv->hna_local_hash; 59 struct hashtable_t *hash = bat_priv->tt_local_hash;
59 struct hlist_head *head; 60 struct hlist_head *head;
60 struct hlist_node *node; 61 struct hlist_node *node;
61 struct hna_local_entry *hna_local_entry, *hna_local_entry_tmp = NULL; 62 struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
62 int index; 63 int index;
63 64
64 if (!hash) 65 if (!hash)
@@ -68,26 +69,26 @@ static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
68 head = &hash->table[index]; 69 head = &hash->table[index];
69 70
70 rcu_read_lock(); 71 rcu_read_lock();
71 hlist_for_each_entry_rcu(hna_local_entry, node, head, hash_entry) { 72 hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
72 if (!compare_eth(hna_local_entry, data)) 73 if (!compare_eth(tt_local_entry, data))
73 continue; 74 continue;
74 75
75 hna_local_entry_tmp = hna_local_entry; 76 tt_local_entry_tmp = tt_local_entry;
76 break; 77 break;
77 } 78 }
78 rcu_read_unlock(); 79 rcu_read_unlock();
79 80
80 return hna_local_entry_tmp; 81 return tt_local_entry_tmp;
81} 82}
82 83
83static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv, 84static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
84 void *data) 85 void *data)
85{ 86{
86 struct hashtable_t *hash = bat_priv->hna_global_hash; 87 struct hashtable_t *hash = bat_priv->tt_global_hash;
87 struct hlist_head *head; 88 struct hlist_head *head;
88 struct hlist_node *node; 89 struct hlist_node *node;
89 struct hna_global_entry *hna_global_entry; 90 struct tt_global_entry *tt_global_entry;
90 struct hna_global_entry *hna_global_entry_tmp = NULL; 91 struct tt_global_entry *tt_global_entry_tmp = NULL;
91 int index; 92 int index;
92 93
93 if (!hash) 94 if (!hash)
@@ -97,125 +98,125 @@ static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
97 head = &hash->table[index]; 98 head = &hash->table[index];
98 99
99 rcu_read_lock(); 100 rcu_read_lock();
100 hlist_for_each_entry_rcu(hna_global_entry, node, head, hash_entry) { 101 hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
101 if (!compare_eth(hna_global_entry, data)) 102 if (!compare_eth(tt_global_entry, data))
102 continue; 103 continue;
103 104
104 hna_global_entry_tmp = hna_global_entry; 105 tt_global_entry_tmp = tt_global_entry;
105 break; 106 break;
106 } 107 }
107 rcu_read_unlock(); 108 rcu_read_unlock();
108 109
109 return hna_global_entry_tmp; 110 return tt_global_entry_tmp;
110} 111}
111 112
112int hna_local_init(struct bat_priv *bat_priv) 113int tt_local_init(struct bat_priv *bat_priv)
113{ 114{
114 if (bat_priv->hna_local_hash) 115 if (bat_priv->tt_local_hash)
115 return 1; 116 return 1;
116 117
117 bat_priv->hna_local_hash = hash_new(1024); 118 bat_priv->tt_local_hash = hash_new(1024);
118 119
119 if (!bat_priv->hna_local_hash) 120 if (!bat_priv->tt_local_hash)
120 return 0; 121 return 0;
121 122
122 atomic_set(&bat_priv->hna_local_changed, 0); 123 atomic_set(&bat_priv->tt_local_changed, 0);
123 hna_local_start_timer(bat_priv); 124 tt_local_start_timer(bat_priv);
124 125
125 return 1; 126 return 1;
126} 127}
127 128
128void hna_local_add(struct net_device *soft_iface, uint8_t *addr) 129void tt_local_add(struct net_device *soft_iface, uint8_t *addr)
129{ 130{
130 struct bat_priv *bat_priv = netdev_priv(soft_iface); 131 struct bat_priv *bat_priv = netdev_priv(soft_iface);
131 struct hna_local_entry *hna_local_entry; 132 struct tt_local_entry *tt_local_entry;
132 struct hna_global_entry *hna_global_entry; 133 struct tt_global_entry *tt_global_entry;
133 int required_bytes; 134 int required_bytes;
134 135
135 spin_lock_bh(&bat_priv->hna_lhash_lock); 136 spin_lock_bh(&bat_priv->tt_lhash_lock);
136 hna_local_entry = hna_local_hash_find(bat_priv, addr); 137 tt_local_entry = tt_local_hash_find(bat_priv, addr);
137 spin_unlock_bh(&bat_priv->hna_lhash_lock); 138 spin_unlock_bh(&bat_priv->tt_lhash_lock);
138 139
139 if (hna_local_entry) { 140 if (tt_local_entry) {
140 hna_local_entry->last_seen = jiffies; 141 tt_local_entry->last_seen = jiffies;
141 return; 142 return;
142 } 143 }
143 144
144 /* only announce as many hosts as possible in the batman-packet and 145 /* only announce as many hosts as possible in the batman-packet and
145 space in batman_packet->num_hna That also should give a limit to 146 space in batman_packet->num_tt That also should give a limit to
146 MAC-flooding. */ 147 MAC-flooding. */
147 required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; 148 required_bytes = (bat_priv->num_local_tt + 1) * ETH_ALEN;
148 required_bytes += BAT_PACKET_LEN; 149 required_bytes += BAT_PACKET_LEN;
149 150
150 if ((required_bytes > ETH_DATA_LEN) || 151 if ((required_bytes > ETH_DATA_LEN) ||
151 (atomic_read(&bat_priv->aggregated_ogms) && 152 (atomic_read(&bat_priv->aggregated_ogms) &&
152 required_bytes > MAX_AGGREGATION_BYTES) || 153 required_bytes > MAX_AGGREGATION_BYTES) ||
153 (bat_priv->num_local_hna + 1 > 255)) { 154 (bat_priv->num_local_tt + 1 > 255)) {
154 bat_dbg(DBG_ROUTES, bat_priv, 155 bat_dbg(DBG_ROUTES, bat_priv,
155 "Can't add new local hna entry (%pM): " 156 "Can't add new local tt entry (%pM): "
156 "number of local hna entries exceeds packet size\n", 157 "number of local tt entries exceeds packet size\n",
157 addr); 158 addr);
158 return; 159 return;
159 } 160 }
160 161
161 bat_dbg(DBG_ROUTES, bat_priv, 162 bat_dbg(DBG_ROUTES, bat_priv,
162 "Creating new local hna entry: %pM\n", addr); 163 "Creating new local tt entry: %pM\n", addr);
163 164
164 hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); 165 tt_local_entry = kmalloc(sizeof(struct tt_local_entry), GFP_ATOMIC);
165 if (!hna_local_entry) 166 if (!tt_local_entry)
166 return; 167 return;
167 168
168 memcpy(hna_local_entry->addr, addr, ETH_ALEN); 169 memcpy(tt_local_entry->addr, addr, ETH_ALEN);
169 hna_local_entry->last_seen = jiffies; 170 tt_local_entry->last_seen = jiffies;
170 171
171 /* the batman interface mac address should never be purged */ 172 /* the batman interface mac address should never be purged */
172 if (compare_eth(addr, soft_iface->dev_addr)) 173 if (compare_eth(addr, soft_iface->dev_addr))
173 hna_local_entry->never_purge = 1; 174 tt_local_entry->never_purge = 1;
174 else 175 else
175 hna_local_entry->never_purge = 0; 176 tt_local_entry->never_purge = 0;
176 177
177 spin_lock_bh(&bat_priv->hna_lhash_lock); 178 spin_lock_bh(&bat_priv->tt_lhash_lock);
178 179
179 hash_add(bat_priv->hna_local_hash, compare_lhna, choose_orig, 180 hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
180 hna_local_entry, &hna_local_entry->hash_entry); 181 tt_local_entry, &tt_local_entry->hash_entry);
181 bat_priv->num_local_hna++; 182 bat_priv->num_local_tt++;
182 atomic_set(&bat_priv->hna_local_changed, 1); 183 atomic_set(&bat_priv->tt_local_changed, 1);
183 184
184 spin_unlock_bh(&bat_priv->hna_lhash_lock); 185 spin_unlock_bh(&bat_priv->tt_lhash_lock);
185 186
186 /* remove address from global hash if present */ 187 /* remove address from global hash if present */
187 spin_lock_bh(&bat_priv->hna_ghash_lock); 188 spin_lock_bh(&bat_priv->tt_ghash_lock);
188 189
189 hna_global_entry = hna_global_hash_find(bat_priv, addr); 190 tt_global_entry = tt_global_hash_find(bat_priv, addr);
190 191
191 if (hna_global_entry) 192 if (tt_global_entry)
192 _hna_global_del_orig(bat_priv, hna_global_entry, 193 _tt_global_del_orig(bat_priv, tt_global_entry,
193 "local hna received"); 194 "local tt received");
194 195
195 spin_unlock_bh(&bat_priv->hna_ghash_lock); 196 spin_unlock_bh(&bat_priv->tt_ghash_lock);
196} 197}
197 198
198int hna_local_fill_buffer(struct bat_priv *bat_priv, 199int tt_local_fill_buffer(struct bat_priv *bat_priv,
199 unsigned char *buff, int buff_len) 200 unsigned char *buff, int buff_len)
200{ 201{
201 struct hashtable_t *hash = bat_priv->hna_local_hash; 202 struct hashtable_t *hash = bat_priv->tt_local_hash;
202 struct hna_local_entry *hna_local_entry; 203 struct tt_local_entry *tt_local_entry;
203 struct hlist_node *node; 204 struct hlist_node *node;
204 struct hlist_head *head; 205 struct hlist_head *head;
205 int i, count = 0; 206 int i, count = 0;
206 207
207 spin_lock_bh(&bat_priv->hna_lhash_lock); 208 spin_lock_bh(&bat_priv->tt_lhash_lock);
208 209
209 for (i = 0; i < hash->size; i++) { 210 for (i = 0; i < hash->size; i++) {
210 head = &hash->table[i]; 211 head = &hash->table[i];
211 212
212 rcu_read_lock(); 213 rcu_read_lock();
213 hlist_for_each_entry_rcu(hna_local_entry, node, 214 hlist_for_each_entry_rcu(tt_local_entry, node,
214 head, hash_entry) { 215 head, hash_entry) {
215 if (buff_len < (count + 1) * ETH_ALEN) 216 if (buff_len < (count + 1) * ETH_ALEN)
216 break; 217 break;
217 218
218 memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr, 219 memcpy(buff + (count * ETH_ALEN), tt_local_entry->addr,
219 ETH_ALEN); 220 ETH_ALEN);
220 221
221 count++; 222 count++;
@@ -223,37 +224,47 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv,
223 rcu_read_unlock(); 224 rcu_read_unlock();
224 } 225 }
225 226
226 /* if we did not get all new local hnas see you next time ;-) */ 227 /* if we did not get all new local tts see you next time ;-) */
227 if (count == bat_priv->num_local_hna) 228 if (count == bat_priv->num_local_tt)
228 atomic_set(&bat_priv->hna_local_changed, 0); 229 atomic_set(&bat_priv->tt_local_changed, 0);
229 230
230 spin_unlock_bh(&bat_priv->hna_lhash_lock); 231 spin_unlock_bh(&bat_priv->tt_lhash_lock);
231 return count; 232 return count;
232} 233}
233 234
234int hna_local_seq_print_text(struct seq_file *seq, void *offset) 235int tt_local_seq_print_text(struct seq_file *seq, void *offset)
235{ 236{
236 struct net_device *net_dev = (struct net_device *)seq->private; 237 struct net_device *net_dev = (struct net_device *)seq->private;
237 struct bat_priv *bat_priv = netdev_priv(net_dev); 238 struct bat_priv *bat_priv = netdev_priv(net_dev);
238 struct hashtable_t *hash = bat_priv->hna_local_hash; 239 struct hashtable_t *hash = bat_priv->tt_local_hash;
239 struct hna_local_entry *hna_local_entry; 240 struct tt_local_entry *tt_local_entry;
241 struct hard_iface *primary_if;
240 struct hlist_node *node; 242 struct hlist_node *node;
241 struct hlist_head *head; 243 struct hlist_head *head;
242 size_t buf_size, pos; 244 size_t buf_size, pos;
243 char *buff; 245 char *buff;
244 int i; 246 int i, ret = 0;
245 247
246 if (!bat_priv->primary_if) { 248 primary_if = primary_if_get_selected(bat_priv);
247 return seq_printf(seq, "BATMAN mesh %s disabled - " 249 if (!primary_if) {
248 "please specify interfaces to enable it\n", 250 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
249 net_dev->name); 251 "please specify interfaces to enable it\n",
252 net_dev->name);
253 goto out;
254 }
255
256 if (primary_if->if_status != IF_ACTIVE) {
257 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
258 "primary interface not active\n",
259 net_dev->name);
260 goto out;
250 } 261 }
251 262
252 seq_printf(seq, "Locally retrieved addresses (from %s) " 263 seq_printf(seq, "Locally retrieved addresses (from %s) "
253 "announced via HNA:\n", 264 "announced via TT:\n",
254 net_dev->name); 265 net_dev->name);
255 266
256 spin_lock_bh(&bat_priv->hna_lhash_lock); 267 spin_lock_bh(&bat_priv->tt_lhash_lock);
257 268
258 buf_size = 1; 269 buf_size = 1;
259 /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ 270 /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
@@ -268,8 +279,9 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
268 279
269 buff = kmalloc(buf_size, GFP_ATOMIC); 280 buff = kmalloc(buf_size, GFP_ATOMIC);
270 if (!buff) { 281 if (!buff) {
271 spin_unlock_bh(&bat_priv->hna_lhash_lock); 282 spin_unlock_bh(&bat_priv->tt_lhash_lock);
272 return -ENOMEM; 283 ret = -ENOMEM;
284 goto out;
273 } 285 }
274 286
275 buff[0] = '\0'; 287 buff[0] = '\0';
@@ -279,211 +291,225 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
279 head = &hash->table[i]; 291 head = &hash->table[i];
280 292
281 rcu_read_lock(); 293 rcu_read_lock();
282 hlist_for_each_entry_rcu(hna_local_entry, node, 294 hlist_for_each_entry_rcu(tt_local_entry, node,
283 head, hash_entry) { 295 head, hash_entry) {
284 pos += snprintf(buff + pos, 22, " * %pM\n", 296 pos += snprintf(buff + pos, 22, " * %pM\n",
285 hna_local_entry->addr); 297 tt_local_entry->addr);
286 } 298 }
287 rcu_read_unlock(); 299 rcu_read_unlock();
288 } 300 }
289 301
290 spin_unlock_bh(&bat_priv->hna_lhash_lock); 302 spin_unlock_bh(&bat_priv->tt_lhash_lock);
291 303
292 seq_printf(seq, "%s", buff); 304 seq_printf(seq, "%s", buff);
293 kfree(buff); 305 kfree(buff);
294 return 0; 306out:
307 if (primary_if)
308 hardif_free_ref(primary_if);
309 return ret;
295} 310}
296 311
297static void _hna_local_del(struct hlist_node *node, void *arg) 312static void _tt_local_del(struct hlist_node *node, void *arg)
298{ 313{
299 struct bat_priv *bat_priv = (struct bat_priv *)arg; 314 struct bat_priv *bat_priv = (struct bat_priv *)arg;
300 void *data = container_of(node, struct hna_local_entry, hash_entry); 315 void *data = container_of(node, struct tt_local_entry, hash_entry);
301 316
302 kfree(data); 317 kfree(data);
303 bat_priv->num_local_hna--; 318 bat_priv->num_local_tt--;
304 atomic_set(&bat_priv->hna_local_changed, 1); 319 atomic_set(&bat_priv->tt_local_changed, 1);
305} 320}
306 321
307static void hna_local_del(struct bat_priv *bat_priv, 322static void tt_local_del(struct bat_priv *bat_priv,
308 struct hna_local_entry *hna_local_entry, 323 struct tt_local_entry *tt_local_entry,
309 char *message) 324 char *message)
310{ 325{
311 bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", 326 bat_dbg(DBG_ROUTES, bat_priv, "Deleting local tt entry (%pM): %s\n",
312 hna_local_entry->addr, message); 327 tt_local_entry->addr, message);
313 328
314 hash_remove(bat_priv->hna_local_hash, compare_lhna, choose_orig, 329 hash_remove(bat_priv->tt_local_hash, compare_ltt, choose_orig,
315 hna_local_entry->addr); 330 tt_local_entry->addr);
316 _hna_local_del(&hna_local_entry->hash_entry, bat_priv); 331 _tt_local_del(&tt_local_entry->hash_entry, bat_priv);
317} 332}
318 333
319void hna_local_remove(struct bat_priv *bat_priv, 334void tt_local_remove(struct bat_priv *bat_priv,
320 uint8_t *addr, char *message) 335 uint8_t *addr, char *message)
321{ 336{
322 struct hna_local_entry *hna_local_entry; 337 struct tt_local_entry *tt_local_entry;
323 338
324 spin_lock_bh(&bat_priv->hna_lhash_lock); 339 spin_lock_bh(&bat_priv->tt_lhash_lock);
325 340
326 hna_local_entry = hna_local_hash_find(bat_priv, addr); 341 tt_local_entry = tt_local_hash_find(bat_priv, addr);
327 342
328 if (hna_local_entry) 343 if (tt_local_entry)
329 hna_local_del(bat_priv, hna_local_entry, message); 344 tt_local_del(bat_priv, tt_local_entry, message);
330 345
331 spin_unlock_bh(&bat_priv->hna_lhash_lock); 346 spin_unlock_bh(&bat_priv->tt_lhash_lock);
332} 347}
333 348
334static void hna_local_purge(struct work_struct *work) 349static void tt_local_purge(struct work_struct *work)
335{ 350{
336 struct delayed_work *delayed_work = 351 struct delayed_work *delayed_work =
337 container_of(work, struct delayed_work, work); 352 container_of(work, struct delayed_work, work);
338 struct bat_priv *bat_priv = 353 struct bat_priv *bat_priv =
339 container_of(delayed_work, struct bat_priv, hna_work); 354 container_of(delayed_work, struct bat_priv, tt_work);
340 struct hashtable_t *hash = bat_priv->hna_local_hash; 355 struct hashtable_t *hash = bat_priv->tt_local_hash;
341 struct hna_local_entry *hna_local_entry; 356 struct tt_local_entry *tt_local_entry;
342 struct hlist_node *node, *node_tmp; 357 struct hlist_node *node, *node_tmp;
343 struct hlist_head *head; 358 struct hlist_head *head;
344 unsigned long timeout; 359 unsigned long timeout;
345 int i; 360 int i;
346 361
347 spin_lock_bh(&bat_priv->hna_lhash_lock); 362 spin_lock_bh(&bat_priv->tt_lhash_lock);
348 363
349 for (i = 0; i < hash->size; i++) { 364 for (i = 0; i < hash->size; i++) {
350 head = &hash->table[i]; 365 head = &hash->table[i];
351 366
352 hlist_for_each_entry_safe(hna_local_entry, node, node_tmp, 367 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
353 head, hash_entry) { 368 head, hash_entry) {
354 if (hna_local_entry->never_purge) 369 if (tt_local_entry->never_purge)
355 continue; 370 continue;
356 371
357 timeout = hna_local_entry->last_seen; 372 timeout = tt_local_entry->last_seen;
358 timeout += LOCAL_HNA_TIMEOUT * HZ; 373 timeout += TT_LOCAL_TIMEOUT * HZ;
359 374
360 if (time_before(jiffies, timeout)) 375 if (time_before(jiffies, timeout))
361 continue; 376 continue;
362 377
363 hna_local_del(bat_priv, hna_local_entry, 378 tt_local_del(bat_priv, tt_local_entry,
364 "address timed out"); 379 "address timed out");
365 } 380 }
366 } 381 }
367 382
368 spin_unlock_bh(&bat_priv->hna_lhash_lock); 383 spin_unlock_bh(&bat_priv->tt_lhash_lock);
369 hna_local_start_timer(bat_priv); 384 tt_local_start_timer(bat_priv);
370} 385}
371 386
372void hna_local_free(struct bat_priv *bat_priv) 387void tt_local_free(struct bat_priv *bat_priv)
373{ 388{
374 if (!bat_priv->hna_local_hash) 389 if (!bat_priv->tt_local_hash)
375 return; 390 return;
376 391
377 cancel_delayed_work_sync(&bat_priv->hna_work); 392 cancel_delayed_work_sync(&bat_priv->tt_work);
378 hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); 393 hash_delete(bat_priv->tt_local_hash, _tt_local_del, bat_priv);
379 bat_priv->hna_local_hash = NULL; 394 bat_priv->tt_local_hash = NULL;
380} 395}
381 396
382int hna_global_init(struct bat_priv *bat_priv) 397int tt_global_init(struct bat_priv *bat_priv)
383{ 398{
384 if (bat_priv->hna_global_hash) 399 if (bat_priv->tt_global_hash)
385 return 1; 400 return 1;
386 401
387 bat_priv->hna_global_hash = hash_new(1024); 402 bat_priv->tt_global_hash = hash_new(1024);
388 403
389 if (!bat_priv->hna_global_hash) 404 if (!bat_priv->tt_global_hash)
390 return 0; 405 return 0;
391 406
392 return 1; 407 return 1;
393} 408}
394 409
395void hna_global_add_orig(struct bat_priv *bat_priv, 410void tt_global_add_orig(struct bat_priv *bat_priv,
396 struct orig_node *orig_node, 411 struct orig_node *orig_node,
397 unsigned char *hna_buff, int hna_buff_len) 412 unsigned char *tt_buff, int tt_buff_len)
398{ 413{
399 struct hna_global_entry *hna_global_entry; 414 struct tt_global_entry *tt_global_entry;
400 struct hna_local_entry *hna_local_entry; 415 struct tt_local_entry *tt_local_entry;
401 int hna_buff_count = 0; 416 int tt_buff_count = 0;
402 unsigned char *hna_ptr; 417 unsigned char *tt_ptr;
403 418
404 while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { 419 while ((tt_buff_count + 1) * ETH_ALEN <= tt_buff_len) {
405 spin_lock_bh(&bat_priv->hna_ghash_lock); 420 spin_lock_bh(&bat_priv->tt_ghash_lock);
406 421
407 hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 422 tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
408 hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr); 423 tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
409 424
410 if (!hna_global_entry) { 425 if (!tt_global_entry) {
411 spin_unlock_bh(&bat_priv->hna_ghash_lock); 426 spin_unlock_bh(&bat_priv->tt_ghash_lock);
412 427
413 hna_global_entry = 428 tt_global_entry =
414 kmalloc(sizeof(struct hna_global_entry), 429 kmalloc(sizeof(struct tt_global_entry),
415 GFP_ATOMIC); 430 GFP_ATOMIC);
416 431
417 if (!hna_global_entry) 432 if (!tt_global_entry)
418 break; 433 break;
419 434
420 memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); 435 memcpy(tt_global_entry->addr, tt_ptr, ETH_ALEN);
421 436
422 bat_dbg(DBG_ROUTES, bat_priv, 437 bat_dbg(DBG_ROUTES, bat_priv,
423 "Creating new global hna entry: " 438 "Creating new global tt entry: "
424 "%pM (via %pM)\n", 439 "%pM (via %pM)\n",
425 hna_global_entry->addr, orig_node->orig); 440 tt_global_entry->addr, orig_node->orig);
426 441
427 spin_lock_bh(&bat_priv->hna_ghash_lock); 442 spin_lock_bh(&bat_priv->tt_ghash_lock);
428 hash_add(bat_priv->hna_global_hash, compare_ghna, 443 hash_add(bat_priv->tt_global_hash, compare_gtt,
429 choose_orig, hna_global_entry, 444 choose_orig, tt_global_entry,
430 &hna_global_entry->hash_entry); 445 &tt_global_entry->hash_entry);
431 446
432 } 447 }
433 448
434 hna_global_entry->orig_node = orig_node; 449 tt_global_entry->orig_node = orig_node;
435 spin_unlock_bh(&bat_priv->hna_ghash_lock); 450 spin_unlock_bh(&bat_priv->tt_ghash_lock);
436 451
437 /* remove address from local hash if present */ 452 /* remove address from local hash if present */
438 spin_lock_bh(&bat_priv->hna_lhash_lock); 453 spin_lock_bh(&bat_priv->tt_lhash_lock);
439 454
440 hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 455 tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
441 hna_local_entry = hna_local_hash_find(bat_priv, hna_ptr); 456 tt_local_entry = tt_local_hash_find(bat_priv, tt_ptr);
442 457
443 if (hna_local_entry) 458 if (tt_local_entry)
444 hna_local_del(bat_priv, hna_local_entry, 459 tt_local_del(bat_priv, tt_local_entry,
445 "global hna received"); 460 "global tt received");
446 461
447 spin_unlock_bh(&bat_priv->hna_lhash_lock); 462 spin_unlock_bh(&bat_priv->tt_lhash_lock);
448 463
449 hna_buff_count++; 464 tt_buff_count++;
450 } 465 }
451 466
452 /* initialize, and overwrite if malloc succeeds */ 467 /* initialize, and overwrite if malloc succeeds */
453 orig_node->hna_buff = NULL; 468 orig_node->tt_buff = NULL;
454 orig_node->hna_buff_len = 0; 469 orig_node->tt_buff_len = 0;
455 470
456 if (hna_buff_len > 0) { 471 if (tt_buff_len > 0) {
457 orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); 472 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
458 if (orig_node->hna_buff) { 473 if (orig_node->tt_buff) {
459 memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); 474 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
460 orig_node->hna_buff_len = hna_buff_len; 475 orig_node->tt_buff_len = tt_buff_len;
461 } 476 }
462 } 477 }
463} 478}
464 479
465int hna_global_seq_print_text(struct seq_file *seq, void *offset) 480int tt_global_seq_print_text(struct seq_file *seq, void *offset)
466{ 481{
467 struct net_device *net_dev = (struct net_device *)seq->private; 482 struct net_device *net_dev = (struct net_device *)seq->private;
468 struct bat_priv *bat_priv = netdev_priv(net_dev); 483 struct bat_priv *bat_priv = netdev_priv(net_dev);
469 struct hashtable_t *hash = bat_priv->hna_global_hash; 484 struct hashtable_t *hash = bat_priv->tt_global_hash;
470 struct hna_global_entry *hna_global_entry; 485 struct tt_global_entry *tt_global_entry;
486 struct hard_iface *primary_if;
471 struct hlist_node *node; 487 struct hlist_node *node;
472 struct hlist_head *head; 488 struct hlist_head *head;
473 size_t buf_size, pos; 489 size_t buf_size, pos;
474 char *buff; 490 char *buff;
475 int i; 491 int i, ret = 0;
476 492
477 if (!bat_priv->primary_if) { 493 primary_if = primary_if_get_selected(bat_priv);
478 return seq_printf(seq, "BATMAN mesh %s disabled - " 494 if (!primary_if) {
479 "please specify interfaces to enable it\n", 495 ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
480 net_dev->name); 496 "specify interfaces to enable it\n",
497 net_dev->name);
498 goto out;
481 } 499 }
482 500
483 seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", 501 if (primary_if->if_status != IF_ACTIVE) {
502 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
503 "primary interface not active\n",
504 net_dev->name);
505 goto out;
506 }
507
508 seq_printf(seq,
509 "Globally announced TT entries received via the mesh %s\n",
484 net_dev->name); 510 net_dev->name);
485 511
486 spin_lock_bh(&bat_priv->hna_ghash_lock); 512 spin_lock_bh(&bat_priv->tt_ghash_lock);
487 513
488 buf_size = 1; 514 buf_size = 1;
489 /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ 515 /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
@@ -498,8 +524,9 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
498 524
499 buff = kmalloc(buf_size, GFP_ATOMIC); 525 buff = kmalloc(buf_size, GFP_ATOMIC);
500 if (!buff) { 526 if (!buff) {
501 spin_unlock_bh(&bat_priv->hna_ghash_lock); 527 spin_unlock_bh(&bat_priv->tt_ghash_lock);
502 return -ENOMEM; 528 ret = -ENOMEM;
529 goto out;
503 } 530 }
504 buff[0] = '\0'; 531 buff[0] = '\0';
505 pos = 0; 532 pos = 0;
@@ -508,101 +535,104 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
508 head = &hash->table[i]; 535 head = &hash->table[i];
509 536
510 rcu_read_lock(); 537 rcu_read_lock();
511 hlist_for_each_entry_rcu(hna_global_entry, node, 538 hlist_for_each_entry_rcu(tt_global_entry, node,
512 head, hash_entry) { 539 head, hash_entry) {
513 pos += snprintf(buff + pos, 44, 540 pos += snprintf(buff + pos, 44,
514 " * %pM via %pM\n", 541 " * %pM via %pM\n",
515 hna_global_entry->addr, 542 tt_global_entry->addr,
516 hna_global_entry->orig_node->orig); 543 tt_global_entry->orig_node->orig);
517 } 544 }
518 rcu_read_unlock(); 545 rcu_read_unlock();
519 } 546 }
520 547
521 spin_unlock_bh(&bat_priv->hna_ghash_lock); 548 spin_unlock_bh(&bat_priv->tt_ghash_lock);
522 549
523 seq_printf(seq, "%s", buff); 550 seq_printf(seq, "%s", buff);
524 kfree(buff); 551 kfree(buff);
525 return 0; 552out:
553 if (primary_if)
554 hardif_free_ref(primary_if);
555 return ret;
526} 556}
527 557
528static void _hna_global_del_orig(struct bat_priv *bat_priv, 558static void _tt_global_del_orig(struct bat_priv *bat_priv,
529 struct hna_global_entry *hna_global_entry, 559 struct tt_global_entry *tt_global_entry,
530 char *message) 560 char *message)
531{ 561{
532 bat_dbg(DBG_ROUTES, bat_priv, 562 bat_dbg(DBG_ROUTES, bat_priv,
533 "Deleting global hna entry %pM (via %pM): %s\n", 563 "Deleting global tt entry %pM (via %pM): %s\n",
534 hna_global_entry->addr, hna_global_entry->orig_node->orig, 564 tt_global_entry->addr, tt_global_entry->orig_node->orig,
535 message); 565 message);
536 566
537 hash_remove(bat_priv->hna_global_hash, compare_ghna, choose_orig, 567 hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
538 hna_global_entry->addr); 568 tt_global_entry->addr);
539 kfree(hna_global_entry); 569 kfree(tt_global_entry);
540} 570}
541 571
542void hna_global_del_orig(struct bat_priv *bat_priv, 572void tt_global_del_orig(struct bat_priv *bat_priv,
543 struct orig_node *orig_node, char *message) 573 struct orig_node *orig_node, char *message)
544{ 574{
545 struct hna_global_entry *hna_global_entry; 575 struct tt_global_entry *tt_global_entry;
546 int hna_buff_count = 0; 576 int tt_buff_count = 0;
547 unsigned char *hna_ptr; 577 unsigned char *tt_ptr;
548 578
549 if (orig_node->hna_buff_len == 0) 579 if (orig_node->tt_buff_len == 0)
550 return; 580 return;
551 581
552 spin_lock_bh(&bat_priv->hna_ghash_lock); 582 spin_lock_bh(&bat_priv->tt_ghash_lock);
553 583
554 while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { 584 while ((tt_buff_count + 1) * ETH_ALEN <= orig_node->tt_buff_len) {
555 hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); 585 tt_ptr = orig_node->tt_buff + (tt_buff_count * ETH_ALEN);
556 hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr); 586 tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
557 587
558 if ((hna_global_entry) && 588 if ((tt_global_entry) &&
559 (hna_global_entry->orig_node == orig_node)) 589 (tt_global_entry->orig_node == orig_node))
560 _hna_global_del_orig(bat_priv, hna_global_entry, 590 _tt_global_del_orig(bat_priv, tt_global_entry,
561 message); 591 message);
562 592
563 hna_buff_count++; 593 tt_buff_count++;
564 } 594 }
565 595
566 spin_unlock_bh(&bat_priv->hna_ghash_lock); 596 spin_unlock_bh(&bat_priv->tt_ghash_lock);
567 597
568 orig_node->hna_buff_len = 0; 598 orig_node->tt_buff_len = 0;
569 kfree(orig_node->hna_buff); 599 kfree(orig_node->tt_buff);
570 orig_node->hna_buff = NULL; 600 orig_node->tt_buff = NULL;
571} 601}
572 602
573static void hna_global_del(struct hlist_node *node, void *arg) 603static void tt_global_del(struct hlist_node *node, void *arg)
574{ 604{
575 void *data = container_of(node, struct hna_global_entry, hash_entry); 605 void *data = container_of(node, struct tt_global_entry, hash_entry);
576 606
577 kfree(data); 607 kfree(data);
578} 608}
579 609
580void hna_global_free(struct bat_priv *bat_priv) 610void tt_global_free(struct bat_priv *bat_priv)
581{ 611{
582 if (!bat_priv->hna_global_hash) 612 if (!bat_priv->tt_global_hash)
583 return; 613 return;
584 614
585 hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); 615 hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
586 bat_priv->hna_global_hash = NULL; 616 bat_priv->tt_global_hash = NULL;
587} 617}
588 618
589struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) 619struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
590{ 620{
591 struct hna_global_entry *hna_global_entry; 621 struct tt_global_entry *tt_global_entry;
592 struct orig_node *orig_node = NULL; 622 struct orig_node *orig_node = NULL;
593 623
594 spin_lock_bh(&bat_priv->hna_ghash_lock); 624 spin_lock_bh(&bat_priv->tt_ghash_lock);
595 hna_global_entry = hna_global_hash_find(bat_priv, addr); 625 tt_global_entry = tt_global_hash_find(bat_priv, addr);
596 626
597 if (!hna_global_entry) 627 if (!tt_global_entry)
598 goto out; 628 goto out;
599 629
600 if (!atomic_inc_not_zero(&hna_global_entry->orig_node->refcount)) 630 if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
601 goto out; 631 goto out;
602 632
603 orig_node = hna_global_entry->orig_node; 633 orig_node = tt_global_entry->orig_node;
604 634
605out: 635out:
606 spin_unlock_bh(&bat_priv->hna_ghash_lock); 636 spin_unlock_bh(&bat_priv->tt_ghash_lock);
607 return orig_node; 637 return orig_node;
608} 638}