linux/net/batman-adv/bat_iv_ogm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (C) B.A.T.M.A.N. contributors:
   3 *
   4 * Marek Lindner, Simon Wunderlich
   5 */
   6
   7#include "bat_iv_ogm.h"
   8#include "main.h"
   9
  10#include <linux/atomic.h>
  11#include <linux/bitmap.h>
  12#include <linux/bitops.h>
  13#include <linux/bug.h>
  14#include <linux/byteorder/generic.h>
  15#include <linux/cache.h>
  16#include <linux/errno.h>
  17#include <linux/etherdevice.h>
  18#include <linux/gfp.h>
  19#include <linux/if_ether.h>
  20#include <linux/init.h>
  21#include <linux/jiffies.h>
  22#include <linux/kernel.h>
  23#include <linux/kref.h>
  24#include <linux/list.h>
  25#include <linux/lockdep.h>
  26#include <linux/mutex.h>
  27#include <linux/netdevice.h>
  28#include <linux/netlink.h>
  29#include <linux/pkt_sched.h>
  30#include <linux/prandom.h>
  31#include <linux/printk.h>
  32#include <linux/random.h>
  33#include <linux/rculist.h>
  34#include <linux/rcupdate.h>
  35#include <linux/skbuff.h>
  36#include <linux/slab.h>
  37#include <linux/spinlock.h>
  38#include <linux/stddef.h>
  39#include <linux/string.h>
  40#include <linux/types.h>
  41#include <linux/workqueue.h>
  42#include <net/genetlink.h>
  43#include <net/netlink.h>
  44#include <uapi/linux/batadv_packet.h>
  45#include <uapi/linux/batman_adv.h>
  46
  47#include "bat_algo.h"
  48#include "bitarray.h"
  49#include "gateway_client.h"
  50#include "hard-interface.h"
  51#include "hash.h"
  52#include "log.h"
  53#include "netlink.h"
  54#include "network-coding.h"
  55#include "originator.h"
  56#include "routing.h"
  57#include "send.h"
  58#include "translation-table.h"
  59#include "tvlv.h"
  60
  61static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);
  62
  63/**
  64 * enum batadv_dup_status - duplicate status
  65 */
  66enum batadv_dup_status {
  67        /** @BATADV_NO_DUP: the packet is no duplicate */
  68        BATADV_NO_DUP = 0,
  69
  70        /**
  71         * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for
  72         *  the neighbor)
  73         */
  74        BATADV_ORIG_DUP,
  75
  76        /** @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor */
  77        BATADV_NEIGH_DUP,
  78
  79        /**
  80         * @BATADV_PROTECTED: originator is currently protected (after reboot)
  81         */
  82        BATADV_PROTECTED,
  83};
  84
  85/**
  86 * batadv_ring_buffer_set() - update the ring buffer with the given value
  87 * @lq_recv: pointer to the ring buffer
  88 * @lq_index: index to store the value at
  89 * @value: value to store in the ring buffer
  90 */
  91static void batadv_ring_buffer_set(u8 lq_recv[], u8 *lq_index, u8 value)
  92{
  93        lq_recv[*lq_index] = value;
  94        *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
  95}
  96
  97/**
  98 * batadv_ring_buffer_avg() - compute the average of all non-zero values stored
  99 * in the given ring buffer
 100 * @lq_recv: pointer to the ring buffer
 101 *
 102 * Return: computed average value.
 103 */
 104static u8 batadv_ring_buffer_avg(const u8 lq_recv[])
 105{
 106        const u8 *ptr;
 107        u16 count = 0;
 108        u16 i = 0;
 109        u16 sum = 0;
 110
 111        ptr = lq_recv;
 112
 113        while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
 114                if (*ptr != 0) {
 115                        count++;
 116                        sum += *ptr;
 117                }
 118
 119                i++;
 120                ptr++;
 121        }
 122
 123        if (count == 0)
 124                return 0;
 125
 126        return (u8)(sum / count);
 127}
 128
 129/**
 130 * batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
 131 *  originator
 132 * @bat_priv: the bat priv with all the soft interface information
 133 * @addr: mac address of the originator
 134 *
 135 * Return: the originator object corresponding to the passed mac address or NULL
 136 * on failure.
 137 * If the object does not exist, it is created and initialised.
 138 */
 139static struct batadv_orig_node *
 140batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
 141{
 142        struct batadv_orig_node *orig_node;
 143        int hash_added;
 144
 145        orig_node = batadv_orig_hash_find(bat_priv, addr);
 146        if (orig_node)
 147                return orig_node;
 148
 149        orig_node = batadv_orig_node_new(bat_priv, addr);
 150        if (!orig_node)
 151                return NULL;
 152
 153        spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
 154
 155        kref_get(&orig_node->refcount);
 156        hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
 157                                     batadv_choose_orig, orig_node,
 158                                     &orig_node->hash_entry);
 159        if (hash_added != 0)
 160                goto free_orig_node_hash;
 161
 162        return orig_node;
 163
 164free_orig_node_hash:
 165        /* reference for batadv_hash_add */
 166        batadv_orig_node_put(orig_node);
 167        /* reference from batadv_orig_node_new */
 168        batadv_orig_node_put(orig_node);
 169
 170        return NULL;
 171}
 172
 173static struct batadv_neigh_node *
 174batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
 175                        const u8 *neigh_addr,
 176                        struct batadv_orig_node *orig_node,
 177                        struct batadv_orig_node *orig_neigh)
 178{
 179        struct batadv_neigh_node *neigh_node;
 180
 181        neigh_node = batadv_neigh_node_get_or_create(orig_node,
 182                                                     hard_iface, neigh_addr);
 183        if (!neigh_node)
 184                goto out;
 185
 186        neigh_node->orig_node = orig_neigh;
 187
 188out:
 189        return neigh_node;
 190}
 191
 192static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
 193{
 194        struct batadv_ogm_packet *batadv_ogm_packet;
 195        unsigned char *ogm_buff;
 196        u32 random_seqno;
 197
 198        mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
 199
 200        /* randomize initial seqno to avoid collision */
 201        get_random_bytes(&random_seqno, sizeof(random_seqno));
 202        atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
 203
 204        hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
 205        ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
 206        if (!ogm_buff) {
 207                mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 208                return -ENOMEM;
 209        }
 210
 211        hard_iface->bat_iv.ogm_buff = ogm_buff;
 212
 213        batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
 214        batadv_ogm_packet->packet_type = BATADV_IV_OGM;
 215        batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
 216        batadv_ogm_packet->ttl = 2;
 217        batadv_ogm_packet->flags = BATADV_NO_FLAGS;
 218        batadv_ogm_packet->reserved = 0;
 219        batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
 220
 221        mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 222
 223        return 0;
 224}
 225
 226static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
 227{
 228        mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
 229
 230        kfree(hard_iface->bat_iv.ogm_buff);
 231        hard_iface->bat_iv.ogm_buff = NULL;
 232
 233        mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 234}
 235
 236static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
 237{
 238        struct batadv_ogm_packet *batadv_ogm_packet;
 239        void *ogm_buff;
 240
 241        mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
 242
 243        ogm_buff = hard_iface->bat_iv.ogm_buff;
 244        if (!ogm_buff)
 245                goto unlock;
 246
 247        batadv_ogm_packet = ogm_buff;
 248        ether_addr_copy(batadv_ogm_packet->orig,
 249                        hard_iface->net_dev->dev_addr);
 250        ether_addr_copy(batadv_ogm_packet->prev_sender,
 251                        hard_iface->net_dev->dev_addr);
 252
 253unlock:
 254        mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 255}
 256
 257static void
 258batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
 259{
 260        struct batadv_ogm_packet *batadv_ogm_packet;
 261        void *ogm_buff;
 262
 263        mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
 264
 265        ogm_buff = hard_iface->bat_iv.ogm_buff;
 266        if (!ogm_buff)
 267                goto unlock;
 268
 269        batadv_ogm_packet = ogm_buff;
 270        batadv_ogm_packet->ttl = BATADV_TTL;
 271
 272unlock:
 273        mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 274}
 275
 276/* when do we schedule our own ogm to be sent */
 277static unsigned long
 278batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
 279{
 280        unsigned int msecs;
 281
 282        msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
 283        msecs += prandom_u32_max(2 * BATADV_JITTER);
 284
 285        return jiffies + msecs_to_jiffies(msecs);
 286}
 287
 288/* when do we schedule a ogm packet to be sent */
 289static unsigned long batadv_iv_ogm_fwd_send_time(void)
 290{
 291        return jiffies + msecs_to_jiffies(prandom_u32_max(BATADV_JITTER / 2));
 292}
 293
 294/* apply hop penalty for a normal link */
 295static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
 296{
 297        int hop_penalty = atomic_read(&bat_priv->hop_penalty);
 298        int new_tq;
 299
 300        new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
 301        new_tq /= BATADV_TQ_MAX_VALUE;
 302
 303        return new_tq;
 304}
 305
 306/**
 307 * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
 308 * @buff_pos: current position in the skb
 309 * @packet_len: total length of the skb
 310 * @ogm_packet: potential OGM in buffer
 311 *
 312 * Return: true if there is enough space for another OGM, false otherwise.
 313 */
 314static bool
 315batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
 316                          const struct batadv_ogm_packet *ogm_packet)
 317{
 318        int next_buff_pos = 0;
 319
 320        /* check if there is enough space for the header */
 321        next_buff_pos += buff_pos + sizeof(*ogm_packet);
 322        if (next_buff_pos > packet_len)
 323                return false;
 324
 325        /* check if there is enough space for the optional TVLV */
 326        next_buff_pos += ntohs(ogm_packet->tvlv_len);
 327
 328        return (next_buff_pos <= packet_len) &&
 329               (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
 330}
 331
 332/* send a batman ogm to a given interface */
 333static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
 334                                     struct batadv_hard_iface *hard_iface)
 335{
 336        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 337        const char *fwd_str;
 338        u8 packet_num;
 339        s16 buff_pos;
 340        struct batadv_ogm_packet *batadv_ogm_packet;
 341        struct sk_buff *skb;
 342        u8 *packet_pos;
 343
 344        if (hard_iface->if_status != BATADV_IF_ACTIVE)
 345                return;
 346
 347        packet_num = 0;
 348        buff_pos = 0;
 349        packet_pos = forw_packet->skb->data;
 350        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
 351
 352        /* adjust all flags and log packets */
 353        while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
 354                                         batadv_ogm_packet)) {
 355                /* we might have aggregated direct link packets with an
 356                 * ordinary base packet
 357                 */
 358                if (forw_packet->direct_link_flags & BIT(packet_num) &&
 359                    forw_packet->if_incoming == hard_iface)
 360                        batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
 361                else
 362                        batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
 363
 364                if (packet_num > 0 || !forw_packet->own)
 365                        fwd_str = "Forwarding";
 366                else
 367                        fwd_str = "Sending own";
 368
 369                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 370                           "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
 371                           fwd_str, (packet_num > 0 ? "aggregated " : ""),
 372                           batadv_ogm_packet->orig,
 373                           ntohl(batadv_ogm_packet->seqno),
 374                           batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
 375                           ((batadv_ogm_packet->flags & BATADV_DIRECTLINK) ?
 376                            "on" : "off"),
 377                           hard_iface->net_dev->name,
 378                           hard_iface->net_dev->dev_addr);
 379
 380                buff_pos += BATADV_OGM_HLEN;
 381                buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
 382                packet_num++;
 383                packet_pos = forw_packet->skb->data + buff_pos;
 384                batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
 385        }
 386
 387        /* create clone because function is called more than once */
 388        skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
 389        if (skb) {
 390                batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
 391                batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
 392                                   skb->len + ETH_HLEN);
 393                batadv_send_broadcast_skb(skb, hard_iface);
 394        }
 395}
 396
 397/* send a batman ogm packet */
 398static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
 399{
 400        struct net_device *soft_iface;
 401
 402        if (!forw_packet->if_incoming) {
 403                pr_err("Error - can't forward packet: incoming iface not specified\n");
 404                return;
 405        }
 406
 407        soft_iface = forw_packet->if_incoming->soft_iface;
 408
 409        if (WARN_ON(!forw_packet->if_outgoing))
 410                return;
 411
 412        if (forw_packet->if_outgoing->soft_iface != soft_iface) {
 413                pr_warn("%s: soft interface switch for queued OGM\n", __func__);
 414                return;
 415        }
 416
 417        if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
 418                return;
 419
 420        /* only for one specific outgoing interface */
 421        batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
 422}
 423
 424/**
 425 * batadv_iv_ogm_can_aggregate() - find out if an OGM can be aggregated on an
 426 *  existing forward packet
 427 * @new_bat_ogm_packet: OGM packet to be aggregated
 428 * @bat_priv: the bat priv with all the soft interface information
 429 * @packet_len: (total) length of the OGM
 430 * @send_time: timestamp (jiffies) when the packet is to be sent
 431 * @directlink: true if this is a direct link packet
 432 * @if_incoming: interface where the packet was received
 433 * @if_outgoing: interface for which the retransmission should be considered
 434 * @forw_packet: the forwarded packet which should be checked
 435 *
 436 * Return: true if new_packet can be aggregated with forw_packet
 437 */
 438static bool
 439batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
 440                            struct batadv_priv *bat_priv,
 441                            int packet_len, unsigned long send_time,
 442                            bool directlink,
 443                            const struct batadv_hard_iface *if_incoming,
 444                            const struct batadv_hard_iface *if_outgoing,
 445                            const struct batadv_forw_packet *forw_packet)
 446{
 447        struct batadv_ogm_packet *batadv_ogm_packet;
 448        int aggregated_bytes = forw_packet->packet_len + packet_len;
 449        struct batadv_hard_iface *primary_if = NULL;
 450        bool res = false;
 451        unsigned long aggregation_end_time;
 452
 453        batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
 454        aggregation_end_time = send_time;
 455        aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
 456
 457        /* we can aggregate the current packet to this aggregated packet
 458         * if:
 459         *
 460         * - the send time is within our MAX_AGGREGATION_MS time
 461         * - the resulting packet won't be bigger than
 462         *   MAX_AGGREGATION_BYTES
 463         * otherwise aggregation is not possible
 464         */
 465        if (!time_before(send_time, forw_packet->send_time) ||
 466            !time_after_eq(aggregation_end_time, forw_packet->send_time))
 467                return false;
 468
 469        if (aggregated_bytes > BATADV_MAX_AGGREGATION_BYTES)
 470                return false;
 471
 472        /* packet is not leaving on the same interface. */
 473        if (forw_packet->if_outgoing != if_outgoing)
 474                return false;
 475
 476        /* check aggregation compatibility
 477         * -> direct link packets are broadcasted on
 478         *    their interface only
 479         * -> aggregate packet if the current packet is
 480         *    a "global" packet as well as the base
 481         *    packet
 482         */
 483        primary_if = batadv_primary_if_get_selected(bat_priv);
 484        if (!primary_if)
 485                return false;
 486
 487        /* packets without direct link flag and high TTL
 488         * are flooded through the net
 489         */
 490        if (!directlink &&
 491            !(batadv_ogm_packet->flags & BATADV_DIRECTLINK) &&
 492            batadv_ogm_packet->ttl != 1 &&
 493
 494            /* own packets originating non-primary
 495             * interfaces leave only that interface
 496             */
 497            (!forw_packet->own ||
 498             forw_packet->if_incoming == primary_if)) {
 499                res = true;
 500                goto out;
 501        }
 502
 503        /* if the incoming packet is sent via this one
 504         * interface only - we still can aggregate
 505         */
 506        if (directlink &&
 507            new_bat_ogm_packet->ttl == 1 &&
 508            forw_packet->if_incoming == if_incoming &&
 509
 510            /* packets from direct neighbors or
 511             * own secondary interface packets
 512             * (= secondary interface packets in general)
 513             */
 514            (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
 515             (forw_packet->own &&
 516              forw_packet->if_incoming != primary_if))) {
 517                res = true;
 518                goto out;
 519        }
 520
 521out:
 522        if (primary_if)
 523                batadv_hardif_put(primary_if);
 524        return res;
 525}
 526
 527/**
 528 * batadv_iv_ogm_aggregate_new() - create a new aggregated packet and add this
 529 *  packet to it.
 530 * @packet_buff: pointer to the OGM
 531 * @packet_len: (total) length of the OGM
 532 * @send_time: timestamp (jiffies) when the packet is to be sent
 533 * @direct_link: whether this OGM has direct link status
 534 * @if_incoming: interface where the packet was received
 535 * @if_outgoing: interface for which the retransmission should be considered
 536 * @own_packet: true if it is a self-generated ogm
 537 */
 538static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
 539                                        int packet_len, unsigned long send_time,
 540                                        bool direct_link,
 541                                        struct batadv_hard_iface *if_incoming,
 542                                        struct batadv_hard_iface *if_outgoing,
 543                                        int own_packet)
 544{
 545        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 546        struct batadv_forw_packet *forw_packet_aggr;
 547        struct sk_buff *skb;
 548        unsigned char *skb_buff;
 549        unsigned int skb_size;
 550        atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
 551
 552        if (atomic_read(&bat_priv->aggregated_ogms) &&
 553            packet_len < BATADV_MAX_AGGREGATION_BYTES)
 554                skb_size = BATADV_MAX_AGGREGATION_BYTES;
 555        else
 556                skb_size = packet_len;
 557
 558        skb_size += ETH_HLEN;
 559
 560        skb = netdev_alloc_skb_ip_align(NULL, skb_size);
 561        if (!skb)
 562                return;
 563
 564        forw_packet_aggr = batadv_forw_packet_alloc(if_incoming, if_outgoing,
 565                                                    queue_left, bat_priv, skb);
 566        if (!forw_packet_aggr) {
 567                kfree_skb(skb);
 568                return;
 569        }
 570
 571        forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
 572        skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
 573
 574        skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
 575        forw_packet_aggr->packet_len = packet_len;
 576        memcpy(skb_buff, packet_buff, packet_len);
 577
 578        forw_packet_aggr->own = own_packet;
 579        forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
 580        forw_packet_aggr->send_time = send_time;
 581
 582        /* save packet direct link flag status */
 583        if (direct_link)
 584                forw_packet_aggr->direct_link_flags |= 1;
 585
 586        INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
 587                          batadv_iv_send_outstanding_bat_ogm_packet);
 588
 589        batadv_forw_packet_ogmv1_queue(bat_priv, forw_packet_aggr, send_time);
 590}
 591
 592/* aggregate a new packet into the existing ogm packet */
 593static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
 594                                    const unsigned char *packet_buff,
 595                                    int packet_len, bool direct_link)
 596{
 597        unsigned long new_direct_link_flag;
 598
 599        skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len);
 600        forw_packet_aggr->packet_len += packet_len;
 601        forw_packet_aggr->num_packets++;
 602
 603        /* save packet direct link flag status */
 604        if (direct_link) {
 605                new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
 606                forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
 607        }
 608}
 609
 610/**
 611 * batadv_iv_ogm_queue_add() - queue up an OGM for transmission
 612 * @bat_priv: the bat priv with all the soft interface information
 613 * @packet_buff: pointer to the OGM
 614 * @packet_len: (total) length of the OGM
 615 * @if_incoming: interface where the packet was received
 616 * @if_outgoing: interface for which the retransmission should be considered
 617 * @own_packet: true if it is a self-generated ogm
 618 * @send_time: timestamp (jiffies) when the packet is to be sent
 619 */
 620static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
 621                                    unsigned char *packet_buff,
 622                                    int packet_len,
 623                                    struct batadv_hard_iface *if_incoming,
 624                                    struct batadv_hard_iface *if_outgoing,
 625                                    int own_packet, unsigned long send_time)
 626{
 627        /* _aggr -> pointer to the packet we want to aggregate with
 628         * _pos -> pointer to the position in the queue
 629         */
 630        struct batadv_forw_packet *forw_packet_aggr = NULL;
 631        struct batadv_forw_packet *forw_packet_pos = NULL;
 632        struct batadv_ogm_packet *batadv_ogm_packet;
 633        bool direct_link;
 634        unsigned long max_aggregation_jiffies;
 635
 636        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
 637        direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
 638        max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
 639
 640        /* find position for the packet in the forward queue */
 641        spin_lock_bh(&bat_priv->forw_bat_list_lock);
 642        /* own packets are not to be aggregated */
 643        if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
 644                hlist_for_each_entry(forw_packet_pos,
 645                                     &bat_priv->forw_bat_list, list) {
 646                        if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
 647                                                        bat_priv, packet_len,
 648                                                        send_time, direct_link,
 649                                                        if_incoming,
 650                                                        if_outgoing,
 651                                                        forw_packet_pos)) {
 652                                forw_packet_aggr = forw_packet_pos;
 653                                break;
 654                        }
 655                }
 656        }
 657
 658        /* nothing to aggregate with - either aggregation disabled or no
 659         * suitable aggregation packet found
 660         */
 661        if (!forw_packet_aggr) {
 662                /* the following section can run without the lock */
 663                spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 664
 665                /* if we could not aggregate this packet with one of the others
 666                 * we hold it back for a while, so that it might be aggregated
 667                 * later on
 668                 */
 669                if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
 670                        send_time += max_aggregation_jiffies;
 671
 672                batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
 673                                            send_time, direct_link,
 674                                            if_incoming, if_outgoing,
 675                                            own_packet);
 676        } else {
 677                batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
 678                                        packet_len, direct_link);
 679                spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 680        }
 681}
 682
 683static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
 684                                  const struct ethhdr *ethhdr,
 685                                  struct batadv_ogm_packet *batadv_ogm_packet,
 686                                  bool is_single_hop_neigh,
 687                                  bool is_from_best_next_hop,
 688                                  struct batadv_hard_iface *if_incoming,
 689                                  struct batadv_hard_iface *if_outgoing)
 690{
 691        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 692        u16 tvlv_len;
 693
 694        if (batadv_ogm_packet->ttl <= 1) {
 695                batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
 696                return;
 697        }
 698
 699        if (!is_from_best_next_hop) {
 700                /* Mark the forwarded packet when it is not coming from our
 701                 * best next hop. We still need to forward the packet for our
 702                 * neighbor link quality detection to work in case the packet
 703                 * originated from a single hop neighbor. Otherwise we can
 704                 * simply drop the ogm.
 705                 */
 706                if (is_single_hop_neigh)
 707                        batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
 708                else
 709                        return;
 710        }
 711
 712        tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
 713
 714        batadv_ogm_packet->ttl--;
 715        ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
 716
 717        /* apply hop penalty */
 718        batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
 719                                                   bat_priv);
 720
 721        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 722                   "Forwarding packet: tq: %i, ttl: %i\n",
 723                   batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
 724
 725        if (is_single_hop_neigh)
 726                batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
 727        else
 728                batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
 729
 730        batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
 731                                BATADV_OGM_HLEN + tvlv_len,
 732                                if_incoming, if_outgoing, 0,
 733                                batadv_iv_ogm_fwd_send_time());
 734}
 735
 736/**
 737 * batadv_iv_ogm_slide_own_bcast_window() - bitshift own OGM broadcast windows
 738 *  for the given interface
 739 * @hard_iface: the interface for which the windows have to be shifted
 740 */
 741static void
 742batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
 743{
 744        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 745        struct batadv_hashtable *hash = bat_priv->orig_hash;
 746        struct hlist_head *head;
 747        struct batadv_orig_node *orig_node;
 748        struct batadv_orig_ifinfo *orig_ifinfo;
 749        unsigned long *word;
 750        u32 i;
 751        u8 *w;
 752
 753        for (i = 0; i < hash->size; i++) {
 754                head = &hash->table[i];
 755
 756                rcu_read_lock();
 757                hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
 758                        hlist_for_each_entry_rcu(orig_ifinfo,
 759                                                 &orig_node->ifinfo_list,
 760                                                 list) {
 761                                if (orig_ifinfo->if_outgoing != hard_iface)
 762                                        continue;
 763
 764                                spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
 765                                word = orig_ifinfo->bat_iv.bcast_own;
 766                                batadv_bit_get_packet(bat_priv, word, 1, 0);
 767                                w = &orig_ifinfo->bat_iv.bcast_own_sum;
 768                                *w = bitmap_weight(word,
 769                                                   BATADV_TQ_LOCAL_WINDOW_SIZE);
 770                                spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
 771                        }
 772                }
 773                rcu_read_unlock();
 774        }
 775}
 776
 777/**
 778 * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
 779 * @hard_iface: interface whose ogm buffer should be transmitted
 780 */
 781static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
 782{
 783        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 784        unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
 785        struct batadv_ogm_packet *batadv_ogm_packet;
 786        struct batadv_hard_iface *primary_if, *tmp_hard_iface;
 787        int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
 788        u32 seqno;
 789        u16 tvlv_len = 0;
 790        unsigned long send_time;
 791
 792        lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
 793
 794        /* interface already disabled by batadv_iv_ogm_iface_disable */
 795        if (!*ogm_buff)
 796                return;
 797
 798        /* the interface gets activated here to avoid race conditions between
 799         * the moment of activating the interface in
 800         * hardif_activate_interface() where the originator mac is set and
 801         * outdated packets (especially uninitialized mac addresses) in the
 802         * packet queue
 803         */
 804        if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
 805                hard_iface->if_status = BATADV_IF_ACTIVE;
 806
 807        primary_if = batadv_primary_if_get_selected(bat_priv);
 808
 809        if (hard_iface == primary_if) {
 810                /* tt changes have to be committed before the tvlv data is
 811                 * appended as it may alter the tt tvlv container
 812                 */
 813                batadv_tt_local_commit_changes(bat_priv);
 814                tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
 815                                                            ogm_buff_len,
 816                                                            BATADV_OGM_HLEN);
 817        }
 818
 819        batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
 820        batadv_ogm_packet->tvlv_len = htons(tvlv_len);
 821
 822        /* change sequence number to network order */
 823        seqno = (u32)atomic_read(&hard_iface->bat_iv.ogm_seqno);
 824        batadv_ogm_packet->seqno = htonl(seqno);
 825        atomic_inc(&hard_iface->bat_iv.ogm_seqno);
 826
 827        batadv_iv_ogm_slide_own_bcast_window(hard_iface);
 828
 829        send_time = batadv_iv_ogm_emit_send_time(bat_priv);
 830
 831        if (hard_iface != primary_if) {
 832                /* OGMs from secondary interfaces are only scheduled on their
 833                 * respective interfaces.
 834                 */
 835                batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
 836                                        hard_iface, hard_iface, 1, send_time);
 837                goto out;
 838        }
 839
 840        /* OGMs from primary interfaces are scheduled on all
 841         * interfaces.
 842         */
 843        rcu_read_lock();
 844        list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
 845                if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
 846                        continue;
 847
 848                if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
 849                        continue;
 850
 851                batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
 852                                        *ogm_buff_len, hard_iface,
 853                                        tmp_hard_iface, 1, send_time);
 854
 855                batadv_hardif_put(tmp_hard_iface);
 856        }
 857        rcu_read_unlock();
 858
 859out:
 860        if (primary_if)
 861                batadv_hardif_put(primary_if);
 862}
 863
 864static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
 865{
 866        if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
 867            hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
 868                return;
 869
 870        mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
 871        batadv_iv_ogm_schedule_buff(hard_iface);
 872        mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
 873}
 874
 875/**
 876 * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over interface
 877 * @orig_node: originator which reproadcasted the OGMs directly
 878 * @if_outgoing: interface which transmitted the original OGM and received the
 879 *  direct rebroadcast
 880 *
 881 * Return: Number of replied (rebroadcasted) OGMs which were transmitted by
 882 *  an originator and directly (without intermediate hop) received by a specific
 883 *  interface
 884 */
 885static u8 batadv_iv_orig_ifinfo_sum(struct batadv_orig_node *orig_node,
 886                                    struct batadv_hard_iface *if_outgoing)
 887{
 888        struct batadv_orig_ifinfo *orig_ifinfo;
 889        u8 sum;
 890
 891        orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
 892        if (!orig_ifinfo)
 893                return 0;
 894
 895        spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
 896        sum = orig_ifinfo->bat_iv.bcast_own_sum;
 897        spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
 898
 899        batadv_orig_ifinfo_put(orig_ifinfo);
 900
 901        return sum;
 902}
 903
 904/**
 905 * batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
 906 *  originator
 907 * @bat_priv: the bat priv with all the soft interface information
 908 * @orig_node: the orig node who originally emitted the ogm packet
 909 * @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
 910 * @ethhdr: Ethernet header of the OGM
 911 * @batadv_ogm_packet: the ogm packet
 912 * @if_incoming: interface where the packet was received
 913 * @if_outgoing: interface for which the retransmission should be considered
 914 * @dup_status: the duplicate status of this ogm packet.
 915 */
 916static void
 917batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
 918                          struct batadv_orig_node *orig_node,
 919                          struct batadv_orig_ifinfo *orig_ifinfo,
 920                          const struct ethhdr *ethhdr,
 921                          const struct batadv_ogm_packet *batadv_ogm_packet,
 922                          struct batadv_hard_iface *if_incoming,
 923                          struct batadv_hard_iface *if_outgoing,
 924                          enum batadv_dup_status dup_status)
 925{
 926        struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
 927        struct batadv_neigh_ifinfo *router_ifinfo = NULL;
 928        struct batadv_neigh_node *neigh_node = NULL;
 929        struct batadv_neigh_node *tmp_neigh_node = NULL;
 930        struct batadv_neigh_node *router = NULL;
 931        u8 sum_orig, sum_neigh;
 932        u8 *neigh_addr;
 933        u8 tq_avg;
 934
 935        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 936                   "%s(): Searching and updating originator entry of received packet\n",
 937                   __func__);
 938
 939        rcu_read_lock();
 940        hlist_for_each_entry_rcu(tmp_neigh_node,
 941                                 &orig_node->neigh_list, list) {
 942                neigh_addr = tmp_neigh_node->addr;
 943                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
 944                    tmp_neigh_node->if_incoming == if_incoming &&
 945                    kref_get_unless_zero(&tmp_neigh_node->refcount)) {
 946                        if (WARN(neigh_node, "too many matching neigh_nodes"))
 947                                batadv_neigh_node_put(neigh_node);
 948                        neigh_node = tmp_neigh_node;
 949                        continue;
 950                }
 951
 952                if (dup_status != BATADV_NO_DUP)
 953                        continue;
 954
 955                /* only update the entry for this outgoing interface */
 956                neigh_ifinfo = batadv_neigh_ifinfo_get(tmp_neigh_node,
 957                                                       if_outgoing);
 958                if (!neigh_ifinfo)
 959                        continue;
 960
 961                spin_lock_bh(&tmp_neigh_node->ifinfo_lock);
 962                batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
 963                                       &neigh_ifinfo->bat_iv.tq_index, 0);
 964                tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
 965                neigh_ifinfo->bat_iv.tq_avg = tq_avg;
 966                spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);
 967
 968                batadv_neigh_ifinfo_put(neigh_ifinfo);
 969                neigh_ifinfo = NULL;
 970        }
 971
 972        if (!neigh_node) {
 973                struct batadv_orig_node *orig_tmp;
 974
 975                orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
 976                if (!orig_tmp)
 977                        goto unlock;
 978
 979                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
 980                                                     ethhdr->h_source,
 981                                                     orig_node, orig_tmp);
 982
 983                batadv_orig_node_put(orig_tmp);
 984                if (!neigh_node)
 985                        goto unlock;
 986        } else {
 987                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 988                           "Updating existing last-hop neighbor of originator\n");
 989        }
 990
 991        rcu_read_unlock();
 992        neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
 993        if (!neigh_ifinfo)
 994                goto out;
 995
 996        neigh_node->last_seen = jiffies;
 997
 998        spin_lock_bh(&neigh_node->ifinfo_lock);
 999        batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
