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