batman-adv: a delayed_work has to be initialised once
[deliverable/linux.git] / net / batman-adv / vis.c
1 /* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors:
2 *
3 * Simon Wunderlich
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20 #include "main.h"
21 #include "send.h"
22 #include "translation-table.h"
23 #include "vis.h"
24 #include "soft-interface.h"
25 #include "hard-interface.h"
26 #include "hash.h"
27 #include "originator.h"
28
29 #define BATADV_MAX_VIS_PACKET_SIZE 1000
30
31 /* hash class keys */
32 static struct lock_class_key batadv_vis_hash_lock_class_key;
33
34 /* free the info */
35 static void batadv_free_info(struct kref *ref)
36 {
37 struct batadv_vis_info *info;
38 struct batadv_priv *bat_priv;
39 struct batadv_recvlist_node *entry, *tmp;
40
41 info = container_of(ref, struct batadv_vis_info, refcount);
42 bat_priv = info->bat_priv;
43
44 list_del_init(&info->send_list);
45 spin_lock_bh(&bat_priv->vis.list_lock);
46 list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
47 list_del(&entry->list);
48 kfree(entry);
49 }
50
51 spin_unlock_bh(&bat_priv->vis.list_lock);
52 kfree_skb(info->skb_packet);
53 kfree(info);
54 }
55
56 /* Compare two vis packets, used by the hashing algorithm */
57 static int batadv_vis_info_cmp(const struct hlist_node *node, const void *data2)
58 {
59 const struct batadv_vis_info *d1, *d2;
60 const struct batadv_vis_packet *p1, *p2;
61
62 d1 = container_of(node, struct batadv_vis_info, hash_entry);
63 d2 = data2;
64 p1 = (struct batadv_vis_packet *)d1->skb_packet->data;
65 p2 = (struct batadv_vis_packet *)d2->skb_packet->data;
66 return batadv_compare_eth(p1->vis_orig, p2->vis_orig);
67 }
68
69 /* hash function to choose an entry in a hash table of given size
70 * hash algorithm from http://en.wikipedia.org/wiki/Hash_table
71 */
72 static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
73 {
74 const struct batadv_vis_info *vis_info = data;
75 const struct batadv_vis_packet *packet;
76 const unsigned char *key;
77 uint32_t hash = 0;
78 size_t i;
79
80 packet = (struct batadv_vis_packet *)vis_info->skb_packet->data;
81 key = packet->vis_orig;
82 for (i = 0; i < ETH_ALEN; i++) {
83 hash += key[i];
84 hash += (hash << 10);
85 hash ^= (hash >> 6);
86 }
87
88 hash += (hash << 3);
89 hash ^= (hash >> 11);
90 hash += (hash << 15);
91
92 return hash % size;
93 }
94
95 static struct batadv_vis_info *
96 batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
97 {
98 struct batadv_hashtable *hash = bat_priv->vis.hash;
99 struct hlist_head *head;
100 struct hlist_node *node;
101 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
102 uint32_t index;
103
104 if (!hash)
105 return NULL;
106
107 index = batadv_vis_info_choose(data, hash->size);
108 head = &hash->table[index];
109
110 rcu_read_lock();
111 hlist_for_each_entry_rcu(vis_info, node, head, hash_entry) {
112 if (!batadv_vis_info_cmp(node, data))
113 continue;
114
115 vis_info_tmp = vis_info;
116 break;
117 }
118 rcu_read_unlock();
119
120 return vis_info_tmp;
121 }
122
123 /* insert interface to the list of interfaces of one originator, if it
124 * does not already exist in the list
125 */
126 static void batadv_vis_data_insert_interface(const uint8_t *interface,
127 struct hlist_head *if_list,
128 bool primary)
129 {
130 struct batadv_if_list_entry *entry;
131 struct hlist_node *pos;
132
133 hlist_for_each_entry(entry, pos, if_list, list) {
134 if (batadv_compare_eth(entry->addr, interface))
135 return;
136 }
137
138 /* it's a new address, add it to the list */
139 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
140 if (!entry)
141 return;
142 memcpy(entry->addr, interface, ETH_ALEN);
143 entry->primary = primary;
144 hlist_add_head(&entry->list, if_list);
145 }
146
147 static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
148 const struct hlist_head *if_list)
149 {
150 struct batadv_if_list_entry *entry;
151 struct hlist_node *pos;
152
153 hlist_for_each_entry(entry, pos, if_list, list) {
154 if (entry->primary)
155 seq_printf(seq, "PRIMARY, ");
156 else
157 seq_printf(seq, "SEC %pM, ", entry->addr);
158 }
159 }
160
161 /* read an entry */
162 static ssize_t
163 batadv_vis_data_read_entry(struct seq_file *seq,
164 const struct batadv_vis_info_entry *entry,
165 const uint8_t *src, bool primary)
166 {
167 if (primary && entry->quality == 0)
168 return seq_printf(seq, "TT %pM, ", entry->dest);
169 else if (batadv_compare_eth(entry->src, src))
170 return seq_printf(seq, "TQ %pM %d, ", entry->dest,
171 entry->quality);
172
173 return 0;
174 }
175
176 static void
177 batadv_vis_data_insert_interfaces(struct hlist_head *list,
178 struct batadv_vis_packet *packet,
179 struct batadv_vis_info_entry *entries)
180 {
181 int i;
182
183 for (i = 0; i < packet->entries; i++) {
184 if (entries[i].quality == 0)
185 continue;
186
187 if (batadv_compare_eth(entries[i].src, packet->vis_orig))
188 continue;
189
190 batadv_vis_data_insert_interface(entries[i].src, list, false);
191 }
192 }
193
194 static void batadv_vis_data_read_entries(struct seq_file *seq,
195 struct hlist_head *list,
196 struct batadv_vis_packet *packet,
197 struct batadv_vis_info_entry *entries)
198 {
199 int i;
200 struct batadv_if_list_entry *entry;
201 struct hlist_node *pos;
202
203 hlist_for_each_entry(entry, pos, list, list) {
204 seq_printf(seq, "%pM,", entry->addr);
205
206 for (i = 0; i < packet->entries; i++)
207 batadv_vis_data_read_entry(seq, &entries[i],
208 entry->addr, entry->primary);
209
210 /* add primary/secondary records */
211 if (batadv_compare_eth(entry->addr, packet->vis_orig))
212 batadv_vis_data_read_prim_sec(seq, list);
213
214 seq_printf(seq, "\n");
215 }
216 }
217
218 static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
219 const struct hlist_head *head)
220 {
221 struct hlist_node *node;
222 struct batadv_vis_info *info;
223 struct batadv_vis_packet *packet;
224 uint8_t *entries_pos;
225 struct batadv_vis_info_entry *entries;
226 struct batadv_if_list_entry *entry;
227 struct hlist_node *pos, *n;
228
229 HLIST_HEAD(vis_if_list);
230
231 hlist_for_each_entry_rcu(info, node, head, hash_entry) {
232 packet = (struct batadv_vis_packet *)info->skb_packet->data;
233 entries_pos = (uint8_t *)packet + sizeof(*packet);
234 entries = (struct batadv_vis_info_entry *)entries_pos;
235
236 batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list,
237 true);
238 batadv_vis_data_insert_interfaces(&vis_if_list, packet,
239 entries);
240 batadv_vis_data_read_entries(seq, &vis_if_list, packet,
241 entries);
242
243 hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
244 hlist_del(&entry->list);
245 kfree(entry);
246 }
247 }
248 }
249
250 int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
251 {
252 struct batadv_hard_iface *primary_if;
253 struct hlist_head *head;
254 struct net_device *net_dev = (struct net_device *)seq->private;
255 struct batadv_priv *bat_priv = netdev_priv(net_dev);
256 struct batadv_hashtable *hash = bat_priv->vis.hash;
257 uint32_t i;
258 int ret = 0;
259 int vis_server = atomic_read(&bat_priv->vis_mode);
260
261 primary_if = batadv_primary_if_get_selected(bat_priv);
262 if (!primary_if)
263 goto out;
264
265 if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE)
266 goto out;
267
268 spin_lock_bh(&bat_priv->vis.hash_lock);
269 for (i = 0; i < hash->size; i++) {
270 head = &hash->table[i];
271 batadv_vis_seq_print_text_bucket(seq, head);
272 }
273 spin_unlock_bh(&bat_priv->vis.hash_lock);
274
275 out:
276 if (primary_if)
277 batadv_hardif_free_ref(primary_if);
278 return ret;
279 }
280
281 /* add the info packet to the send list, if it was not
282 * already linked in.
283 */
284 static void batadv_send_list_add(struct batadv_priv *bat_priv,
285 struct batadv_vis_info *info)
286 {
287 if (list_empty(&info->send_list)) {
288 kref_get(&info->refcount);
289 list_add_tail(&info->send_list, &bat_priv->vis.send_list);
290 }
291 }
292
293 /* delete the info packet from the send list, if it was
294 * linked in.
295 */
296 static void batadv_send_list_del(struct batadv_vis_info *info)
297 {
298 if (!list_empty(&info->send_list)) {
299 list_del_init(&info->send_list);
300 kref_put(&info->refcount, batadv_free_info);
301 }
302 }
303
304 /* tries to add one entry to the receive list. */
305 static void batadv_recv_list_add(struct batadv_priv *bat_priv,
306 struct list_head *recv_list, const char *mac)
307 {
308 struct batadv_recvlist_node *entry;
309
310 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
311 if (!entry)
312 return;
313
314 memcpy(entry->mac, mac, ETH_ALEN);
315 spin_lock_bh(&bat_priv->vis.list_lock);
316 list_add_tail(&entry->list, recv_list);
317 spin_unlock_bh(&bat_priv->vis.list_lock);
318 }
319
320 /* returns 1 if this mac is in the recv_list */
321 static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
322 const struct list_head *recv_list,
323 const char *mac)
324 {
325 const struct batadv_recvlist_node *entry;
326
327 spin_lock_bh(&bat_priv->vis.list_lock);
328 list_for_each_entry(entry, recv_list, list) {
329 if (batadv_compare_eth(entry->mac, mac)) {
330 spin_unlock_bh(&bat_priv->vis.list_lock);
331 return 1;
332 }
333 }
334 spin_unlock_bh(&bat_priv->vis.list_lock);
335 return 0;
336 }
337
338 /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
339 * broken.. ). vis hash must be locked outside. is_new is set when the packet
340 * is newer than old entries in the hash.
341 */
342 static struct batadv_vis_info *
343 batadv_add_packet(struct batadv_priv *bat_priv,
344 struct batadv_vis_packet *vis_packet, int vis_info_len,
345 int *is_new, int make_broadcast)
346 {
347 struct batadv_vis_info *info, *old_info;
348 struct batadv_vis_packet *search_packet, *old_packet;
349 struct batadv_vis_info search_elem;
350 struct batadv_vis_packet *packet;
351 struct sk_buff *tmp_skb;
352 int hash_added;
353 size_t len;
354 size_t max_entries;
355
356 *is_new = 0;
357 /* sanity check */
358 if (!bat_priv->vis.hash)
359 return NULL;
360
361 /* see if the packet is already in vis_hash */
362 search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
363 if (!search_elem.skb_packet)
364 return NULL;
365 len = sizeof(*search_packet);
366 tmp_skb = search_elem.skb_packet;
367 search_packet = (struct batadv_vis_packet *)skb_put(tmp_skb, len);
368
369 memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
370 old_info = batadv_vis_hash_find(bat_priv, &search_elem);
371 kfree_skb(search_elem.skb_packet);
372
373 if (old_info) {
374 tmp_skb = old_info->skb_packet;
375 old_packet = (struct batadv_vis_packet *)tmp_skb->data;
376 if (!batadv_seq_after(ntohl(vis_packet->seqno),
377 ntohl(old_packet->seqno))) {
378 if (old_packet->seqno == vis_packet->seqno) {
379 batadv_recv_list_add(bat_priv,
380 &old_info->recv_list,
381 vis_packet->sender_orig);
382 return old_info;
383 } else {
384 /* newer packet is already in hash. */
385 return NULL;
386 }
387 }
388 /* remove old entry */
389 batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp,
390 batadv_vis_info_choose, old_info);
391 batadv_send_list_del(old_info);
392 kref_put(&old_info->refcount, batadv_free_info);
393 }
394
395 info = kmalloc(sizeof(*info), GFP_ATOMIC);
396 if (!info)
397 return NULL;
398
399 len = sizeof(*packet) + vis_info_len;
400 info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
401 if (!info->skb_packet) {
402 kfree(info);
403 return NULL;
404 }
405 skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
406 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
407
408 kref_init(&info->refcount);
409 INIT_LIST_HEAD(&info->send_list);
410 INIT_LIST_HEAD(&info->recv_list);
411 info->first_seen = jiffies;
412 info->bat_priv = bat_priv;
413 memcpy(packet, vis_packet, len);
414
415 /* initialize and add new packet. */
416 *is_new = 1;
417
418 /* Make it a broadcast packet, if required */
419 if (make_broadcast)
420 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
421
422 /* repair if entries is longer than packet. */
423 max_entries = vis_info_len / sizeof(struct batadv_vis_info_entry);
424 if (packet->entries > max_entries)
425 packet->entries = max_entries;
426
427 batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
428
429 /* try to add it */
430 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
431 batadv_vis_info_choose, info,
432 &info->hash_entry);
433 if (hash_added != 0) {
434 /* did not work (for some reason) */
435 kref_put(&info->refcount, batadv_free_info);
436 info = NULL;
437 }
438
439 return info;
440 }
441
442 /* handle the server sync packet, forward if needed. */
443 void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
444 struct batadv_vis_packet *vis_packet,
445 int vis_info_len)
446 {
447 struct batadv_vis_info *info;
448 int is_new, make_broadcast;
449 int vis_server = atomic_read(&bat_priv->vis_mode);
450
451 make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);
452
453 spin_lock_bh(&bat_priv->vis.hash_lock);
454 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
455 &is_new, make_broadcast);
456 if (!info)
457 goto end;
458
459 /* only if we are server ourselves and packet is newer than the one in
460 * hash.
461 */
462 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new)
463 batadv_send_list_add(bat_priv, info);
464 end:
465 spin_unlock_bh(&bat_priv->vis.hash_lock);
466 }
467
468 /* handle an incoming client update packet and schedule forward if needed. */
469 void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
470 struct batadv_vis_packet *vis_packet,
471 int vis_info_len)
472 {
473 struct batadv_vis_info *info;
474 struct batadv_vis_packet *packet;
475 int is_new;
476 int vis_server = atomic_read(&bat_priv->vis_mode);
477 int are_target = 0;
478
479 /* clients shall not broadcast. */
480 if (is_broadcast_ether_addr(vis_packet->target_orig))
481 return;
482
483 /* Are we the target for this VIS packet? */
484 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC &&
485 batadv_is_my_mac(vis_packet->target_orig))
486 are_target = 1;
487
488 spin_lock_bh(&bat_priv->vis.hash_lock);
489 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
490 &is_new, are_target);
491
492 if (!info)
493 goto end;
494 /* note that outdated packets will be dropped at this point. */
495
496 packet = (struct batadv_vis_packet *)info->skb_packet->data;
497
498 /* send only if we're the target server or ... */
499 if (are_target && is_new) {
500 packet->vis_type = BATADV_VIS_TYPE_SERVER_SYNC; /* upgrade! */
501 batadv_send_list_add(bat_priv, info);
502
503 /* ... we're not the recipient (and thus need to forward). */
504 } else if (!batadv_is_my_mac(packet->target_orig)) {
505 batadv_send_list_add(bat_priv, info);
506 }
507
508 end:
509 spin_unlock_bh(&bat_priv->vis.hash_lock);
510 }
511
512 /* Walk the originators and find the VIS server with the best tq. Set the packet
513 * address to its address and return the best_tq.
514 *
515 * Must be called with the originator hash locked
516 */
517 static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
518 struct batadv_vis_info *info)
519 {
520 struct batadv_hashtable *hash = bat_priv->orig_hash;
521 struct batadv_neigh_node *router;
522 struct hlist_node *node;
523 struct hlist_head *head;
524 struct batadv_orig_node *orig_node;
525 struct batadv_vis_packet *packet;
526 int best_tq = -1;
527 uint32_t i;
528
529 packet = (struct batadv_vis_packet *)info->skb_packet->data;
530
531 for (i = 0; i < hash->size; i++) {
532 head = &hash->table[i];
533
534 rcu_read_lock();
535 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
536 router = batadv_orig_node_get_router(orig_node);
537 if (!router)
538 continue;
539
540 if ((orig_node->flags & BATADV_VIS_SERVER) &&
541 (router->tq_avg > best_tq)) {
542 best_tq = router->tq_avg;
543 memcpy(packet->target_orig, orig_node->orig,
544 ETH_ALEN);
545 }
546 batadv_neigh_node_free_ref(router);
547 }
548 rcu_read_unlock();
549 }
550
551 return best_tq;
552 }
553
554 /* Return true if the vis packet is full. */
555 static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
556 {
557 const struct batadv_vis_packet *packet;
558 size_t num;
559
560 packet = (struct batadv_vis_packet *)info->skb_packet->data;
561 num = BATADV_MAX_VIS_PACKET_SIZE / sizeof(struct batadv_vis_info_entry);
562
563 if (num < packet->entries + 1)
564 return true;
565 return false;
566 }
567
568 /* generates a packet of own vis data,
569 * returns 0 on success, -1 if no packet could be generated
570 */
571 static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
572 {
573 struct batadv_hashtable *hash = bat_priv->orig_hash;
574 struct hlist_node *node;
575 struct hlist_head *head;
576 struct batadv_orig_node *orig_node;
577 struct batadv_neigh_node *router;
578 struct batadv_vis_info *info = bat_priv->vis.my_info;
579 struct batadv_vis_packet *packet;
580 struct batadv_vis_info_entry *entry;
581 struct batadv_tt_common_entry *tt_common_entry;
582 uint8_t *packet_pos;
583 int best_tq = -1;
584 uint32_t i;
585
586 info->first_seen = jiffies;
587 packet = (struct batadv_vis_packet *)info->skb_packet->data;
588 packet->vis_type = atomic_read(&bat_priv->vis_mode);
589
590 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
591 packet->header.ttl = BATADV_TTL;
592 packet->seqno = htonl(ntohl(packet->seqno) + 1);
593 packet->entries = 0;
594 packet->reserved = 0;
595 skb_trim(info->skb_packet, sizeof(*packet));
596
597 if (packet->vis_type == BATADV_VIS_TYPE_CLIENT_UPDATE) {
598 best_tq = batadv_find_best_vis_server(bat_priv, info);
599
600 if (best_tq < 0)
601 return best_tq;
602 }
603
604 for (i = 0; i < hash->size; i++) {
605 head = &hash->table[i];
606
607 rcu_read_lock();
608 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
609 router = batadv_orig_node_get_router(orig_node);
610 if (!router)
611 continue;
612
613 if (!batadv_compare_eth(router->addr, orig_node->orig))
614 goto next;
615
616 if (router->if_incoming->if_status != BATADV_IF_ACTIVE)
617 goto next;
618
619 if (router->tq_avg < 1)
620 goto next;
621
622 /* fill one entry into buffer. */
623 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
624 entry = (struct batadv_vis_info_entry *)packet_pos;
625 memcpy(entry->src,
626 router->if_incoming->net_dev->dev_addr,
627 ETH_ALEN);
628 memcpy(entry->dest, orig_node->orig, ETH_ALEN);
629 entry->quality = router->tq_avg;
630 packet->entries++;
631
632 next:
633 batadv_neigh_node_free_ref(router);
634
635 if (batadv_vis_packet_full(info))
636 goto unlock;
637 }
638 rcu_read_unlock();
639 }
640
641 hash = bat_priv->tt.local_hash;
642
643 for (i = 0; i < hash->size; i++) {
644 head = &hash->table[i];
645
646 rcu_read_lock();
647 hlist_for_each_entry_rcu(tt_common_entry, node, head,
648 hash_entry) {
649 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
650 entry = (struct batadv_vis_info_entry *)packet_pos;
651 memset(entry->src, 0, ETH_ALEN);
652 memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN);
653 entry->quality = 0; /* 0 means TT */
654 packet->entries++;
655
656 if (batadv_vis_packet_full(info))
657 goto unlock;
658 }
659 rcu_read_unlock();
660 }
661
662 return 0;
663
664 unlock:
665 rcu_read_unlock();
666 return 0;
667 }
668
669 /* free old vis packets. Must be called with this vis_hash_lock
670 * held
671 */
672 static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
673 {
674 uint32_t i;
675 struct batadv_hashtable *hash = bat_priv->vis.hash;
676 struct hlist_node *node, *node_tmp;
677 struct hlist_head *head;
678 struct batadv_vis_info *info;
679
680 for (i = 0; i < hash->size; i++) {
681 head = &hash->table[i];
682
683 hlist_for_each_entry_safe(info, node, node_tmp,
684 head, hash_entry) {
685 /* never purge own data. */
686 if (info == bat_priv->vis.my_info)
687 continue;
688
689 if (batadv_has_timed_out(info->first_seen,
690 BATADV_VIS_TIMEOUT)) {
691 hlist_del(node);
692 batadv_send_list_del(info);
693 kref_put(&info->refcount, batadv_free_info);
694 }
695 }
696 }
697 }
698
699 static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
700 struct batadv_vis_info *info)
701 {
702 struct batadv_hashtable *hash = bat_priv->orig_hash;
703 struct hlist_node *node;
704 struct hlist_head *head;
705 struct batadv_orig_node *orig_node;
706 struct batadv_vis_packet *packet;
707 struct sk_buff *skb;
708 uint32_t i;
709
710
711 packet = (struct batadv_vis_packet *)info->skb_packet->data;
712
713 /* send to all routers in range. */
714 for (i = 0; i < hash->size; i++) {
715 head = &hash->table[i];
716
717 rcu_read_lock();
718 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
719 /* if it's a vis server and reachable, send it. */
720 if (!(orig_node->flags & BATADV_VIS_SERVER))
721 continue;
722
723 /* don't send it if we already received the packet from
724 * this node.
725 */
726 if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
727 orig_node->orig))
728 continue;
729
730 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
731 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
732 if (!skb)
733 continue;
734
735 if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
736 kfree_skb(skb);
737 }
738 rcu_read_unlock();
739 }
740 }
741
742 static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
743 struct batadv_vis_info *info)
744 {
745 struct batadv_orig_node *orig_node;
746 struct sk_buff *skb;
747 struct batadv_vis_packet *packet;
748
749 packet = (struct batadv_vis_packet *)info->skb_packet->data;
750
751 orig_node = batadv_orig_hash_find(bat_priv, packet->target_orig);
752 if (!orig_node)
753 goto out;
754
755 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
756 if (!skb)
757 goto out;
758
759 if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
760 kfree_skb(skb);
761
762 out:
763 if (orig_node)
764 batadv_orig_node_free_ref(orig_node);
765 }
766
767 /* only send one vis packet. called from batadv_send_vis_packets() */
768 static void batadv_send_vis_packet(struct batadv_priv *bat_priv,
769 struct batadv_vis_info *info)
770 {
771 struct batadv_hard_iface *primary_if;
772 struct batadv_vis_packet *packet;
773
774 primary_if = batadv_primary_if_get_selected(bat_priv);
775 if (!primary_if)
776 goto out;
777
778 packet = (struct batadv_vis_packet *)info->skb_packet->data;
779 if (packet->header.ttl < 2) {
780 pr_debug("Error - can't send vis packet: ttl exceeded\n");
781 goto out;
782 }
783
784 memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
785 packet->header.ttl--;
786
787 if (is_broadcast_ether_addr(packet->target_orig))
788 batadv_broadcast_vis_packet(bat_priv, info);
789 else
790 batadv_unicast_vis_packet(bat_priv, info);
791 packet->header.ttl++; /* restore TTL */
792
793 out:
794 if (primary_if)
795 batadv_hardif_free_ref(primary_if);
796 }
797
798 /* called from timer; send (and maybe generate) vis packet. */
799 static void batadv_send_vis_packets(struct work_struct *work)
800 {
801 struct delayed_work *delayed_work;
802 struct batadv_priv *bat_priv;
803 struct batadv_priv_vis *priv_vis;
804 struct batadv_vis_info *info;
805
806 delayed_work = container_of(work, struct delayed_work, work);
807 priv_vis = container_of(delayed_work, struct batadv_priv_vis, work);
808 bat_priv = container_of(priv_vis, struct batadv_priv, vis);
809 spin_lock_bh(&bat_priv->vis.hash_lock);
810 batadv_purge_vis_packets(bat_priv);
811
812 if (batadv_generate_vis_packet(bat_priv) == 0) {
813 /* schedule if generation was successful */
814 batadv_send_list_add(bat_priv, bat_priv->vis.my_info);
815 }
816
817 while (!list_empty(&bat_priv->vis.send_list)) {
818 info = list_first_entry(&bat_priv->vis.send_list,
819 typeof(*info), send_list);
820
821 kref_get(&info->refcount);
822 spin_unlock_bh(&bat_priv->vis.hash_lock);
823
824 batadv_send_vis_packet(bat_priv, info);
825
826 spin_lock_bh(&bat_priv->vis.hash_lock);
827 batadv_send_list_del(info);
828 kref_put(&info->refcount, batadv_free_info);
829 }
830 spin_unlock_bh(&bat_priv->vis.hash_lock);
831
832 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
833 msecs_to_jiffies(BATADV_VIS_INTERVAL));
834 }
835
836 /* init the vis server. this may only be called when if_list is already
837 * initialized (e.g. bat0 is initialized, interfaces have been added)
838 */
839 int batadv_vis_init(struct batadv_priv *bat_priv)
840 {
841 struct batadv_vis_packet *packet;
842 int hash_added;
843 unsigned int len;
844 unsigned long first_seen;
845 struct sk_buff *tmp_skb;
846
847 if (bat_priv->vis.hash)
848 return 0;
849
850 spin_lock_bh(&bat_priv->vis.hash_lock);
851
852 bat_priv->vis.hash = batadv_hash_new(256);
853 if (!bat_priv->vis.hash) {
854 pr_err("Can't initialize vis_hash\n");
855 goto err;
856 }
857
858 batadv_hash_set_lock_class(bat_priv->vis.hash,
859 &batadv_vis_hash_lock_class_key);
860
861 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
862 if (!bat_priv->vis.my_info)
863 goto err;
864
865 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
866 len += ETH_HLEN + NET_IP_ALIGN;
867 bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
868 if (!bat_priv->vis.my_info->skb_packet)
869 goto free_info;
870
871 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
872 tmp_skb = bat_priv->vis.my_info->skb_packet;
873 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
874
875 /* prefill the vis info */
876 first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL);
877 bat_priv->vis.my_info->first_seen = first_seen;
878 INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list);
879 INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list);
880 kref_init(&bat_priv->vis.my_info->refcount);
881 bat_priv->vis.my_info->bat_priv = bat_priv;
882 packet->header.version = BATADV_COMPAT_VERSION;
883 packet->header.packet_type = BATADV_VIS;
884 packet->header.ttl = BATADV_TTL;
885 packet->seqno = 0;
886 packet->reserved = 0;
887 packet->entries = 0;
888
889 INIT_LIST_HEAD(&bat_priv->vis.send_list);
890
891 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
892 batadv_vis_info_choose,
893 bat_priv->vis.my_info,
894 &bat_priv->vis.my_info->hash_entry);
895 if (hash_added != 0) {
896 pr_err("Can't add own vis packet into hash\n");
897 /* not in hash, need to remove it manually. */
898 kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info);
899 goto err;
900 }
901
902 spin_unlock_bh(&bat_priv->vis.hash_lock);
903
904 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
905 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
906 msecs_to_jiffies(BATADV_VIS_INTERVAL));
907
908 return 0;
909
910 free_info:
911 kfree(bat_priv->vis.my_info);
912 bat_priv->vis.my_info = NULL;
913 err:
914 spin_unlock_bh(&bat_priv->vis.hash_lock);
915 batadv_vis_quit(bat_priv);
916 return -ENOMEM;
917 }
918
919 /* Decrease the reference count on a hash item info */
920 static void batadv_free_info_ref(struct hlist_node *node, void *arg)
921 {
922 struct batadv_vis_info *info;
923
924 info = container_of(node, struct batadv_vis_info, hash_entry);
925 batadv_send_list_del(info);
926 kref_put(&info->refcount, batadv_free_info);
927 }
928
929 /* shutdown vis-server */
930 void batadv_vis_quit(struct batadv_priv *bat_priv)
931 {
932 if (!bat_priv->vis.hash)
933 return;
934
935 cancel_delayed_work_sync(&bat_priv->vis.work);
936
937 spin_lock_bh(&bat_priv->vis.hash_lock);
938 /* properly remove, kill timers ... */
939 batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL);
940 bat_priv->vis.hash = NULL;
941 bat_priv->vis.my_info = NULL;
942 spin_unlock_bh(&bat_priv->vis.hash_lock);
943 }
This page took 0.067181 seconds and 5 git commands to generate.