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