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