linux/net/batman-adv/bat_iv_ogm.c
<<
>>
Prefs
   1/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
   2 *
   3 * Marek Lindner, Simon Wunderlich
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of version 2 of the GNU General Public
   7 * License as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but
  10 * WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12 * General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17 * 02110-1301, USA
  18 */
  19
  20#include "main.h"
  21#include "translation-table.h"
  22#include "originator.h"
  23#include "routing.h"
  24#include "gateway_common.h"
  25#include "gateway_client.h"
  26#include "hard-interface.h"
  27#include "send.h"
  28#include "bat_algo.h"
  29#include "network-coding.h"
  30
  31
  32/**
  33 * batadv_dup_status - duplicate status
  34 * @BATADV_NO_DUP: the packet is a duplicate
  35 * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
  36 *  neighbor)
  37 * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
  38 * @BATADV_PROTECTED: originator is currently protected (after reboot)
  39 */
  40enum batadv_dup_status {
  41        BATADV_NO_DUP = 0,
  42        BATADV_ORIG_DUP,
  43        BATADV_NEIGH_DUP,
  44        BATADV_PROTECTED,
  45};
  46
  47/**
  48 * batadv_ring_buffer_set - update the ring buffer with the given value
  49 * @lq_recv: pointer to the ring buffer
  50 * @lq_index: index to store the value at
  51 * @value: value to store in the ring buffer
  52 */
  53static void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
  54                                   uint8_t value)
  55{
  56        lq_recv[*lq_index] = value;
  57        *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
  58}
  59
  60/**
  61 * batadv_ring_buffer_set - compute the average of all non-zero values stored
  62 * in the given ring buffer
  63 * @lq_recv: pointer to the ring buffer
  64 *
  65 * Returns computed average value.
  66 */
  67static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
  68{
  69        const uint8_t *ptr;
  70        uint16_t count = 0, i = 0, sum = 0;
  71
  72        ptr = lq_recv;
  73
  74        while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
  75                if (*ptr != 0) {
  76                        count++;
  77                        sum += *ptr;
  78                }
  79
  80                i++;
  81                ptr++;
  82        }
  83
  84        if (count == 0)
  85                return 0;
  86
  87        return (uint8_t)(sum / count);
  88}
  89
  90static struct batadv_neigh_node *
  91batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
  92                        const uint8_t *neigh_addr,
  93                        struct batadv_orig_node *orig_node,
  94                        struct batadv_orig_node *orig_neigh)
  95{
  96        struct batadv_neigh_node *neigh_node;
  97
  98        neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr);
  99        if (!neigh_node)
 100                goto out;
 101
 102        INIT_LIST_HEAD(&neigh_node->bonding_list);
 103
 104        neigh_node->orig_node = orig_neigh;
 105        neigh_node->if_incoming = hard_iface;
 106
 107        spin_lock_bh(&orig_node->neigh_list_lock);
 108        hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
 109        spin_unlock_bh(&orig_node->neigh_list_lock);
 110
 111out:
 112        return neigh_node;
 113}
 114
 115static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
 116{
 117        struct batadv_ogm_packet *batadv_ogm_packet;
 118        unsigned char *ogm_buff;
 119        uint32_t random_seqno;
 120        int res = -ENOMEM;
 121
 122        /* randomize initial seqno to avoid collision */
 123        get_random_bytes(&random_seqno, sizeof(random_seqno));
 124        atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
 125
 126        hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
 127        ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
 128        if (!ogm_buff)
 129                goto out;
 130
 131        hard_iface->bat_iv.ogm_buff = ogm_buff;
 132
 133        batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
 134        batadv_ogm_packet->header.packet_type = BATADV_IV_OGM;
 135        batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
 136        batadv_ogm_packet->header.ttl = 2;
 137        batadv_ogm_packet->flags = BATADV_NO_FLAGS;
 138        batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
 139        batadv_ogm_packet->tt_num_changes = 0;
 140        batadv_ogm_packet->ttvn = 0;
 141
 142        res = 0;
 143
 144out:
 145        return res;
 146}
 147
 148static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
 149{
 150        kfree(hard_iface->bat_iv.ogm_buff);
 151        hard_iface->bat_iv.ogm_buff = NULL;
 152}
 153
 154static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
 155{
 156        struct batadv_ogm_packet *batadv_ogm_packet;
 157        unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
 158
 159        batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
 160        memcpy(batadv_ogm_packet->orig,
 161               hard_iface->net_dev->dev_addr, ETH_ALEN);
 162        memcpy(batadv_ogm_packet->prev_sender,
 163               hard_iface->net_dev->dev_addr, ETH_ALEN);
 164}
 165
 166static void
 167batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
 168{
 169        struct batadv_ogm_packet *batadv_ogm_packet;
 170        unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
 171
 172        batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
 173        batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
 174        batadv_ogm_packet->header.ttl = BATADV_TTL;
 175}
 176
 177/* when do we schedule our own ogm to be sent */
 178static unsigned long
 179batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
 180{
 181        unsigned int msecs;
 182
 183        msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
 184        msecs += prandom_u32() % (2 * BATADV_JITTER);
 185
 186        return jiffies + msecs_to_jiffies(msecs);
 187}
 188
 189/* when do we schedule a ogm packet to be sent */
 190static unsigned long batadv_iv_ogm_fwd_send_time(void)
 191{
 192        return jiffies + msecs_to_jiffies(prandom_u32() % (BATADV_JITTER / 2));
 193}
 194
 195/* apply hop penalty for a normal link */
 196static uint8_t batadv_hop_penalty(uint8_t tq,
 197                                  const struct batadv_priv *bat_priv)
 198{
 199        int hop_penalty = atomic_read(&bat_priv->hop_penalty);
 200        int new_tq;
 201
 202        new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
 203        new_tq /= BATADV_TQ_MAX_VALUE;
 204
 205        return new_tq;
 206}
 207
 208/* is there another aggregated packet here? */
 209static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
 210                                     int tt_num_changes)
 211{
 212        int next_buff_pos = 0;
 213
 214        next_buff_pos += buff_pos + BATADV_OGM_HLEN;
 215        next_buff_pos += batadv_tt_len(tt_num_changes);
 216
 217        return (next_buff_pos <= packet_len) &&
 218               (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
 219}
 220
 221/* send a batman ogm to a given interface */
 222static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
 223                                     struct batadv_hard_iface *hard_iface)
 224{
 225        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 226        char *fwd_str;
 227        uint8_t packet_num;
 228        int16_t buff_pos;
 229        struct batadv_ogm_packet *batadv_ogm_packet;
 230        struct sk_buff *skb;
 231        uint8_t *packet_pos;
 232
 233        if (hard_iface->if_status != BATADV_IF_ACTIVE)
 234                return;
 235
 236        packet_num = 0;
 237        buff_pos = 0;
 238        packet_pos = forw_packet->skb->data;
 239        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
 240
 241        /* adjust all flags and log packets */
 242        while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
 243                                         batadv_ogm_packet->tt_num_changes)) {
 244                /* we might have aggregated direct link packets with an
 245                 * ordinary base packet
 246                 */
 247                if (forw_packet->direct_link_flags & BIT(packet_num) &&
 248                    forw_packet->if_incoming == hard_iface)
 249                        batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
 250                else
 251                        batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
 252
 253                if (packet_num > 0 || !forw_packet->own)
 254                        fwd_str = "Forwarding";
 255                else
 256                        fwd_str = "Sending own";
 257
 258                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 259                           "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
 260                           fwd_str, (packet_num > 0 ? "aggregated " : ""),
 261                           batadv_ogm_packet->orig,
 262                           ntohl(batadv_ogm_packet->seqno),
 263                           batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl,
 264                           (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
 265                            "on" : "off"),
 266                           batadv_ogm_packet->ttvn, hard_iface->net_dev->name,
 267                           hard_iface->net_dev->dev_addr);
 268
 269                buff_pos += BATADV_OGM_HLEN;
 270                buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
 271                packet_num++;
 272                packet_pos = forw_packet->skb->data + buff_pos;
 273                batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
 274        }
 275
 276        /* create clone because function is called more than once */
 277        skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
 278        if (skb) {
 279                batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
 280                batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
 281                                   skb->len + ETH_HLEN);
 282                batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
 283        }
 284}
 285
 286/* send a batman ogm packet */
 287static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
 288{
 289        struct batadv_hard_iface *hard_iface;
 290        struct net_device *soft_iface;
 291        struct batadv_priv *bat_priv;
 292        struct batadv_hard_iface *primary_if = NULL;
 293        struct batadv_ogm_packet *batadv_ogm_packet;
 294        unsigned char directlink;
 295        uint8_t *packet_pos;
 296
 297        packet_pos = forw_packet->skb->data;
 298        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
 299        directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
 300
 301        if (!forw_packet->if_incoming) {
 302                pr_err("Error - can't forward packet: incoming iface not specified\n");
 303                goto out;
 304        }
 305
 306        soft_iface = forw_packet->if_incoming->soft_iface;
 307        bat_priv = netdev_priv(soft_iface);
 308
 309        if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
 310                goto out;
 311
 312        primary_if = batadv_primary_if_get_selected(bat_priv);
 313        if (!primary_if)
 314                goto out;
 315
 316        /* multihomed peer assumed
 317         * non-primary OGMs are only broadcasted on their interface
 318         */
 319        if ((directlink && (batadv_ogm_packet->header.ttl == 1)) ||
 320            (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
 321                /* FIXME: what about aggregated packets ? */
 322                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 323                           "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
 324                           (forw_packet->own ? "Sending own" : "Forwarding"),
 325                           batadv_ogm_packet->orig,
 326                           ntohl(batadv_ogm_packet->seqno),
 327                           batadv_ogm_packet->header.ttl,
 328                           forw_packet->if_incoming->net_dev->name,
 329                           forw_packet->if_incoming->net_dev->dev_addr);
 330
 331                /* skb is only used once and than forw_packet is free'd */
 332                batadv_send_skb_packet(forw_packet->skb,
 333                                       forw_packet->if_incoming,
 334                                       batadv_broadcast_addr);
 335                forw_packet->skb = NULL;
 336
 337                goto out;
 338        }
 339
 340        /* broadcast on every interface */
 341        rcu_read_lock();
 342        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
 343                if (hard_iface->soft_iface != soft_iface)
 344                        continue;
 345
 346                batadv_iv_ogm_send_to_if(forw_packet, hard_iface);
 347        }
 348        rcu_read_unlock();
 349
 350out:
 351        if (primary_if)
 352                batadv_hardif_free_ref(primary_if);
 353}
 354
 355/* return true if new_packet can be aggregated with forw_packet */
 356static bool
 357batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
 358                            struct batadv_priv *bat_priv,
 359                            int packet_len, unsigned long send_time,
 360                            bool directlink,
 361                            const struct batadv_hard_iface *if_incoming,
 362                            const struct batadv_forw_packet *forw_packet)
 363{
 364        struct batadv_ogm_packet *batadv_ogm_packet;
 365        int aggregated_bytes = forw_packet->packet_len + packet_len;
 366        struct batadv_hard_iface *primary_if = NULL;
 367        bool res = false;
 368        unsigned long aggregation_end_time;
 369
 370        batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
 371        aggregation_end_time = send_time;
 372        aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
 373
 374        /* we can aggregate the current packet to this aggregated packet
 375         * if:
 376         *
 377         * - the send time is within our MAX_AGGREGATION_MS time
 378         * - the resulting packet wont be bigger than
 379         *   MAX_AGGREGATION_BYTES
 380         */
 381        if (time_before(send_time, forw_packet->send_time) &&
 382            time_after_eq(aggregation_end_time, forw_packet->send_time) &&
 383            (aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) {
 384                /* check aggregation compatibility
 385                 * -> direct link packets are broadcasted on
 386                 *    their interface only
 387                 * -> aggregate packet if the current packet is
 388                 *    a "global" packet as well as the base
 389                 *    packet
 390                 */
 391                primary_if = batadv_primary_if_get_selected(bat_priv);
 392                if (!primary_if)
 393                        goto out;
 394
 395                /* packets without direct link flag and high TTL
 396                 * are flooded through the net
 397                 */
 398                if ((!directlink) &&
 399                    (!(batadv_ogm_packet->flags & BATADV_DIRECTLINK)) &&
 400                    (batadv_ogm_packet->header.ttl != 1) &&
 401
 402                    /* own packets originating non-primary
 403                     * interfaces leave only that interface
 404                     */
 405                    ((!forw_packet->own) ||
 406                     (forw_packet->if_incoming == primary_if))) {
 407                        res = true;
 408                        goto out;
 409                }
 410
 411                /* if the incoming packet is sent via this one
 412                 * interface only - we still can aggregate
 413                 */
 414                if ((directlink) &&
 415                    (new_bat_ogm_packet->header.ttl == 1) &&
 416                    (forw_packet->if_incoming == if_incoming) &&
 417
 418                    /* packets from direct neighbors or
 419                     * own secondary interface packets
 420                     * (= secondary interface packets in general)
 421                     */
 422                    (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
 423                     (forw_packet->own &&
 424                      forw_packet->if_incoming != primary_if))) {
 425                        res = true;
 426                        goto out;
 427                }
 428        }
 429
 430out:
 431        if (primary_if)
 432                batadv_hardif_free_ref(primary_if);
 433        return res;
 434}
 435
 436/* create a new aggregated packet and add this packet to it */
 437static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
 438                                        int packet_len, unsigned long send_time,
 439                                        bool direct_link,
 440                                        struct batadv_hard_iface *if_incoming,
 441                                        int own_packet)
 442{
 443        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 444        struct batadv_forw_packet *forw_packet_aggr;
 445        unsigned char *skb_buff;
 446        unsigned int skb_size;
 447
 448        if (!atomic_inc_not_zero(&if_incoming->refcount))
 449                return;
 450
 451        /* own packet should always be scheduled */
 452        if (!own_packet) {
 453                if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
 454                        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 455                                   "batman packet queue full\n");
 456                        goto out;
 457                }
 458        }
 459
 460        forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
 461        if (!forw_packet_aggr) {
 462                if (!own_packet)
 463                        atomic_inc(&bat_priv->batman_queue_left);
 464                goto out;
 465        }
 466
 467        if ((atomic_read(&bat_priv->aggregated_ogms)) &&
 468            (packet_len < BATADV_MAX_AGGREGATION_BYTES))
 469                skb_size = BATADV_MAX_AGGREGATION_BYTES;
 470        else
 471                skb_size = packet_len;
 472
 473        skb_size += ETH_HLEN;
 474
 475        forw_packet_aggr->skb = netdev_alloc_skb_ip_align(NULL, skb_size);
 476        if (!forw_packet_aggr->skb) {
 477                if (!own_packet)
 478                        atomic_inc(&bat_priv->batman_queue_left);
 479                kfree(forw_packet_aggr);
 480                goto out;
 481        }
 482        forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
 483        skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
 484
 485        skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
 486        forw_packet_aggr->packet_len = packet_len;
 487        memcpy(skb_buff, packet_buff, packet_len);
 488
 489        forw_packet_aggr->own = own_packet;
 490        forw_packet_aggr->if_incoming = if_incoming;
 491        forw_packet_aggr->num_packets = 0;
 492        forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
 493        forw_packet_aggr->send_time = send_time;
 494
 495        /* save packet direct link flag status */
 496        if (direct_link)
 497                forw_packet_aggr->direct_link_flags |= 1;
 498
 499        /* add new packet to packet list */
 500        spin_lock_bh(&bat_priv->forw_bat_list_lock);
 501        hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
 502        spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 503
 504        /* start timer for this packet */
 505        INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
 506                          batadv_send_outstanding_bat_ogm_packet);
 507        queue_delayed_work(batadv_event_workqueue,
 508                           &forw_packet_aggr->delayed_work,
 509                           send_time - jiffies);
 510
 511        return;
 512out:
 513        batadv_hardif_free_ref(if_incoming);
 514}
 515
 516/* aggregate a new packet into the existing ogm packet */
 517static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
 518                                    const unsigned char *packet_buff,
 519                                    int packet_len, bool direct_link)
 520{
 521        unsigned char *skb_buff;
 522        unsigned long new_direct_link_flag;
 523
 524        skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
 525        memcpy(skb_buff, packet_buff, packet_len);
 526        forw_packet_aggr->packet_len += packet_len;
 527        forw_packet_aggr->num_packets++;
 528
 529        /* save packet direct link flag status */
 530        if (direct_link) {
 531                new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
 532                forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
 533        }
 534}
 535
 536static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
 537                                    unsigned char *packet_buff,
 538                                    int packet_len,
 539                                    struct batadv_hard_iface *if_incoming,
 540                                    int own_packet, unsigned long send_time)
 541{
 542        /* _aggr -> pointer to the packet we want to aggregate with
 543         * _pos -> pointer to the position in the queue
 544         */
 545        struct batadv_forw_packet *forw_packet_aggr = NULL;
 546        struct batadv_forw_packet *forw_packet_pos = NULL;
 547        struct batadv_ogm_packet *batadv_ogm_packet;
 548        bool direct_link;
 549        unsigned long max_aggregation_jiffies;
 550
 551        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
 552        direct_link = batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0;
 553        max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
 554
 555        /* find position for the packet in the forward queue */
 556        spin_lock_bh(&bat_priv->forw_bat_list_lock);
 557        /* own packets are not to be aggregated */
 558        if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
 559                hlist_for_each_entry(forw_packet_pos,
 560                                     &bat_priv->forw_bat_list, list) {
 561                        if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
 562                                                        bat_priv, packet_len,
 563                                                        send_time, direct_link,
 564                                                        if_incoming,
 565                                                        forw_packet_pos)) {
 566                                forw_packet_aggr = forw_packet_pos;
 567                                break;
 568                        }
 569                }
 570        }
 571
 572        /* nothing to aggregate with - either aggregation disabled or no
 573         * suitable aggregation packet found
 574         */
 575        if (!forw_packet_aggr) {
 576                /* the following section can run without the lock */
 577                spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 578
 579                /* if we could not aggregate this packet with one of the others
 580                 * we hold it back for a while, so that it might be aggregated
 581                 * later on
 582                 */
 583                if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
 584                        send_time += max_aggregation_jiffies;
 585
 586                batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
 587                                            send_time, direct_link,
 588                                            if_incoming, own_packet);
 589        } else {
 590                batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
 591                                        packet_len, direct_link);
 592                spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 593        }
 594}
 595
 596static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
 597                                  const struct ethhdr *ethhdr,
 598                                  struct batadv_ogm_packet *batadv_ogm_packet,
 599                                  bool is_single_hop_neigh,
 600                                  bool is_from_best_next_hop,
 601                                  struct batadv_hard_iface *if_incoming)
 602{
 603        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 604        uint8_t tt_num_changes;
 605
 606        if (batadv_ogm_packet->header.ttl <= 1) {
 607                batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
 608                return;
 609        }
 610
 611        if (!is_from_best_next_hop) {
 612                /* Mark the forwarded packet when it is not coming from our
 613                 * best next hop. We still need to forward the packet for our
 614                 * neighbor link quality detection to work in case the packet
 615                 * originated from a single hop neighbor. Otherwise we can
 616                 * simply drop the ogm.
 617                 */
 618                if (is_single_hop_neigh)
 619                        batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
 620                else
 621                        return;
 622        }
 623
 624        tt_num_changes = batadv_ogm_packet->tt_num_changes;
 625
 626        batadv_ogm_packet->header.ttl--;
 627        memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
 628
 629        /* apply hop penalty */
 630        batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
 631                                                   bat_priv);
 632
 633        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 634                   "Forwarding packet: tq: %i, ttl: %i\n",
 635                   batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl);
 636
 637        /* switch of primaries first hop flag when forwarding */
 638        batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP;
 639        if (is_single_hop_neigh)
 640                batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
 641        else
 642                batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
 643
 644        batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
 645                                BATADV_OGM_HLEN + batadv_tt_len(tt_num_changes),
 646                                if_incoming, 0, batadv_iv_ogm_fwd_send_time());
 647}
 648
 649/**
 650 * batadv_iv_ogm_slide_own_bcast_window - bitshift own OGM broadcast windows for
 651 * the given interface
 652 * @hard_iface: the interface for which the windows have to be shifted
 653 */
 654static void
 655batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
 656{
 657        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 658        struct batadv_hashtable *hash = bat_priv->orig_hash;
 659        struct hlist_head *head;
 660        struct batadv_orig_node *orig_node;
 661        unsigned long *word;
 662        uint32_t i;
 663        size_t word_index;
 664        uint8_t *w;
 665
 666        for (i = 0; i < hash->size; i++) {
 667                head = &hash->table[i];
 668
 669                rcu_read_lock();
 670                hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
 671                        spin_lock_bh(&orig_node->ogm_cnt_lock);
 672                        word_index = hard_iface->if_num * BATADV_NUM_WORDS;
 673                        word = &(orig_node->bcast_own[word_index]);
 674
 675                        batadv_bit_get_packet(bat_priv, word, 1, 0);
 676                        w = &orig_node->bcast_own_sum[hard_iface->if_num];
 677                        *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
 678                        spin_unlock_bh(&orig_node->ogm_cnt_lock);
 679                }
 680                rcu_read_unlock();
 681        }
 682}
 683
 684static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
 685{
 686        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 687        unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
 688        struct batadv_ogm_packet *batadv_ogm_packet;
 689        struct batadv_hard_iface *primary_if;
 690        int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
 691        int vis_server, tt_num_changes = 0;
 692        uint32_t seqno;
 693        uint8_t bandwidth;
 694
 695        vis_server = atomic_read(&bat_priv->vis_mode);
 696        primary_if = batadv_primary_if_get_selected(bat_priv);
 697
 698        if (hard_iface == primary_if)
 699                tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff,
 700                                                       ogm_buff_len,
 701                                                       BATADV_OGM_HLEN);
 702
 703        batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
 704
 705        /* change sequence number to network order */
 706        seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
 707        batadv_ogm_packet->seqno = htonl(seqno);
 708        atomic_inc(&hard_iface->bat_iv.ogm_seqno);
 709
 710        batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
 711        batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
 712        if (tt_num_changes >= 0)
 713                batadv_ogm_packet->tt_num_changes = tt_num_changes;
 714
 715        if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC)
 716                batadv_ogm_packet->flags |= BATADV_VIS_SERVER;
 717        else
 718                batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
 719
 720        if (hard_iface == primary_if &&
 721            atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
 722                bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
 723                batadv_ogm_packet->gw_flags = bandwidth;
 724        } else {
 725                batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
 726        }
 727
 728        batadv_iv_ogm_slide_own_bcast_window(hard_iface);
 729        batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
 730                                hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
 731                                batadv_iv_ogm_emit_send_time(bat_priv));
 732
 733        if (primary_if)
 734                batadv_hardif_free_ref(primary_if);
 735}
 736
 737static void
 738batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
 739                          struct batadv_orig_node *orig_node,
 740                          const struct ethhdr *ethhdr,
 741                          const struct batadv_ogm_packet *batadv_ogm_packet,
 742                          struct batadv_hard_iface *if_incoming,
 743                          const unsigned char *tt_buff,
 744                          enum batadv_dup_status dup_status)
 745{
 746        struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
 747        struct batadv_neigh_node *router = NULL;
 748        struct batadv_orig_node *orig_node_tmp;
 749        int if_num;
 750        uint8_t sum_orig, sum_neigh;
 751        uint8_t *neigh_addr;
 752        uint8_t tq_avg;
 753
 754        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 755                   "update_originator(): Searching and updating originator entry of received packet\n");
 756
 757        rcu_read_lock();
 758        hlist_for_each_entry_rcu(tmp_neigh_node,
 759                                 &orig_node->neigh_list, list) {
 760                neigh_addr = tmp_neigh_node->addr;
 761                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
 762                    tmp_neigh_node->if_incoming == if_incoming &&
 763                    atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
 764                        if (WARN(neigh_node, "too many matching neigh_nodes"))
 765                                batadv_neigh_node_free_ref(neigh_node);
 766                        neigh_node = tmp_neigh_node;
 767                        continue;
 768                }
 769
 770                if (dup_status != BATADV_NO_DUP)
 771                        continue;
 772
 773                spin_lock_bh(&tmp_neigh_node->lq_update_lock);
 774                batadv_ring_buffer_set(tmp_neigh_node->tq_recv,
 775                                       &tmp_neigh_node->tq_index, 0);
 776                tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv);
 777                tmp_neigh_node->tq_avg = tq_avg;
 778                spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
 779        }
 780
 781        if (!neigh_node) {
 782                struct batadv_orig_node *orig_tmp;
 783
 784                orig_tmp = batadv_get_orig_node(bat_priv, ethhdr->h_source);
 785                if (!orig_tmp)
 786                        goto unlock;
 787
 788                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
 789                                                     ethhdr->h_source,
 790                                                     orig_node, orig_tmp);
 791
 792                batadv_orig_node_free_ref(orig_tmp);
 793                if (!neigh_node)
 794                        goto unlock;
 795        } else
 796                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 797                           "Updating existing last-hop neighbor of originator\n");
 798
 799        rcu_read_unlock();
 800
 801        orig_node->flags = batadv_ogm_packet->flags;
 802        neigh_node->last_seen = jiffies;
 803
 804        spin_lock_bh(&neigh_node->lq_update_lock);
 805        batadv_ring_buffer_set(neigh_node->tq_recv,
 806                               &neigh_node->tq_index,
 807                               batadv_ogm_packet->tq);
 808        neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv);
 809        spin_unlock_bh(&neigh_node->lq_update_lock);
 810
 811        if (dup_status == BATADV_NO_DUP) {
 812                orig_node->last_ttl = batadv_ogm_packet->header.ttl;
 813                neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
 814        }
 815
 816        batadv_bonding_candidate_add(orig_node, neigh_node);
 817
 818        /* if this neighbor already is our next hop there is nothing
 819         * to change
 820         */
 821        router = batadv_orig_node_get_router(orig_node);
 822        if (router == neigh_node)
 823                goto update_tt;
 824
 825        /* if this neighbor does not offer a better TQ we won't consider it */
 826        if (router && (router->tq_avg > neigh_node->tq_avg))
 827                goto update_tt;
 828
 829        /* if the TQ is the same and the link not more symmetric we
 830         * won't consider it either
 831         */
 832        if (router && (neigh_node->tq_avg == router->tq_avg)) {
 833                orig_node_tmp = router->orig_node;
 834                spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
 835                if_num = router->if_incoming->if_num;
 836                sum_orig = orig_node_tmp->bcast_own_sum[if_num];
 837                spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
 838
 839                orig_node_tmp = neigh_node->orig_node;
 840                spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
 841                if_num = neigh_node->if_incoming->if_num;
 842                sum_neigh = orig_node_tmp->bcast_own_sum[if_num];
 843                spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
 844
 845                if (sum_orig >= sum_neigh)
 846                        goto update_tt;
 847        }
 848
 849        batadv_update_route(bat_priv, orig_node, neigh_node);
 850
 851update_tt:
 852        /* I have to check for transtable changes only if the OGM has been
 853         * sent through a primary interface
 854         */
 855        if (((batadv_ogm_packet->orig != ethhdr->h_source) &&
 856             (batadv_ogm_packet->header.ttl > 2)) ||
 857            (batadv_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP))
 858                batadv_tt_update_orig(bat_priv, orig_node, tt_buff,
 859                                      batadv_ogm_packet->tt_num_changes,
 860                                      batadv_ogm_packet->ttvn,
 861                                      ntohs(batadv_ogm_packet->tt_crc));
 862
 863        if (orig_node->gw_flags != batadv_ogm_packet->gw_flags)
 864                batadv_gw_node_update(bat_priv, orig_node,
 865                                      batadv_ogm_packet->gw_flags);
 866
 867        orig_node->gw_flags = batadv_ogm_packet->gw_flags;
 868
 869        /* restart gateway selection if fast or late switching was enabled */
 870        if ((orig_node->gw_flags) &&
 871            (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
 872            (atomic_read(&bat_priv->gw_sel_class) > 2))
 873                batadv_gw_check_election(bat_priv, orig_node);
 874
 875        goto out;
 876
 877unlock:
 878        rcu_read_unlock();
 879out:
 880        if (neigh_node)
 881                batadv_neigh_node_free_ref(neigh_node);
 882        if (router)
 883                batadv_neigh_node_free_ref(router);
 884}
 885
 886static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
 887                                 struct batadv_orig_node *orig_neigh_node,
 888                                 struct batadv_ogm_packet *batadv_ogm_packet,
 889                                 struct batadv_hard_iface *if_incoming)
 890{
 891        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 892        struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
 893        uint8_t total_count;
 894        uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
 895        unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
 896        int tq_asym_penalty, inv_asym_penalty, ret = 0;
 897        unsigned int combined_tq;
 898
 899        /* find corresponding one hop neighbor */
 900        rcu_read_lock();
 901        hlist_for_each_entry_rcu(tmp_neigh_node,
 902                                 &orig_neigh_node->neigh_list, list) {
 903                if (!batadv_compare_eth(tmp_neigh_node->addr,
 904                                        orig_neigh_node->orig))
 905                        continue;
 906
 907                if (tmp_neigh_node->if_incoming != if_incoming)
 908                        continue;
 909
 910                if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
 911                        continue;
 912
 913                neigh_node = tmp_neigh_node;
 914                break;
 915        }
 916        rcu_read_unlock();
 917
 918        if (!neigh_node)
 919                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
 920                                                     orig_neigh_node->orig,
 921                                                     orig_neigh_node,
 922                                                     orig_neigh_node);
 923
 924        if (!neigh_node)
 925                goto out;
 926
 927        /* if orig_node is direct neighbor update neigh_node last_seen */
 928        if (orig_node == orig_neigh_node)
 929                neigh_node->last_seen = jiffies;
 930
 931        orig_node->last_seen = jiffies;
 932
 933        /* find packet count of corresponding one hop neighbor */
 934        spin_lock_bh(&orig_node->ogm_cnt_lock);
 935        orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
 936        neigh_rq_count = neigh_node->real_packet_count;
 937        spin_unlock_bh(&orig_node->ogm_cnt_lock);
 938
 939        /* pay attention to not get a value bigger than 100 % */
 940        if (orig_eq_count > neigh_rq_count)
 941                total_count = neigh_rq_count;
 942        else
 943                total_count = orig_eq_count;
 944
 945        /* if we have too few packets (too less data) we set tq_own to zero
 946         * if we receive too few packets it is not considered bidirectional
 947         */
 948        if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
 949            neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
 950                tq_own = 0;
 951        else
 952                /* neigh_node->real_packet_count is never zero as we
 953                 * only purge old information when getting new
 954                 * information
 955                 */
 956                tq_own = (BATADV_TQ_MAX_VALUE * total_count) /  neigh_rq_count;
 957
 958        /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
 959         * affect the nearly-symmetric links only a little, but
 960         * punishes asymmetric links more.  This will give a value
 961         * between 0 and TQ_MAX_VALUE
 962         */
 963        neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
 964        neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv;
 965        neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE *
 966                            BATADV_TQ_LOCAL_WINDOW_SIZE *
 967                            BATADV_TQ_LOCAL_WINDOW_SIZE;
 968        inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
 969        inv_asym_penalty /= neigh_rq_max_cube;
 970        tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
 971
 972        combined_tq = batadv_ogm_packet->tq * tq_own * tq_asym_penalty;
 973        combined_tq /= BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE;
 974        batadv_ogm_packet->tq = combined_tq;
 975
 976        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 977                   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
 978                   orig_node->orig, orig_neigh_node->orig, total_count,
 979                   neigh_rq_count, tq_own,
 980                   tq_asym_penalty, batadv_ogm_packet->tq);
 981
 982        /* if link has the minimum required transmission quality
 983         * consider it bidirectional
 984         */
 985        if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
 986                ret = 1;
 987
 988out:
 989        if (neigh_node)
 990                batadv_neigh_node_free_ref(neigh_node);
 991        return ret;
 992}
 993
 994/**
 995 * batadv_iv_ogm_update_seqnos -  process a batman packet for all interfaces,
 996 *  adjust the sequence number and find out whether it is a duplicate
 997 * @ethhdr: ethernet header of the packet
 998 * @batadv_ogm_packet: OGM packet to be considered
 999 * @if_incoming: interface on which the OGM packet was received
1000 *
1001 * Returns duplicate status as enum batadv_dup_status
1002 */
1003static enum batadv_dup_status
1004batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1005                            const struct batadv_ogm_packet *batadv_ogm_packet,
1006                            const struct batadv_hard_iface *if_incoming)
1007{
1008        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1009        struct batadv_orig_node *orig_node;
1010        struct batadv_neigh_node *tmp_neigh_node;
1011        int is_dup;
1012        int32_t seq_diff;
1013        int need_update = 0;
1014        int set_mark;
1015        enum batadv_dup_status ret = BATADV_NO_DUP;
1016        uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
1017        uint8_t *neigh_addr;
1018        uint8_t packet_count;
1019
1020        orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
1021        if (!orig_node)
1022                return BATADV_NO_DUP;
1023
1024        spin_lock_bh(&orig_node->ogm_cnt_lock);
1025        seq_diff = seqno - orig_node->last_real_seqno;
1026
1027        /* signalize caller that the packet is to be dropped. */
1028        if (!hlist_empty(&orig_node->neigh_list) &&
1029            batadv_window_protected(bat_priv, seq_diff,
1030                                    &orig_node->batman_seqno_reset)) {
1031                ret = BATADV_PROTECTED;
1032                goto out;
1033        }
1034
1035        rcu_read_lock();
1036        hlist_for_each_entry_rcu(tmp_neigh_node,
1037                                 &orig_node->neigh_list, list) {
1038                neigh_addr = tmp_neigh_node->addr;
1039                is_dup = batadv_test_bit(tmp_neigh_node->real_bits,
1040                                         orig_node->last_real_seqno,
1041                                         seqno);
1042
1043                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1044                    tmp_neigh_node->if_incoming == if_incoming) {
1045                        set_mark = 1;
1046                        if (is_dup)
1047                                ret = BATADV_NEIGH_DUP;
1048                } else {
1049                        set_mark = 0;
1050                        if (is_dup && (ret != BATADV_NEIGH_DUP))
1051                                ret = BATADV_ORIG_DUP;
1052                }
1053
1054                /* if the window moved, set the update flag. */
1055                need_update |= batadv_bit_get_packet(bat_priv,
1056                                                     tmp_neigh_node->real_bits,
1057                                                     seq_diff, set_mark);
1058
1059                packet_count = bitmap_weight(tmp_neigh_node->real_bits,
1060                                             BATADV_TQ_LOCAL_WINDOW_SIZE);
1061                tmp_neigh_node->real_packet_count = packet_count;
1062        }
1063        rcu_read_unlock();
1064
1065        if (need_update) {
1066                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1067                           "updating last_seqno: old %u, new %u\n",
1068                           orig_node->last_real_seqno, seqno);
1069                orig_node->last_real_seqno = seqno;
1070        }
1071
1072out:
1073        spin_unlock_bh(&orig_node->ogm_cnt_lock);
1074        batadv_orig_node_free_ref(orig_node);
1075        return ret;
1076}
1077
1078static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1079                                  struct batadv_ogm_packet *batadv_ogm_packet,
1080                                  const unsigned char *tt_buff,
1081                                  struct batadv_hard_iface *if_incoming)
1082{
1083        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1084        struct batadv_hard_iface *hard_iface;
1085        struct batadv_orig_node *orig_neigh_node, *orig_node;
1086        struct batadv_neigh_node *router = NULL, *router_router = NULL;
1087        struct batadv_neigh_node *orig_neigh_router = NULL;
1088        int has_directlink_flag;
1089        int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
1090        int is_bidirect;
1091        bool is_single_hop_neigh = false;
1092        bool is_from_best_next_hop = false;
1093        int sameseq, similar_ttl;
1094        enum batadv_dup_status dup_status;
1095        uint32_t if_incoming_seqno;
1096        uint8_t *prev_sender;
1097
1098        /* Silently drop when the batman packet is actually not a
1099         * correct packet.
1100         *
1101         * This might happen if a packet is padded (e.g. Ethernet has a
1102         * minimum frame length of 64 byte) and the aggregation interprets
1103         * it as an additional length.
1104         *
1105         * TODO: A more sane solution would be to have a bit in the
1106         * batadv_ogm_packet to detect whether the packet is the last
1107         * packet in an aggregation.  Here we expect that the padding
1108         * is always zero (or not 0x01)
1109         */
1110        if (batadv_ogm_packet->header.packet_type != BATADV_IV_OGM)
1111                return;
1112
1113        /* could be changed by schedule_own_packet() */
1114        if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1115
1116        if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
1117                has_directlink_flag = 1;
1118        else
1119                has_directlink_flag = 0;
1120
1121        if (batadv_compare_eth(ethhdr->h_source, batadv_ogm_packet->orig))
1122                is_single_hop_neigh = true;
1123
1124        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1125                   "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %#.4x, changes %u, tq %d, TTL %d, V %d, IDF %d)\n",
1126                   ethhdr->h_source, if_incoming->net_dev->name,
1127                   if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
1128                   batadv_ogm_packet->prev_sender,
1129                   ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->ttvn,
1130                   ntohs(batadv_ogm_packet->tt_crc),
1131                   batadv_ogm_packet->tt_num_changes, batadv_ogm_packet->tq,
1132                   batadv_ogm_packet->header.ttl,
1133                   batadv_ogm_packet->header.version, has_directlink_flag);
1134
1135        rcu_read_lock();
1136        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1137                if (hard_iface->if_status != BATADV_IF_ACTIVE)
1138                        continue;
1139
1140                if (hard_iface->soft_iface != if_incoming->soft_iface)
1141                        continue;
1142
1143                if (batadv_compare_eth(ethhdr->h_source,
1144                                       hard_iface->net_dev->dev_addr))
1145                        is_my_addr = 1;
1146
1147                if (batadv_compare_eth(batadv_ogm_packet->orig,
1148                                       hard_iface->net_dev->dev_addr))
1149                        is_my_orig = 1;
1150
1151                if (batadv_compare_eth(batadv_ogm_packet->prev_sender,
1152                                       hard_iface->net_dev->dev_addr))
1153                        is_my_oldorig = 1;
1154        }
1155        rcu_read_unlock();
1156
1157        if (is_my_addr) {
1158                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1159                           "Drop packet: received my own broadcast (sender: %pM)\n",
1160                           ethhdr->h_source);
1161                return;
1162        }
1163
1164        if (is_my_orig) {
1165                unsigned long *word;
1166                int offset;
1167                int32_t bit_pos;
1168                int16_t if_num;
1169                uint8_t *weight;
1170
1171                orig_neigh_node = batadv_get_orig_node(bat_priv,
1172                                                       ethhdr->h_source);
1173                if (!orig_neigh_node)
1174                        return;
1175
1176                /* neighbor has to indicate direct link and it has to
1177                 * come via the corresponding interface
1178                 * save packet seqno for bidirectional check
1179                 */
1180                if (has_directlink_flag &&
1181                    batadv_compare_eth(if_incoming->net_dev->dev_addr,
1182                                       batadv_ogm_packet->orig)) {
1183                        if_num = if_incoming->if_num;
1184                        offset = if_num * BATADV_NUM_WORDS;
1185
1186                        spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
1187                        word = &(orig_neigh_node->bcast_own[offset]);
1188                        bit_pos = if_incoming_seqno - 2;
1189                        bit_pos -= ntohl(batadv_ogm_packet->seqno);
1190                        batadv_set_bit(word, bit_pos);
1191                        weight = &orig_neigh_node->bcast_own_sum[if_num];
1192                        *weight = bitmap_weight(word,
1193                                                BATADV_TQ_LOCAL_WINDOW_SIZE);
1194                        spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
1195                }
1196
1197                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1198                           "Drop packet: originator packet from myself (via neighbor)\n");
1199                batadv_orig_node_free_ref(orig_neigh_node);
1200                return;
1201        }
1202
1203        if (is_my_oldorig) {
1204                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1205                           "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1206                           ethhdr->h_source);
1207                return;
1208        }
1209
1210        if (batadv_ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1211                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1212                           "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1213                           ethhdr->h_source);
1214                return;
1215        }
1216
1217        orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
1218        if (!orig_node)
1219                return;
1220
1221        dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
1222                                                 if_incoming);
1223
1224        if (dup_status == BATADV_PROTECTED) {
1225                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1226                           "Drop packet: packet within seqno protection time (sender: %pM)\n",
1227                           ethhdr->h_source);
1228                goto out;
1229        }
1230
1231        if (batadv_ogm_packet->tq == 0) {
1232                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1233                           "Drop packet: originator packet with tq equal 0\n");
1234                goto out;
1235        }
1236
1237        router = batadv_orig_node_get_router(orig_node);
1238        if (router)
1239                router_router = batadv_orig_node_get_router(router->orig_node);
1240
1241        if ((router && router->tq_avg != 0) &&
1242            (batadv_compare_eth(router->addr, ethhdr->h_source)))
1243                is_from_best_next_hop = true;
1244
1245        prev_sender = batadv_ogm_packet->prev_sender;
1246        /* avoid temporary routing loops */
1247        if (router && router_router &&
1248            (batadv_compare_eth(router->addr, prev_sender)) &&
1249            !(batadv_compare_eth(batadv_ogm_packet->orig, prev_sender)) &&
1250            (batadv_compare_eth(router->addr, router_router->addr))) {
1251                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1252                           "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
1253                           ethhdr->h_source);
1254                goto out;
1255        }
1256
1257        /* if sender is a direct neighbor the sender mac equals
1258         * originator mac
1259         */
1260        if (is_single_hop_neigh)
1261                orig_neigh_node = orig_node;
1262        else
1263                orig_neigh_node = batadv_get_orig_node(bat_priv,
1264                                                       ethhdr->h_source);
1265
1266        if (!orig_neigh_node)
1267                goto out;
1268
1269        /* Update nc_nodes of the originator */
1270        batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
1271                                 batadv_ogm_packet, is_single_hop_neigh);
1272
1273        orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node);
1274
1275        /* drop packet if sender is not a direct neighbor and if we
1276         * don't route towards it
1277         */
1278        if (!is_single_hop_neigh && (!orig_neigh_router)) {
1279                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1280                           "Drop packet: OGM via unknown neighbor!\n");
1281                goto out_neigh;
1282        }
1283
1284        is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1285                                            batadv_ogm_packet, if_incoming);
1286
1287        batadv_bonding_save_primary(orig_node, orig_neigh_node,
1288                                    batadv_ogm_packet);
1289
1290        /* update ranking if it is not a duplicate or has the same
1291         * seqno and similar ttl as the non-duplicate
1292         */
1293        sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
1294        similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
1295        if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
1296                            (sameseq && similar_ttl)))
1297                batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
1298                                          batadv_ogm_packet, if_incoming,
1299                                          tt_buff, dup_status);
1300
1301        /* is single hop (direct) neighbor */
1302        if (is_single_hop_neigh) {
1303                /* mark direct link on incoming interface */
1304                batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet,
1305                                      is_single_hop_neigh,
1306                                      is_from_best_next_hop, if_incoming);
1307
1308                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1309                           "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1310                goto out_neigh;
1311        }
1312
1313        /* multihop originator */
1314        if (!is_bidirect) {
1315                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1316                           "Drop packet: not received via bidirectional link\n");
1317                goto out_neigh;
1318        }
1319
1320        if (dup_status == BATADV_NEIGH_DUP) {
1321                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1322                           "Drop packet: duplicate packet received\n");
1323                goto out_neigh;
1324        }
1325
1326        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1327                   "Forwarding packet: rebroadcast originator packet\n");
1328        batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet,
1329                              is_single_hop_neigh, is_from_best_next_hop,
1330                              if_incoming);
1331
1332out_neigh:
1333        if ((orig_neigh_node) && (!is_single_hop_neigh))
1334                batadv_orig_node_free_ref(orig_neigh_node);
1335out:
1336        if (router)
1337                batadv_neigh_node_free_ref(router);
1338        if (router_router)
1339                batadv_neigh_node_free_ref(router_router);
1340        if (orig_neigh_router)
1341                batadv_neigh_node_free_ref(orig_neigh_router);
1342
1343        batadv_orig_node_free_ref(orig_node);
1344}
1345
1346static int batadv_iv_ogm_receive(struct sk_buff *skb,
1347                                 struct batadv_hard_iface *if_incoming)
1348{
1349        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1350        struct batadv_ogm_packet *batadv_ogm_packet;
1351        struct ethhdr *ethhdr;
1352        int buff_pos = 0, packet_len;
1353        unsigned char *tt_buff, *packet_buff;
1354        bool ret;
1355        uint8_t *packet_pos;
1356
1357        ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1358        if (!ret)
1359                return NET_RX_DROP;
1360
1361        /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
1362         * that does not have B.A.T.M.A.N. IV enabled ?
1363         */
1364        if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit)
1365                return NET_RX_DROP;
1366
1367        batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
1368        batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1369                           skb->len + ETH_HLEN);
1370
1371        packet_len = skb_headlen(skb);
1372        ethhdr = eth_hdr(skb);
1373        packet_buff = skb->data;
1374        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
1375
1376        /* unpack the aggregated packets and process them one by one */
1377        while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
1378                                         batadv_ogm_packet->tt_num_changes)) {
1379                tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
1380
1381                batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
1382                                      if_incoming);
1383
1384                buff_pos += BATADV_OGM_HLEN;
1385                buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
1386
1387                packet_pos = packet_buff + buff_pos;
1388                batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1389        }
1390
1391        kfree_skb(skb);
1392        return NET_RX_SUCCESS;
1393}
1394
1395static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
1396        .name = "BATMAN_IV",
1397        .bat_iface_enable = batadv_iv_ogm_iface_enable,
1398        .bat_iface_disable = batadv_iv_ogm_iface_disable,
1399        .bat_iface_update_mac = batadv_iv_ogm_iface_update_mac,
1400        .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set,
1401        .bat_ogm_schedule = batadv_iv_ogm_schedule,
1402        .bat_ogm_emit = batadv_iv_ogm_emit,
1403};
1404
1405int __init batadv_iv_init(void)
1406{
1407        int ret;
1408
1409        /* batman originator packet */
1410        ret = batadv_recv_handler_register(BATADV_IV_OGM,
1411                                           batadv_iv_ogm_receive);
1412        if (ret < 0)
1413                goto out;
1414
1415        ret = batadv_algo_register(&batadv_batman_iv);
1416        if (ret < 0)
1417                goto handler_unregister;
1418
1419        goto out;
1420
1421handler_unregister:
1422        batadv_recv_handler_unregister(BATADV_IV_OGM);
1423out:
1424        return ret;
1425}
1426