1000                               &neigh_ifinfo->bat_iv.tq_index,
1001                               batadv_ogm_packet->tq);
1002        tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
1003        neigh_ifinfo->bat_iv.tq_avg = tq_avg;
1004        spin_unlock_bh(&neigh_node->ifinfo_lock);
1005
1006        if (dup_status == BATADV_NO_DUP) {
1007                orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1008                neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1009        }
1010
1011        /* if this neighbor already is our next hop there is nothing
1012         * to change
1013         */
1014        router = batadv_orig_router_get(orig_node, if_outgoing);
1015        if (router == neigh_node)
1016                goto out;
1017
1018        if (router) {
1019                router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1020                if (!router_ifinfo)
1021                        goto out;
1022
1023                /* if this neighbor does not offer a better TQ we won't
1024                 * consider it
1025                 */
1026                if (router_ifinfo->bat_iv.tq_avg > neigh_ifinfo->bat_iv.tq_avg)
1027                        goto out;
1028        }
1029
1030        /* if the TQ is the same and the link not more symmetric we
1031         * won't consider it either
1032         */
1033        if (router_ifinfo &&
1034            neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg) {
1035                sum_orig = batadv_iv_orig_ifinfo_sum(router->orig_node,
1036                                                     router->if_incoming);
1037                sum_neigh = batadv_iv_orig_ifinfo_sum(neigh_node->orig_node,
1038                                                      neigh_node->if_incoming);
1039                if (sum_orig >= sum_neigh)
1040                        goto out;
1041        }
1042
1043        batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
1044        goto out;
1045
1046unlock:
1047        rcu_read_unlock();
1048out:
1049        if (neigh_node)
1050                batadv_neigh_node_put(neigh_node);
1051        if (router)
1052                batadv_neigh_node_put(router);
1053        if (neigh_ifinfo)
1054                batadv_neigh_ifinfo_put(neigh_ifinfo);
1055        if (router_ifinfo)
1056                batadv_neigh_ifinfo_put(router_ifinfo);
1057}
1058
1059/**
1060 * batadv_iv_ogm_calc_tq() - calculate tq for current received ogm packet
1061 * @orig_node: the orig node who originally emitted the ogm packet
1062 * @orig_neigh_node: the orig node struct of the neighbor who sent the packet
1063 * @batadv_ogm_packet: the ogm packet
1064 * @if_incoming: interface where the packet was received
1065 * @if_outgoing: interface for which the retransmission should be considered
1066 *
1067 * Return: true if the link can be considered bidirectional, false otherwise
1068 */
1069static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
1070                                  struct batadv_orig_node *orig_neigh_node,
1071                                  struct batadv_ogm_packet *batadv_ogm_packet,
1072                                  struct batadv_hard_iface *if_incoming,
1073                                  struct batadv_hard_iface *if_outgoing)
1074{
1075        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1076        struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
1077        struct batadv_neigh_ifinfo *neigh_ifinfo;
1078        u8 total_count;
1079        u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
1080        unsigned int tq_iface_hop_penalty = BATADV_TQ_MAX_VALUE;
1081        unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1082        unsigned int tq_asym_penalty, inv_asym_penalty;
1083        unsigned int combined_tq;
1084        bool ret = false;
1085
1086        /* find corresponding one hop neighbor */
1087        rcu_read_lock();
1088        hlist_for_each_entry_rcu(tmp_neigh_node,
1089                                 &orig_neigh_node->neigh_list, list) {
1090                if (!batadv_compare_eth(tmp_neigh_node->addr,
1091                                        orig_neigh_node->orig))
1092                        continue;
1093
1094                if (tmp_neigh_node->if_incoming != if_incoming)
1095                        continue;
1096
1097                if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
1098                        continue;
1099
1100                neigh_node = tmp_neigh_node;
1101                break;
1102        }
1103        rcu_read_unlock();
1104
1105        if (!neigh_node)
1106                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
1107                                                     orig_neigh_node->orig,
1108                                                     orig_neigh_node,
1109                                                     orig_neigh_node);
1110
1111        if (!neigh_node)
1112                goto out;
1113
1114        /* if orig_node is direct neighbor update neigh_node last_seen */
1115        if (orig_node == orig_neigh_node)
1116                neigh_node->last_seen = jiffies;
1117
1118        orig_node->last_seen = jiffies;
1119
1120        /* find packet count of corresponding one hop neighbor */
1121        orig_eq_count = batadv_iv_orig_ifinfo_sum(orig_neigh_node, if_incoming);
1122        neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
1123        if (neigh_ifinfo) {
1124                neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count;
1125                batadv_neigh_ifinfo_put(neigh_ifinfo);
1126        } else {
1127                neigh_rq_count = 0;
1128        }
1129
1130        /* pay attention to not get a value bigger than 100 % */
1131        if (orig_eq_count > neigh_rq_count)
1132                total_count = neigh_rq_count;
1133        else
1134                total_count = orig_eq_count;
1135
1136        /* if we have too few packets (too less data) we set tq_own to zero
1137         * if we receive too few packets it is not considered bidirectional
1138         */
1139        if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
1140            neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
1141                tq_own = 0;
1142        else
1143                /* neigh_node->real_packet_count is never zero as we
1144                 * only purge old information when getting new
1145                 * information
1146                 */
1147                tq_own = (BATADV_TQ_MAX_VALUE * total_count) /  neigh_rq_count;
1148
1149        /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
1150         * affect the nearly-symmetric links only a little, but
1151         * punishes asymmetric links more.  This will give a value
1152         * between 0 and TQ_MAX_VALUE
1153         */
1154        neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
1155        neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv;
1156        neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE *
1157                            BATADV_TQ_LOCAL_WINDOW_SIZE *
1158                            BATADV_TQ_LOCAL_WINDOW_SIZE;
1159        inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
1160        inv_asym_penalty /= neigh_rq_max_cube;
1161        tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
1162        tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
1163
1164        /* penalize if the OGM is forwarded on the same interface. WiFi
1165         * interfaces and other half duplex devices suffer from throughput
1166         * drops as they can't send and receive at the same time.
1167         */
1168        if (if_outgoing && if_incoming == if_outgoing &&
1169            batadv_is_wifi_hardif(if_outgoing))
1170                tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty,
1171                                                          bat_priv);
1172
1173        combined_tq = batadv_ogm_packet->tq *
1174                      tq_own *
1175                      tq_asym_penalty *
1176                      tq_iface_hop_penalty;
1177        combined_tq /= BATADV_TQ_MAX_VALUE *
1178                       BATADV_TQ_MAX_VALUE *
1179                       BATADV_TQ_MAX_VALUE;
1180        batadv_ogm_packet->tq = combined_tq;
1181
1182        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1183                   "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_hop_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
1184                   orig_node->orig, orig_neigh_node->orig, total_count,
1185                   neigh_rq_count, tq_own, tq_asym_penalty,
1186                   tq_iface_hop_penalty, batadv_ogm_packet->tq,
1187                   if_incoming->net_dev->name,
1188                   if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
1189
1190        /* if link has the minimum required transmission quality
1191         * consider it bidirectional
1192         */
1193        if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
1194                ret = true;
1195
1196out:
1197        if (neigh_node)
1198                batadv_neigh_node_put(neigh_node);
1199        return ret;
1200}
1201
1202/**
1203 * batadv_iv_ogm_update_seqnos() -  process a batman packet for all interfaces,
1204 *  adjust the sequence number and find out whether it is a duplicate
1205 * @ethhdr: ethernet header of the packet
1206 * @batadv_ogm_packet: OGM packet to be considered
1207 * @if_incoming: interface on which the OGM packet was received
1208 * @if_outgoing: interface for which the retransmission should be considered
1209 *
1210 * Return: duplicate status as enum batadv_dup_status
1211 */
1212static enum batadv_dup_status
1213batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1214                            const struct batadv_ogm_packet *batadv_ogm_packet,
1215                            const struct batadv_hard_iface *if_incoming,
1216                            struct batadv_hard_iface *if_outgoing)
1217{
1218        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1219        struct batadv_orig_node *orig_node;
1220        struct batadv_orig_ifinfo *orig_ifinfo = NULL;
1221        struct batadv_neigh_node *neigh_node;
1222        struct batadv_neigh_ifinfo *neigh_ifinfo;
1223        bool is_dup;
1224        s32 seq_diff;
1225        bool need_update = false;
1226        int set_mark;
1227        enum batadv_dup_status ret = BATADV_NO_DUP;
1228        u32 seqno = ntohl(batadv_ogm_packet->seqno);
1229        u8 *neigh_addr;
1230        u8 packet_count;
1231        unsigned long *bitmap;
1232
1233        orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1234        if (!orig_node)
1235                return BATADV_NO_DUP;
1236
1237        orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1238        if (WARN_ON(!orig_ifinfo)) {
1239                batadv_orig_node_put(orig_node);
1240                return 0;
1241        }
1242
1243        spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1244        seq_diff = seqno - orig_ifinfo->last_real_seqno;
1245
1246        /* signalize caller that the packet is to be dropped. */
1247        if (!hlist_empty(&orig_node->neigh_list) &&
1248            batadv_window_protected(bat_priv, seq_diff,
1249                                    BATADV_TQ_LOCAL_WINDOW_SIZE,
1250                                    &orig_ifinfo->batman_seqno_reset, NULL)) {
1251                ret = BATADV_PROTECTED;
1252                goto out;
1253        }
1254
1255        rcu_read_lock();
1256        hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1257                neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node,
1258                                                       if_outgoing);
1259                if (!neigh_ifinfo)
1260                        continue;
1261
1262                neigh_addr = neigh_node->addr;
1263                is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
1264                                         orig_ifinfo->last_real_seqno,
1265                                         seqno);
1266
1267                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1268                    neigh_node->if_incoming == if_incoming) {
1269                        set_mark = 1;
1270                        if (is_dup)
1271                                ret = BATADV_NEIGH_DUP;
1272                } else {
1273                        set_mark = 0;
1274                        if (is_dup && ret != BATADV_NEIGH_DUP)
1275                                ret = BATADV_ORIG_DUP;
1276                }
1277
1278                /* if the window moved, set the update flag. */
1279                bitmap = neigh_ifinfo->bat_iv.real_bits;
1280                need_update |= batadv_bit_get_packet(bat_priv, bitmap,
1281                                                     seq_diff, set_mark);
1282
1283                packet_count = bitmap_weight(bitmap,
1284                                             BATADV_TQ_LOCAL_WINDOW_SIZE);
1285                neigh_ifinfo->bat_iv.real_packet_count = packet_count;
1286                batadv_neigh_ifinfo_put(neigh_ifinfo);
1287        }
1288        rcu_read_unlock();
1289
1290        if (need_update) {
1291                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1292                           "%s updating last_seqno: old %u, new %u\n",
1293                           if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
1294                           orig_ifinfo->last_real_seqno, seqno);
1295                orig_ifinfo->last_real_seqno = seqno;
1296        }
1297
1298out:
1299        spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1300        batadv_orig_node_put(orig_node);
1301        batadv_orig_ifinfo_put(orig_ifinfo);
1302        return ret;
1303}
1304
1305/**
1306 * batadv_iv_ogm_process_per_outif() - process a batman iv OGM for an outgoing
1307 *  interface
1308 * @skb: the skb containing the OGM
1309 * @ogm_offset: offset from skb->data to start of ogm header
1310 * @orig_node: the (cached) orig node for the originator of this OGM
1311 * @if_incoming: the interface where this packet was received
1312 * @if_outgoing: the interface for which the packet should be considered
1313 */
1314static void
1315batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1316                                struct batadv_orig_node *orig_node,
1317                                struct batadv_hard_iface *if_incoming,
1318                                struct batadv_hard_iface *if_outgoing)
1319{
1320        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1321        struct batadv_hardif_neigh_node *hardif_neigh = NULL;
1322        struct batadv_neigh_node *router = NULL;
1323        struct batadv_neigh_node *router_router = NULL;
1324        struct batadv_orig_node *orig_neigh_node;
1325        struct batadv_orig_ifinfo *orig_ifinfo;
1326        struct batadv_neigh_node *orig_neigh_router = NULL;
1327        struct batadv_neigh_ifinfo *router_ifinfo = NULL;
1328        struct batadv_ogm_packet *ogm_packet;
1329        enum batadv_dup_status dup_status;
1330        bool is_from_best_next_hop = false;
1331        bool is_single_hop_neigh = false;
1332        bool sameseq, similar_ttl;
1333        struct sk_buff *skb_priv;
1334        struct ethhdr *ethhdr;
1335        u8 *prev_sender;
1336        bool is_bidirect;
1337
1338        /* create a private copy of the skb, as some functions change tq value
1339         * and/or flags.
1340         */
1341        skb_priv = skb_copy(skb, GFP_ATOMIC);
1342        if (!skb_priv)
1343                return;
1344
1345        ethhdr = eth_hdr(skb_priv);
1346        ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
1347
1348        dup_status = batadv_iv_ogm_update_seqnos(ethhdr, ogm_packet,
1349                                                 if_incoming, if_outgoing);
1350        if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
1351                is_single_hop_neigh = true;
1352
1353        if (dup_status == BATADV_PROTECTED) {
1354                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1355                           "Drop packet: packet within seqno protection time (sender: %pM)\n",
1356                           ethhdr->h_source);
1357                goto out;
1358        }
1359
1360        if (ogm_packet->tq == 0) {
1361                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1362                           "Drop packet: originator packet with tq equal 0\n");
1363                goto out;
1364        }
1365
1366        if (is_single_hop_neigh) {
1367                hardif_neigh = batadv_hardif_neigh_get(if_incoming,
1368                                                       ethhdr->h_source);
1369                if (hardif_neigh)
1370                        hardif_neigh->last_seen = jiffies;
1371        }
1372
1373        router = batadv_orig_router_get(orig_node, if_outgoing);
1374        if (router) {
1375                router_router = batadv_orig_router_get(router->orig_node,
1376                                                       if_outgoing);
1377                router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1378        }
1379
1380        if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
1381            (batadv_compare_eth(router->addr, ethhdr->h_source)))
1382                is_from_best_next_hop = true;
1383
1384        prev_sender = ogm_packet->prev_sender;
1385        /* avoid temporary routing loops */
1386        if (router && router_router &&
1387            (batadv_compare_eth(router->addr, prev_sender)) &&
1388            !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
1389            (batadv_compare_eth(router->addr, router_router->addr))) {
1390                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1391                           "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
1392                           ethhdr->h_source);
1393                goto out;
1394        }
1395
1396        if (if_outgoing == BATADV_IF_DEFAULT)
1397                batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
1398
1399        /* if sender is a direct neighbor the sender mac equals
1400         * originator mac
1401         */
1402        if (is_single_hop_neigh)
1403                orig_neigh_node = orig_node;
1404        else
1405                orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1406                                                         ethhdr->h_source);
1407
1408        if (!orig_neigh_node)
1409                goto out;
1410
1411        /* Update nc_nodes of the originator */
1412        batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
1413                                 ogm_packet, is_single_hop_neigh);
1414
1415        orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
1416                                                   if_outgoing);
1417
1418        /* drop packet if sender is not a direct neighbor and if we
1419         * don't route towards it
1420         */
1421        if (!is_single_hop_neigh && !orig_neigh_router) {
1422                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1423                           "Drop packet: OGM via unknown neighbor!\n");
1424                goto out_neigh;
1425        }
1426
1427        is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1428                                            ogm_packet, if_incoming,
1429                                            if_outgoing);
1430
1431        /* update ranking if it is not a duplicate or has the same
1432         * seqno and similar ttl as the non-duplicate
1433         */
1434        orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1435        if (!orig_ifinfo)
1436                goto out_neigh;
1437
1438        sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
1439        similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;
1440
1441        if (is_bidirect && (dup_status == BATADV_NO_DUP ||
1442                            (sameseq && similar_ttl))) {
1443                batadv_iv_ogm_orig_update(bat_priv, orig_node,
1444                                          orig_ifinfo, ethhdr,
1445                                          ogm_packet, if_incoming,
1446                                          if_outgoing, dup_status);
1447        }
1448        batadv_orig_ifinfo_put(orig_ifinfo);
1449
1450        /* only forward for specific interface, not for the default one. */
1451        if (if_outgoing == BATADV_IF_DEFAULT)
1452                goto out_neigh;
1453
1454        /* is single hop (direct) neighbor */
1455        if (is_single_hop_neigh) {
1456                /* OGMs from secondary interfaces should only scheduled once
1457                 * per interface where it has been received, not multiple times
1458                 */
1459                if (ogm_packet->ttl <= 2 &&
1460                    if_incoming != if_outgoing) {
1461                        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1462                                   "Drop packet: OGM from secondary interface and wrong outgoing interface\n");
1463                        goto out_neigh;
1464                }
1465                /* mark direct link on incoming interface */
1466                batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1467                                      is_single_hop_neigh,
1468                                      is_from_best_next_hop, if_incoming,
1469                                      if_outgoing);
1470
1471                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1472                           "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1473                goto out_neigh;
1474        }
1475
1476        /* multihop originator */
1477        if (!is_bidirect) {
1478                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1479                           "Drop packet: not received via bidirectional link\n");
1480                goto out_neigh;
1481        }
1482
1483        if (dup_status == BATADV_NEIGH_DUP) {
1484                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1485                           "Drop packet: duplicate packet received\n");
1486                goto out_neigh;
1487        }
1488
1489        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1490                   "Forwarding packet: rebroadcast originator packet\n");
1491        batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1492                              is_single_hop_neigh, is_from_best_next_hop,
1493                              if_incoming, if_outgoing);
1494
1495out_neigh:
1496        if (orig_neigh_node && !is_single_hop_neigh)
1497                batadv_orig_node_put(orig_neigh_node);
1498out:
1499        if (router_ifinfo)
1500                batadv_neigh_ifinfo_put(router_ifinfo);
1501        if (router)
1502                batadv_neigh_node_put(router);
1503        if (router_router)
1504                batadv_neigh_node_put(router_router);
1505        if (orig_neigh_router)
1506                batadv_neigh_node_put(orig_neigh_router);
1507        if (hardif_neigh)
1508                batadv_hardif_neigh_put(hardif_neigh);
1509
1510        consume_skb(skb_priv);
1511}
1512
1513/**
1514 * batadv_iv_ogm_process_reply() - Check OGM for direct reply and process it
1515 * @ogm_packet: rebroadcast OGM packet to process
1516 * @if_incoming: the interface where this packet was received
1517 * @orig_node: originator which reproadcasted the OGMs
1518 * @if_incoming_seqno: OGM sequence number when rebroadcast was received
1519 */
1520static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet,
1521                                        struct batadv_hard_iface *if_incoming,
1522                                        struct batadv_orig_node *orig_node,
1523                                        u32 if_incoming_seqno)
1524{
1525        struct batadv_orig_ifinfo *orig_ifinfo;
1526        s32 bit_pos;
1527        u8 *weight;
1528
1529        /* neighbor has to indicate direct link and it has to
1530         * come via the corresponding interface
1531         */
1532        if (!(ogm_packet->flags & BATADV_DIRECTLINK))
1533                return;
1534
1535        if (!batadv_compare_eth(if_incoming->net_dev->dev_addr,
1536                                ogm_packet->orig))
1537                return;
1538
1539        orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_incoming);
1540        if (!orig_ifinfo)
1541                return;
1542
1543        /* save packet seqno for bidirectional check */
1544        spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1545        bit_pos = if_incoming_seqno - 2;
1546        bit_pos -= ntohl(ogm_packet->seqno);
1547        batadv_set_bit(orig_ifinfo->bat_iv.bcast_own, bit_pos);
1548        weight = &orig_ifinfo->bat_iv.bcast_own_sum;
1549        *weight = bitmap_weight(orig_ifinfo->bat_iv.bcast_own,
1550                                BATADV_TQ_LOCAL_WINDOW_SIZE);
1551        spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1552
1553        batadv_orig_ifinfo_put(orig_ifinfo);
1554}
1555
1556/**
1557 * batadv_iv_ogm_process() - process an incoming batman iv OGM
1558 * @skb: the skb containing the OGM
1559 * @ogm_offset: offset to the OGM which should be processed (for aggregates)
1560 * @if_incoming: the interface where this packet was received
1561 */
1562static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
1563                                  struct batadv_hard_iface *if_incoming)
1564{
1565        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1566        struct batadv_orig_node *orig_neigh_node, *orig_node;
1567        struct batadv_hard_iface *hard_iface;
1568        struct batadv_ogm_packet *ogm_packet;
1569        u32 if_incoming_seqno;
1570        bool has_directlink_flag;
1571        struct ethhdr *ethhdr;
1572        bool is_my_oldorig = false;
1573        bool is_my_addr = false;
1574        bool is_my_orig = false;
1575
1576        ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
1577        ethhdr = eth_hdr(skb);
1578
1579        /* Silently drop when the batman packet is actually not a
1580         * correct packet.
1581         *
1582         * This might happen if a packet is padded (e.g. Ethernet has a
1583         * minimum frame length of 64 byte) and the aggregation interprets
1584         * it as an additional length.
1585         *
1586         * TODO: A more sane solution would be to have a bit in the
1587         * batadv_ogm_packet to detect whether the packet is the last
1588         * packet in an aggregation.  Here we expect that the padding
1589         * is always zero (or not 0x01)
1590         */
1591        if (ogm_packet->packet_type != BATADV_IV_OGM)
1592                return;
1593
1594        /* could be changed by schedule_own_packet() */
1595        if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1596
1597        if (ogm_packet->flags & BATADV_DIRECTLINK)
1598                has_directlink_flag = true;
1599        else
1600                has_directlink_flag = false;
1601
1602        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1603                   "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1604                   ethhdr->h_source, if_incoming->net_dev->name,
1605                   if_incoming->net_dev->dev_addr, ogm_packet->orig,
1606                   ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
1607                   ogm_packet->tq, ogm_packet->ttl,
1608                   ogm_packet->version, has_directlink_flag);
1609
1610        rcu_read_lock();
1611        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1612                if (hard_iface->if_status != BATADV_IF_ACTIVE)
1613                        continue;
1614
1615                if (hard_iface->soft_iface != if_incoming->soft_iface)
1616                        continue;
1617
1618                if (batadv_compare_eth(ethhdr->h_source,
1619                                       hard_iface->net_dev->dev_addr))
1620                        is_my_addr = true;
1621
1622                if (batadv_compare_eth(ogm_packet->orig,
1623                                       hard_iface->net_dev->dev_addr))
1624                        is_my_orig = true;
1625
1626                if (batadv_compare_eth(ogm_packet->prev_sender,
1627                                       hard_iface->net_dev->dev_addr))
1628                        is_my_oldorig = true;
1629        }
1630        rcu_read_unlock();
1631
1632        if (is_my_addr) {
1633                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1634                           "Drop packet: received my own broadcast (sender: %pM)\n",
1635                           ethhdr->h_source);
1636                return;
1637        }
1638
1639        if (is_my_orig) {
1640                orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1641                                                         ethhdr->h_source);
1642                if (!orig_neigh_node)
1643                        return;
1644
1645                batadv_iv_ogm_process_reply(ogm_packet, if_incoming,
1646                                            orig_neigh_node, if_incoming_seqno);
1647
1648                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1649                           "Drop packet: originator packet from myself (via neighbor)\n");
1650                batadv_orig_node_put(orig_neigh_node);
1651                return;
1652        }
1653
1654        if (is_my_oldorig) {
1655                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1656                           "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1657                           ethhdr->h_source);
1658                return;
1659        }
1660
1661        if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1662                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1663                           "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1664                           ethhdr->h_source);
1665                return;
1666        }
1667
1668        orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
1669        if (!orig_node)
1670                return;
1671
1672        batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1673                                        if_incoming, BATADV_IF_DEFAULT);
1674
1675        rcu_read_lock();
1676        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1677                if (hard_iface->if_status != BATADV_IF_ACTIVE)
1678                        continue;
1679
1680                if (hard_iface->soft_iface != bat_priv->soft_iface)
1681                        continue;
1682
1683                if (!kref_get_unless_zero(&hard_iface->refcount))
1684                        continue;
1685
1686                batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1687                                                if_incoming, hard_iface);
1688
1689                batadv_hardif_put(hard_iface);
1690        }
1691        rcu_read_unlock();
1692
1693        batadv_orig_node_put(orig_node);
1694}
1695
1696static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
1697{
1698        struct delayed_work *delayed_work;
1699        struct batadv_forw_packet *forw_packet;
1700        struct batadv_priv *bat_priv;
1701        bool dropped = false;
1702
1703        delayed_work = to_delayed_work(work);
1704        forw_packet = container_of(delayed_work, struct batadv_forw_packet,
1705                                   delayed_work);
1706        bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
1707
1708        if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
1709                dropped = true;
1710                goto out;
1711        }
1712
1713        batadv_iv_ogm_emit(forw_packet);
1714
1715        /* we have to have at least one packet in the queue to determine the
1716         * queues wake up time unless we are shutting down.
1717         *
1718         * only re-schedule if this is the "original" copy, e.g. the OGM of the
1719         * primary interface should only be rescheduled once per period, but
1720         * this function will be called for the forw_packet instances of the
1721         * other secondary interfaces as well.
1722         */
1723        if (forw_packet->own &&
1724            forw_packet->if_incoming == forw_packet->if_outgoing)
1725                batadv_iv_ogm_schedule(forw_packet->if_incoming);
1726
1727out:
1728        /* do we get something for free()? */
1729        if (batadv_forw_packet_steal(forw_packet,
1730                                     &bat_priv->forw_bat_list_lock))
1731                batadv_forw_packet_free(forw_packet, dropped);
1732}
1733
1734static int batadv_iv_ogm_receive(struct sk_buff *skb,
1735                                 struct batadv_hard_iface *if_incoming)
1736{
1737        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1738        struct batadv_ogm_packet *ogm_packet;
1739        u8 *packet_pos;
1740        int ogm_offset;
1741        bool res;
1742        int ret = NET_RX_DROP;
1743
1744        res = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1745        if (!res)
1746                goto free_skb;
1747
1748        /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
1749         * that does not have B.A.T.M.A.N. IV enabled ?
1750         */
1751        if (bat_priv->algo_ops->iface.enable != batadv_iv_ogm_iface_enable)
1752                goto free_skb;
1753
1754        batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
1755        batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1756                           skb->len + ETH_HLEN);
1757
1758        ogm_offset = 0;
1759        ogm_packet = (struct batadv_ogm_packet *)skb->data;
1760
1761        /* unpack the aggregated packets and process them one by one */
1762        while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
1763                                         ogm_packet)) {
1764                batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
1765
1766                ogm_offset += BATADV_OGM_HLEN;
1767                ogm_offset += ntohs(ogm_packet->tvlv_len);
1768
1769                packet_pos = skb->data + ogm_offset;
1770                ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1771        }
1772
1773        ret = NET_RX_SUCCESS;
1774
1775free_skb:
1776        if (ret == NET_RX_SUCCESS)
1777                consume_skb(skb);
1778        else
1779                kfree_skb(skb);
1780
1781        return ret;
1782}
1783
1784/**
1785 * batadv_iv_ogm_neigh_get_tq_avg() - Get the TQ average for a neighbour on a
1786 *  given outgoing interface.
1787 * @neigh_node: Neighbour of interest
1788 * @if_outgoing: Outgoing interface of interest
1789 * @tq_avg: Pointer of where to store the TQ average
1790 *
1791 * Return: False if no average TQ available, otherwise true.
1792 */
1793static bool
1794batadv_iv_ogm_neigh_get_tq_avg(struct batadv_neigh_node *neigh_node,
1795                               struct batadv_hard_iface *if_outgoing,
1796                               u8 *tq_avg)
1797{
1798        struct batadv_neigh_ifinfo *n_ifinfo;
1799
1800        n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
1801        if (!n_ifinfo)
1802                return false;
1803
1804        *tq_avg = n_ifinfo->bat_iv.tq_avg;
1805        batadv_neigh_ifinfo_put(n_ifinfo);
1806
1807        return true;
1808}
1809
1810/**
1811 * batadv_iv_ogm_orig_dump_subentry() - Dump an originator subentry into a
1812 *  message
1813 * @msg: Netlink message to dump into
1814 * @portid: Port making netlink request
1815 * @seq: Sequence number of netlink message
1816 * @bat_priv: The bat priv with all the soft interface information
1817 * @if_outgoing: Limit dump to entries with this outgoing interface
1818 * @orig_node: Originator to dump
1819 * @neigh_node: Single hops neighbour
1820 * @best: Is the best originator
1821 *
1822 * Return: Error code, or 0 on success
1823 */
1824static int
1825batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
1826                                 struct batadv_priv *bat_priv,
1827                                 struct batadv_hard_iface *if_outgoing,
1828                                 struct batadv_orig_node *orig_node,
1829                                 struct batadv_neigh_node *neigh_node,
1830                                 bool best)
1831{
1832        void *hdr;
1833        u8 tq_avg;
1834        unsigned int last_seen_msecs;
1835
1836        last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
1837
1838        if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node, if_outgoing, &tq_avg))
1839                return 0;
1840
1841        if (if_outgoing != BATADV_IF_DEFAULT &&
1842            if_outgoing != neigh_node->if_incoming)
1843                return 0;
1844
1845        hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
1846                          NLM_F_MULTI, BATADV_CMD_GET_ORIGINATORS);
1847        if (!hdr)
1848                return -ENOBUFS;
1849
1850        if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
1851                    orig_node->orig) ||
1852            nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
1853                    neigh_node->addr) ||
1854            nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
1855                           neigh_node->if_incoming->net_dev->name) ||
1856            nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
1857                        neigh_node->if_incoming->net_dev->ifindex) ||
1858            nla_put_u8(msg, BATADV_ATTR_TQ, tq_avg) ||
1859            nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
1860                        last_seen_msecs))
1861                goto nla_put_failure;
1862
1863        if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
1864                goto nla_put_failure;
1865
1866        genlmsg_end(msg, hdr);
1867        return 0;
1868
1869 nla_put_failure:
1870        genlmsg_cancel(msg, hdr);
1871        return -EMSGSIZE;
1872}
1873
1874/**
1875 * batadv_iv_ogm_orig_dump_entry() - Dump an originator entry into a message
1876 * @msg: Netlink message to dump into
1877 * @portid: Port making netlink request
1878 * @seq: Sequence number of netlink message
1879 * @bat_priv: The bat priv with all the soft interface information
1880 * @if_outgoing: Limit dump to entries with this outgoing interface
1881 * @orig_node: Originator to dump
1882 * @sub_s: Number of sub entries to skip
1883 *
1884 * This function assumes the caller holds rcu_read_lock().
1885 *
1886 * Return: Error code, or 0 on success
1887 */
1888static int
1889batadv_iv_ogm_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1890                              struct batadv_priv *bat_priv,
1891                              struct batadv_hard_iface *if_outgoing,
1892                              struct batadv_orig_node *orig_node, int *sub_s)
1893{
1894        struct batadv_neigh_node *neigh_node_best;
1895        struct batadv_neigh_node *neigh_node;
1896        int sub = 0;
1897        bool best;
1898        u8 tq_avg_best;
1899
1900        neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
1901        if (!neigh_node_best)
1902                goto out;
1903
1904        if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node_best, if_outgoing,
1905                                            &tq_avg_best))
1906                goto out;
1907
1908        if (tq_avg_best == 0)
1909                goto out;
1910
1911        hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1912                if (sub++ < *sub_s)
1913                        continue;
1914
1915                best = (neigh_node == neigh_node_best);
1916
1917                if (batadv_iv_ogm_orig_dump_subentry(msg, portid, seq,
1918                                                     bat_priv, if_outgoing,
1919                                                     orig_node, neigh_node,
1920                                                     best)) {
1921                        batadv_neigh_node_put(neigh_node_best);
1922
1923                        *sub_s = sub - 1;
1924                        return -EMSGSIZE;
1925                }
1926        }
1927
1928 out:
1929        if (neigh_node_best)
1930                batadv_neigh_node_put(neigh_node_best);
1931
1932        *sub_s = 0;
1933        return 0;
1934}
1935
1936/**
1937 * batadv_iv_ogm_orig_dump_bucket() - Dump an originator bucket into a
1938 *  message
1939 * @msg: Netlink message to dump into
1940 * @portid: Port making netlink request
1941 * @seq: Sequence number of netlink message
1942 * @bat_priv: The bat priv with all the soft interface information
1943 * @if_outgoing: Limit dump to entries with this outgoing interface
1944 * @head: Bucket to be dumped
1945 * @idx_s: Number of entries to be skipped
1946 * @sub: Number of sub entries to be skipped
1947 *
1948 * Return: Error code, or 0 on success
1949 */
1950static int
1951batadv_iv_ogm_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1952                               struct batadv_priv *bat_priv,
1953                               struct batadv_hard_iface *if_outgoing,
1954                               struct hlist_head *head, int *idx_s, int *sub)
1955{
1956        struct batadv_orig_node *orig_node;
1957        int idx = 0;
1958
1959        rcu_read_lock();
1960        hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1961                if (idx++ < *idx_s)
1962                        continue;
1963
1964                if (batadv_iv_ogm_orig_dump_entry(msg, portid, seq, bat_priv,
1965                                                  if_outgoing, orig_node,
1966                                                  sub)) {
1967                        rcu_read_unlock();
1968                        *idx_s = idx - 1;
1969                        return -EMSGSIZE;
1970                }
1971        }
1972        rcu_read_unlock();
1973
1974        *idx_s = 0;
1975        *sub = 0;
1976        return 0;
1977}
1978
1979/**
1980 * batadv_iv_ogm_orig_dump() - Dump the originators into a message
1981 * @msg: Netlink message to dump into
1982 * @cb: Control block containing additional options
1983 * @bat_priv: The bat priv with all the soft interface information
1984 * @if_outgoing: Limit dump to entries with this outgoing interface
1985 */
1986static void
1987batadv_iv_ogm_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
1988                        struct batadv_priv *bat_priv,
1989                        struct batadv_hard_iface *if_outgoing)
1990{
1991        struct batadv_hashtable *hash = bat_priv->orig_hash;
1992        struct hlist_head *head;
1993        int bucket = cb->args[0];
1994        int idx = cb->args[1];
1995        int sub = cb->args[2];
1996        int portid = NETLINK_CB(cb->skb).portid;
1997
1998        while (bucket < hash->size) {
1999                head = &hash->table[bucket];
2000
2001                if (batadv_iv_ogm_orig_dump_bucket(msg, portid,
2002                                                   cb->nlh->nlmsg_seq,
2003                                                   bat_priv, if_outgoing, head,
2004                                                   &idx, &sub))
2005                        break;
2006
2007                bucket++;
2008        }
2009
2010        cb->args[0] = bucket;
2011        cb->args[1] = idx;
2012        cb->args[2] = sub;
2013}
2014
2015/**
2016 * batadv_iv_ogm_neigh_diff() - calculate tq difference of two neighbors
2017 * @neigh1: the first neighbor object of the comparison
2018 * @if_outgoing1: outgoing interface for the first neighbor
2019 * @neigh2: the second neighbor object of the comparison
2020 * @if_outgoing2: outgoing interface for the second neighbor
2021 * @diff: pointer to integer receiving the calculated difference
2022 *
2023 * The content of *@diff is only valid when this function returns true.
2024 * It is less, equal to or greater than 0 if the metric via neigh1 is lower,
2025 * the same as or higher than the metric via neigh2
2026 *
2027 * Return: true when the difference could be calculated, false otherwise
2028 */
2029static bool batadv_iv_ogm_neigh_diff(struct batadv_neigh_node *neigh1,
2030                                     struct batadv_hard_iface *if_outgoing1,
2031                                     struct batadv_neigh_node *neigh2,
2032                                     struct batadv_hard_iface *if_outgoing2,
2033                                     int *diff)
2034{
2035        struct batadv_neigh_ifinfo *neigh1_ifinfo, *neigh2_ifinfo;
2036        u8 tq1, tq2;
2037        bool ret = true;
2038
2039        neigh1_ifinfo = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
2040        neigh2_ifinfo = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
2041
2042        if (!neigh1_ifinfo || !neigh2_ifinfo) {
2043                ret = false;
2044                goto out;
2045        }
2046
2047        tq1 = neigh1_ifinfo->bat_iv.tq_avg;
2048        tq2 = neigh2_ifinfo->bat_iv.tq_avg;
2049        *diff = (int)tq1 - (int)tq2;
2050
2051out:
2052        if (neigh1_ifinfo)
2053                batadv_neigh_ifinfo_put(neigh1_ifinfo);
2054        if (neigh2_ifinfo)
2055                batadv_neigh_ifinfo_put(neigh2_ifinfo);
2056
2057        return ret;
2058}
2059
2060/**
2061 * batadv_iv_ogm_neigh_dump_neigh() - Dump a neighbour into a netlink message
2062 * @msg: Netlink message to dump into
2063 * @portid: Port making netlink request
2064 * @seq: Sequence number of netlink message
2065 * @hardif_neigh: Neighbour to be dumped
2066 *
2067 * Return: Error code, or 0 on success
2068 */
2069static int
2070batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
2071                               struct batadv_hardif_neigh_node *hardif_neigh)
2072{
2073        void *hdr;
2074        unsigned int last_seen_msecs;
2075
2076        last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
2077
2078        hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
2079                          NLM_F_MULTI, BATADV_CMD_GET_NEIGHBORS);
2080        if (!hdr)
2081                return -ENOBUFS;
2082
2083        if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
2084                    hardif_neigh->addr) ||
2085            nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
2086                           hardif_neigh->if_incoming->net_dev->name) ||
2087            nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
2088                        hardif_neigh->if_incoming->net_dev->ifindex) ||
2089            nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
2090                        last_seen_msecs))
2091                goto nla_put_failure;
2092
2093        genlmsg_end(msg, hdr);
2094        return 0;
2095
2096 nla_put_failure:
2097        genlmsg_cancel(msg, hdr);
2098        return -EMSGSIZE;
2099}
2100
2101/**
2102 * batadv_iv_ogm_neigh_dump_hardif() - Dump the neighbours of a hard interface
2103 *  into a message
2104 * @msg: Netlink message to dump into
2105 * @portid: Port making netlink request
2106 * @seq: Sequence number of netlink message
2107 * @bat_priv: The bat priv with all the soft interface information
2108 * @hard_iface: Hard interface to dump the neighbours for
2109 * @idx_s: Number of entries to skip
2110 *
2111 * This function assumes the caller holds rcu_read_lock().
2112 *
2113 * Return: Error code, or 0 on success
2114 */
2115static int
2116batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
2117                                struct batadv_priv *bat_priv,
2118                                struct batadv_hard_iface *hard_iface,
2119                                int *idx_s)
2120{
2121        struct batadv_hardif_neigh_node *hardif_neigh;
2122        int idx = 0;
2123
2124        hlist_for_each_entry_rcu(hardif_neigh,
2125                                 &hard_iface->neigh_list, list) {
2126                if (idx++ < *idx_s)
2127                        continue;
2128
2129                if (batadv_iv_ogm_neigh_dump_neigh(msg, portid, seq,
2130                                                   hardif_neigh)) {
2131                        *idx_s = idx - 1;
2132                        return -EMSGSIZE;
2133                }
2134        }
2135
2136        *idx_s = 0;
2137        return 0;
2138}
2139
2140/**
2141 * batadv_iv_ogm_neigh_dump() - Dump the neighbours into a message
2142 * @msg: Netlink message to dump into
2143 * @cb: Control block containing additional options
2144 * @bat_priv: The bat priv with all the soft interface information
2145 * @single_hardif: Limit dump to this hard interface
2146 */
2147static void
2148batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
2149                         struct batadv_priv *bat_priv,
2150                         struct batadv_hard_iface *single_hardif)
2151{
2152        struct batadv_hard_iface *hard_iface;
2153        int i_hardif = 0;
2154        int i_hardif_s = cb->args[0];
2155        int idx = cb->args[1];
2156        int portid = NETLINK_CB(cb->skb).portid;
2157
2158        rcu_read_lock();
2159        if (single_hardif) {
2160                if (i_hardif_s == 0) {
2161                        if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
2162                                                            cb->nlh->nlmsg_seq,
2163                                                            bat_priv,
2164                                                            single_hardif,
2165                                                            &idx) == 0)
2166                                i_hardif++;
2167                }
2168        } else {
2169                list_for_each_entry_rcu(hard_iface, &batadv_hardif_list,
2170                                        list) {
2171                        if (hard_iface->soft_iface != bat_priv->soft_iface)
2172                                continue;
2173
2174                        if (i_hardif++ < i_hardif_s)
2175                                continue;
2176
2177                        if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
2178                                                            cb->nlh->nlmsg_seq,
2179                                                            bat_priv,
2180                                                            hard_iface, &idx)) {
2181                                i_hardif--;
2182                                break;
2183                        }
2184                }
2185        }
2186        rcu_read_unlock();
2187
2188        cb->args[0] = i_hardif;
2189        cb->args[1] = idx;
2190}
2191
2192/**
2193 * batadv_iv_ogm_neigh_cmp() - compare the metrics of two neighbors
2194 * @neigh1: the first neighbor object of the comparison
2195 * @if_outgoing1: outgoing interface for the first neighbor
2196 * @neigh2: the second neighbor object of the comparison
2197 * @if_outgoing2: outgoing interface for the second neighbor
2198 *
2199 * Return: a value less, equal to or greater than 0 if the metric via neigh1 is
2200 * lower, the same as or higher than the metric via neigh2
2201 */
2202static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
2203                                   struct batadv_hard_iface *if_outgoing1,
2204                                   struct batadv_neigh_node *neigh2,
2205                                   struct batadv_hard_iface *if_outgoing2)
2206{
2207        bool ret;
2208        int diff;
2209
2210        ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
2211                                       if_outgoing2, &diff);
2212        if (!ret)
2213                return 0;
2214
2215        return diff;
2216}
2217
2218/**
2219 * batadv_iv_ogm_neigh_is_sob() - check if neigh1 is similarly good or better
2220 *  than neigh2 from the metric prospective
2221 * @neigh1: the first neighbor object of the comparison
2222 * @if_outgoing1: outgoing interface for the first neighbor
2223 * @neigh2: the second neighbor object of the comparison
2224 * @if_outgoing2: outgoing interface for the second neighbor
2225 *
2226 * Return: true if the metric via neigh1 is equally good or better than
2227 * the metric via neigh2, false otherwise.
2228 */
2229static bool
2230batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
2231                           struct batadv_hard_iface *if_outgoing1,
2232                           struct batadv_neigh_node *neigh2,
2233                           struct batadv_hard_iface *if_outgoing2)
2234{
2235        bool ret;
2236        int diff;
2237
2238        ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
2239                                       if_outgoing2, &diff);
2240        if (!ret)
2241                return false;
2242
2243        ret = diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
2244        return ret;
2245}
2246
2247static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
2248{
2249        /* begin scheduling originator messages on that interface */
2250        batadv_iv_ogm_schedule(hard_iface);
2251}
2252
2253/**
2254 * batadv_iv_init_sel_class() - initialize GW selection class
2255 * @bat_priv: the bat priv with all the soft interface information
2256 */
2257static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
2258{
2259        /* set default TQ difference threshold to 20 */
2260        atomic_set(&bat_priv->gw.sel_class, 20);
2261}
2262
2263static struct batadv_gw_node *
2264batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
2265{
2266        struct batadv_neigh_node *router;
2267        struct batadv_neigh_ifinfo *router_ifinfo;
2268        struct batadv_gw_node *gw_node, *curr_gw = NULL;
2269        u64 max_gw_factor = 0;
2270        u64 tmp_gw_factor = 0;
2271        u8 max_tq = 0;
2272        u8 tq_avg;
2273        struct batadv_orig_node *orig_node;
2274
2275        rcu_read_lock();
2276        hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
2277                orig_node = gw_node->orig_node;
2278                router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
2279                if (!router)
2280                        continue;
2281
2282                router_ifinfo = batadv_neigh_ifinfo_get(router,
2283                                                        BATADV_IF_DEFAULT);
2284                if (!router_ifinfo)
2285                        goto next;
2286
2287                if (!kref_get_unless_zero(&gw_node->refcount))
2288                        goto next;
2289
2290                tq_avg = router_ifinfo->bat_iv.tq_avg;
2291
2292                switch (atomic_read(&bat_priv->gw.sel_class)) {
2293                case 1: /* fast connection */
2294                        tmp_gw_factor = tq_avg * tq_avg;
2295                        tmp_gw_factor *= gw_node->bandwidth_down;
2296                        tmp_gw_factor *= 100 * 100;
2297                        tmp_gw_factor >>= 18;
2298
2299                        if (tmp_gw_factor > max_gw_factor ||
2300                            (tmp_gw_factor == max_gw_factor &&
2301                             tq_avg > max_tq)) {
2302                                if (curr_gw)
2303                                        batadv_gw_node_put(curr_gw);
2304                                curr_gw = gw_node;
2305                                kref_get(&curr_gw->refcount);
2306                        }
2307                        break;
2308
2309                default: /* 2:  stable connection (use best statistic)
2310                          * 3:  fast-switch (use best statistic but change as
2311                          *     soon as a better gateway appears)
2312                          * XX: late-switch (use best statistic but change as
2313                          *     soon as a better gateway appears which has
2314                          *     $routing_class more tq points)
2315                          */
2316                        if (tq_avg > max_tq) {
2317                                if (curr_gw)
2318                                        batadv_gw_node_put(curr_gw);
2319                                curr_gw = gw_node;
2320                                kref_get(&curr_gw->refcount);
2321                        }
2322                        break;
2323                }
2324
2325                if (tq_avg > max_tq)
2326                        max_tq = tq_avg;
2327
2328                if (tmp_gw_factor > max_gw_factor)
2329                        max_gw_factor = tmp_gw_factor;
2330
2331                batadv_gw_node_put(gw_node);
2332
2333next:
2334                batadv_neigh_node_put(router);
2335                if (router_ifinfo)
2336                        batadv_neigh_ifinfo_put(router_ifinfo);
2337        }
2338        rcu_read_unlock();
2339
2340        return curr_gw;
2341}
2342
2343static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
2344                                     struct batadv_orig_node *curr_gw_orig,
2345                                     struct batadv_orig_node *orig_node)
2346{
2347        struct batadv_neigh_ifinfo *router_orig_ifinfo = NULL;
2348        struct batadv_neigh_ifinfo *router_gw_ifinfo = NULL;
2349        struct batadv_neigh_node *router_gw = NULL;
2350        struct batadv_neigh_node *router_orig = NULL;
2351        u8 gw_tq_avg, orig_tq_avg;
2352        bool ret = false;
2353
2354        /* dynamic re-election is performed only on fast or late switch */
2355        if (atomic_read(&bat_priv->gw.sel_class) <= 2)
2356                return false;
2357
2358        router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
2359        if (!router_gw) {
2360                ret = true;
2361                goto out;
2362        }
2363
2364        router_gw_ifinfo = batadv_neigh_ifinfo_get(router_gw,
2365                                                   BATADV_IF_DEFAULT);
2366        if (!router_gw_ifinfo) {
2367                ret = true;
2368                goto out;
2369        }
2370
2371        router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
2372        if (!router_orig)
2373                goto out;
2374
2375        router_orig_ifinfo = batadv_neigh_ifinfo_get(router_orig,
2376                                                     BATADV_IF_DEFAULT);
2377        if (!router_orig_ifinfo)
2378                goto out;
2379
2380        gw_tq_avg = router_gw_ifinfo->bat_iv.tq_avg;
2381        orig_tq_avg = router_orig_ifinfo->bat_iv.tq_avg;
2382
2383        /* the TQ value has to be better */
2384        if (orig_tq_avg < gw_tq_avg)
2385                goto out;
2386
2387        /* if the routing class is greater than 3 the value tells us how much
2388         * greater the TQ value of the new gateway must be
2389         */
2390        if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
2391            (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
2392                goto out;
2393
2394        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
2395                   "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
2396                   gw_tq_avg, orig_tq_avg);
2397
2398        ret = true;
2399out:
2400        if (router_gw_ifinfo)
2401                batadv_neigh_ifinfo_put(router_gw_ifinfo);
2402        if (router_orig_ifinfo)
2403                batadv_neigh_ifinfo_put(router_orig_ifinfo);
2404        if (router_gw)
2405                batadv_neigh_node_put(router_gw);
2406        if (router_orig)
2407                batadv_neigh_node_put(router_orig);
2408
2409        return ret;
2410}
2411
2412/**
2413 * batadv_iv_gw_dump_entry() - Dump a gateway into a message
2414 * @msg: Netlink message to dump into
2415 * @portid: Port making netlink request
2416 * @cb: Control block containing additional options
2417 * @bat_priv: The bat priv with all the soft interface information
2418 * @gw_node: Gateway to be dumped
2419 *
2420 * Return: Error code, or 0 on success
2421 */
2422static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid,
2423                                   struct netlink_callback *cb,
2424                                   struct batadv_priv *bat_priv,
2425                                   struct batadv_gw_node *gw_node)
2426{
2427        struct batadv_neigh_ifinfo *router_ifinfo = NULL;
2428        struct batadv_neigh_node *router;
2429        struct batadv_gw_node *curr_gw = NULL;
2430        int ret = 0;
2431        void *hdr;
2432
2433        router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
2434        if (!router)
2435                goto out;
2436
2437        router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
2438        if (!router_ifinfo)
2439                goto out;
2440
2441        curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
2442
2443        hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2444                          &batadv_netlink_family, NLM_F_MULTI,
2445                          BATADV_CMD_GET_GATEWAYS);
2446        if (!hdr) {
2447                ret = -ENOBUFS;
2448                goto out;
2449        }
2450
2451        genl_dump_check_consistent(cb, hdr);
2452
2453        ret = -EMSGSIZE;
2454
2455        if (curr_gw == gw_node)
2456                if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
2457                        genlmsg_cancel(msg, hdr);
2458                        goto out;
2459                }
2460
2461        if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
2462                    gw_node->orig_node->orig) ||
2463            nla_put_u8(msg, BATADV_ATTR_TQ, router_ifinfo->bat_iv.tq_avg) ||
2464            nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN,
2465                    router->addr) ||
2466            nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
2467                           router->if_incoming->net_dev->name) ||
2468            nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
2469                        router->if_incoming->net_dev->ifindex) ||
2470            nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
2471                        gw_node->bandwidth_down) ||
2472            nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP,
2473                        gw_node->bandwidth_up)) {
2474                genlmsg_cancel(msg, hdr);
2475                goto out;
2476        }
2477
2478        genlmsg_end(msg, hdr);
2479        ret = 0;
2480
2481out:
2482        if (curr_gw)
2483                batadv_gw_node_put(curr_gw);
2484        if (router_ifinfo)
2485                batadv_neigh_ifinfo_put(router_ifinfo);
2486        if (router)
2487                batadv_neigh_node_put(router);
2488        return ret;
2489}
2490
2491/**
2492 * batadv_iv_gw_dump() - Dump gateways into a message
2493 * @msg: Netlink message to dump into
2494 * @cb: Control block containing additional options
2495 * @bat_priv: The bat priv with all the soft interface information
2496 */
2497static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
2498                              struct batadv_priv *bat_priv)
2499{
2500        int portid = NETLINK_CB(cb->skb).portid;
2501        struct batadv_gw_node *gw_node;
2502        int idx_skip = cb->args[0];
2503        int idx = 0;
2504
2505        spin_lock_bh(&bat_priv->gw.list_lock);
2506        cb->seq = bat_priv->gw.generation << 1 | 1;
2507
2508        hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
2509                if (idx++ < idx_skip)
2510                        continue;
2511
2512                if (batadv_iv_gw_dump_entry(msg, portid, cb, bat_priv,
2513                                            gw_node)) {
2514                        idx_skip = idx - 1;
2515                        goto unlock;
2516                }
2517        }
2518
2519        idx_skip = idx;
2520unlock:
2521        spin_unlock_bh(&bat_priv->gw.list_lock);
2522
2523        cb->args[0] = idx_skip;
2524}
2525
2526static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
2527        .name = "BATMAN_IV",
2528        .iface = {
2529                .enable = batadv_iv_ogm_iface_enable,
2530                .enabled = batadv_iv_iface_enabled,
2531                .disable = batadv_iv_ogm_iface_disable,
2532                .update_mac = batadv_iv_ogm_iface_update_mac,
2533                .primary_set = batadv_iv_ogm_primary_iface_set,
2534        },
2535        .neigh = {
2536                .cmp = batadv_iv_ogm_neigh_cmp,
2537                .is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
2538                .dump = batadv_iv_ogm_neigh_dump,
2539        },
2540        .orig = {
2541                .dump = batadv_iv_ogm_orig_dump,
2542        },
2543        .gw = {
2544                .init_sel_class = batadv_iv_init_sel_class,
2545                .get_best_gw_node = batadv_iv_gw_get_best_gw_node,
2546                .is_eligible = batadv_iv_gw_is_eligible,
2547                .dump = batadv_iv_gw_dump,
2548        },
2549};
2550
2551/**
2552 * batadv_iv_init() - B.A.T.M.A.N. IV initialization function
2553 *
2554 * Return: 0 on success or negative error number in case of failure
2555 */
2556int __init batadv_iv_init(void)
2557{
2558        int ret;
2559
2560        /* batman originator packet */
2561        ret = batadv_recv_handler_register(BATADV_IV_OGM,
2562                                           batadv_iv_ogm_receive);
2563        if (ret < 0)
2564                goto out;
2565
2566        ret = batadv_algo_register(&batadv_batman_iv);
2567        if (ret < 0)
2568                goto handler_unregister;
2569
2570        goto out;
2571
2572handler_unregister:
2573        batadv_recv_handler_unregister(BATADV_IV_OGM);
2574out:
2575        return ret;
2576}
2577