cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bat_iv_ogm.c (75074B)


      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/container_of.h>
     17#include <linux/errno.h>
     18#include <linux/etherdevice.h>
     19#include <linux/gfp.h>
     20#include <linux/if_ether.h>
     21#include <linux/init.h>
     22#include <linux/jiffies.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}