bat_iv_ogm.c 59.5 KB
Newer Older
1
/* Copyright (C) 2007-2015 B.A.T.M.A.N. contributors:
2 3 4 5 6 7 8 9 10 11 12 13 14
 *
 * Marek Lindner, Simon Wunderlich
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 17 18 19 20 21 22 23 24 25
 */

#include "main.h"
#include "translation-table.h"
#include "originator.h"
#include "routing.h"
#include "gateway_common.h"
#include "gateway_client.h"
#include "hard-interface.h"
#include "send.h"
26
#include "bat_algo.h"
27
#include "network-coding.h"
28

29
/**
30
 * enum batadv_dup_status - duplicate status
31 32 33 34 35 36 37 38 39 40 41 42 43
 * @BATADV_NO_DUP: the packet is a duplicate
 * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
 *  neighbor)
 * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
 * @BATADV_PROTECTED: originator is currently protected (after reboot)
 */
enum batadv_dup_status {
	BATADV_NO_DUP = 0,
	BATADV_ORIG_DUP,
	BATADV_NEIGH_DUP,
	BATADV_PROTECTED,
};

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/**
 * batadv_ring_buffer_set - update the ring buffer with the given value
 * @lq_recv: pointer to the ring buffer
 * @lq_index: index to store the value at
 * @value: value to store in the ring buffer
 */
static void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
				   uint8_t value)
{
	lq_recv[*lq_index] = value;
	*lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
}

/**
 * batadv_ring_buffer_set - compute the average of all non-zero values stored
 * in the given ring buffer
 * @lq_recv: pointer to the ring buffer
 *
 * Returns computed average value.
 */
static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
{
	const uint8_t *ptr;
	uint16_t count = 0, i = 0, sum = 0;

	ptr = lq_recv;

	while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
		if (*ptr != 0) {
			count++;
			sum += *ptr;
		}

		i++;
		ptr++;
	}

	if (count == 0)
		return 0;

	return (uint8_t)(sum / count);
}
86

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/**
 * batadv_iv_ogm_orig_free - free the private resources allocated for this
 *  orig_node
 * @orig_node: the orig_node for which the resources have to be free'd
 */
static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
{
	kfree(orig_node->bat_iv.bcast_own);
	kfree(orig_node->bat_iv.bcast_own_sum);
}

/**
 * batadv_iv_ogm_orig_add_if - change the private structures of the orig_node to
 *  include the new hard-interface
 * @orig_node: the orig_node that has to be changed
 * @max_if_num: the current amount of interfaces
 *
 * Returns 0 on success, a negative error code otherwise.
 */
static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
				     int max_if_num)
{
	void *data_ptr;
110
	size_t old_size;
111 112 113 114 115
	int ret = -ENOMEM;

	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);

	old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS;
116 117 118
	data_ptr = kmalloc_array(max_if_num,
				 BATADV_NUM_WORDS * sizeof(unsigned long),
				 GFP_ATOMIC);
119 120 121 122 123 124 125
	if (!data_ptr)
		goto unlock;

	memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size);
	kfree(orig_node->bat_iv.bcast_own);
	orig_node->bat_iv.bcast_own = data_ptr;

126
	data_ptr = kmalloc_array(max_if_num, sizeof(uint8_t), GFP_ATOMIC);
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	if (!data_ptr) {
		kfree(orig_node->bat_iv.bcast_own);
		goto unlock;
	}

	memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
	       (max_if_num - 1) * sizeof(uint8_t));
	kfree(orig_node->bat_iv.bcast_own_sum);
	orig_node->bat_iv.bcast_own_sum = data_ptr;

	ret = 0;

unlock:
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);

	return ret;
}

/**
 * batadv_iv_ogm_orig_del_if - change the private structures of the orig_node to
 *  exclude the removed interface
 * @orig_node: the orig_node that has to be changed
 * @max_if_num: the current amount of interfaces
 * @del_if_num: the index of the interface being removed
 *
 * Returns 0 on success, a negative error code otherwise.
 */
static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
				     int max_if_num, int del_if_num)
{
	int chunk_size,  ret = -ENOMEM, if_offset;
	void *data_ptr = NULL;

	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);

	/* last interface was removed */
	if (max_if_num == 0)
		goto free_bcast_own;

	chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
167
	data_ptr = kmalloc_array(max_if_num, chunk_size, GFP_ATOMIC);
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
	if (!data_ptr)
		goto unlock;

	/* copy first part */
	memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);

	/* copy second part */
	memcpy((char *)data_ptr + del_if_num * chunk_size,
	       orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size),
	       (max_if_num - del_if_num) * chunk_size);

free_bcast_own:
	kfree(orig_node->bat_iv.bcast_own);
	orig_node->bat_iv.bcast_own = data_ptr;

	if (max_if_num == 0)
		goto free_own_sum;

186
	data_ptr = kmalloc_array(max_if_num, sizeof(uint8_t), GFP_ATOMIC);
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
	if (!data_ptr) {
		kfree(orig_node->bat_iv.bcast_own);
		goto unlock;
	}

	memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
	       del_if_num * sizeof(uint8_t));

	if_offset = (del_if_num + 1) * sizeof(uint8_t);
	memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t),
	       orig_node->bat_iv.bcast_own_sum + if_offset,
	       (max_if_num - del_if_num) * sizeof(uint8_t));

free_own_sum:
	kfree(orig_node->bat_iv.bcast_own_sum);
	orig_node->bat_iv.bcast_own_sum = data_ptr;

	ret = 0;
unlock:
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);

	return ret;
}

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
/**
 * batadv_iv_ogm_orig_get - retrieve or create (if does not exist) an originator
 * @bat_priv: the bat priv with all the soft interface information
 * @addr: mac address of the originator
 *
 * Returns the originator object corresponding to the passed mac address or NULL
 * on failure.
 * If the object does not exists it is created an initialised.
 */
static struct batadv_orig_node *
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr)
{
	struct batadv_orig_node *orig_node;
	int size, hash_added;

	orig_node = batadv_orig_hash_find(bat_priv, addr);
	if (orig_node)
		return orig_node;

	orig_node = batadv_orig_node_new(bat_priv, addr);
	if (!orig_node)
		return NULL;

	spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);

	size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
	orig_node->bat_iv.bcast_own = kzalloc(size, GFP_ATOMIC);
	if (!orig_node->bat_iv.bcast_own)
		goto free_orig_node;

	size = bat_priv->num_ifaces * sizeof(uint8_t);
	orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC);
	if (!orig_node->bat_iv.bcast_own_sum)
244
		goto free_orig_node;
245 246 247 248 249

	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
				     batadv_choose_orig, orig_node,
				     &orig_node->hash_entry);
	if (hash_added != 0)
250
		goto free_orig_node;
251 252 253 254

	return orig_node;

free_orig_node:
255 256
	/* free twice, as batadv_orig_node_new sets refcount to 2 */
	batadv_orig_node_free_ref(orig_node);
257 258 259 260 261
	batadv_orig_node_free_ref(orig_node);

	return NULL;
}

262 263 264 265
static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
			const uint8_t *neigh_addr,
			struct batadv_orig_node *orig_node,
266
			struct batadv_orig_node *orig_neigh)
267
{
268
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
269
	struct batadv_neigh_node *neigh_node, *tmp_neigh_node;
270

271
	neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node);
272 273 274
	if (!neigh_node)
		goto out;

275 276 277 278 279 280 281 282
	if (!atomic_inc_not_zero(&hard_iface->refcount)) {
		kfree(neigh_node);
		neigh_node = NULL;
		goto out;
	}

	neigh_node->orig_node = orig_neigh;
	neigh_node->if_incoming = hard_iface;
283 284

	spin_lock_bh(&orig_node->neigh_list_lock);
285 286 287 288 289 290 291 292 293
	tmp_neigh_node = batadv_neigh_node_get(orig_node, hard_iface,
					       neigh_addr);
	if (!tmp_neigh_node) {
		hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
	} else {
		kfree(neigh_node);
		batadv_hardif_free_ref(hard_iface);
		neigh_node = tmp_neigh_node;
	}
294 295
	spin_unlock_bh(&orig_node->neigh_list_lock);

296 297 298 299 300 301
	if (!tmp_neigh_node)
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Creating new neighbor %pM for orig_node %pM on interface %s\n",
			   neigh_addr, orig_node->orig,
			   hard_iface->net_dev->name);

302 303 304 305
out:
	return neigh_node;
}

306
static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
307
{
308
	struct batadv_ogm_packet *batadv_ogm_packet;
309
	unsigned char *ogm_buff;
310 311 312 313
	uint32_t random_seqno;

	/* randomize initial seqno to avoid collision */
	get_random_bytes(&random_seqno, sizeof(random_seqno));
314
	atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
315

316 317 318
	hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
	ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
	if (!ogm_buff)
319
		return -ENOMEM;
320

321 322 323
	hard_iface->bat_iv.ogm_buff = ogm_buff;

	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
324 325 326
	batadv_ogm_packet->packet_type = BATADV_IV_OGM;
	batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
	batadv_ogm_packet->ttl = 2;
327
	batadv_ogm_packet->flags = BATADV_NO_FLAGS;
328
	batadv_ogm_packet->reserved = 0;
329
	batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
330

331
	return 0;
332 333
}

334
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
335
{
336 337
	kfree(hard_iface->bat_iv.ogm_buff);
	hard_iface->bat_iv.ogm_buff = NULL;
338 339
}

340
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
341
{
342
	struct batadv_ogm_packet *batadv_ogm_packet;
343
	unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
344

345
	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
346 347 348 349
	ether_addr_copy(batadv_ogm_packet->orig,
			hard_iface->net_dev->dev_addr);
	ether_addr_copy(batadv_ogm_packet->prev_sender,
			hard_iface->net_dev->dev_addr);
350 351
}

352 353
static void
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
354
{
355
	struct batadv_ogm_packet *batadv_ogm_packet;
356
	unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
357

358
	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
359
	batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
360
	batadv_ogm_packet->ttl = BATADV_TTL;
361 362
}

363
/* when do we schedule our own ogm to be sent */
364
static unsigned long
365
batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
366
{
367 368 369
	unsigned int msecs;

	msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
370
	msecs += prandom_u32() % (2 * BATADV_JITTER);
371 372

	return jiffies + msecs_to_jiffies(msecs);
373 374 375
}

/* when do we schedule a ogm packet to be sent */
376
static unsigned long batadv_iv_ogm_fwd_send_time(void)
377
{
378
	return jiffies + msecs_to_jiffies(prandom_u32() % (BATADV_JITTER / 2));
379 380 381
}

/* apply hop penalty for a normal link */
382 383
static uint8_t batadv_hop_penalty(uint8_t tq,
				  const struct batadv_priv *bat_priv)
384 385
{
	int hop_penalty = atomic_read(&bat_priv->hop_penalty);
386 387 388 389 390 391
	int new_tq;

	new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
	new_tq /= BATADV_TQ_MAX_VALUE;

	return new_tq;
392 393
}

394
/* is there another aggregated packet here? */
395
static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
396
				     __be16 tvlv_len)
397
{
398 399
	int next_buff_pos = 0;

400
	next_buff_pos += buff_pos + BATADV_OGM_HLEN;
401
	next_buff_pos += ntohs(tvlv_len);
402 403

	return (next_buff_pos <= packet_len) &&
404
	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
405 406
}

407
/* send a batman ogm to a given interface */
408 409
static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
				     struct batadv_hard_iface *hard_iface)
410
{
411
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
412 413 414
	char *fwd_str;
	uint8_t packet_num;
	int16_t buff_pos;
415
	struct batadv_ogm_packet *batadv_ogm_packet;
416
	struct sk_buff *skb;
417
	uint8_t *packet_pos;
418

419
	if (hard_iface->if_status != BATADV_IF_ACTIVE)
420 421 422 423
		return;

	packet_num = 0;
	buff_pos = 0;
424 425
	packet_pos = forw_packet->skb->data;
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
426 427

	/* adjust all flags and log packets */
428
	while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
429
					 batadv_ogm_packet->tvlv_len)) {
430
		/* we might have aggregated direct link packets with an
431 432
		 * ordinary base packet
		 */
433 434
		if (forw_packet->direct_link_flags & BIT(packet_num) &&
		    forw_packet->if_incoming == hard_iface)
435
			batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
436
		else
437
			batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
438

439 440 441 442 443
		if (packet_num > 0 || !forw_packet->own)
			fwd_str = "Forwarding";
		else
			fwd_str = "Sending own";

444
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
445
			   "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
446
			   fwd_str, (packet_num > 0 ? "aggregated " : ""),
447 448
			   batadv_ogm_packet->orig,
			   ntohl(batadv_ogm_packet->seqno),
449
			   batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
450
			   (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
451
			    "on" : "off"),
452
			   hard_iface->net_dev->name,
453
			   hard_iface->net_dev->dev_addr);
454

455
		buff_pos += BATADV_OGM_HLEN;
456
		buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
457
		packet_num++;
458 459
		packet_pos = forw_packet->skb->data + buff_pos;
		batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
460 461 462 463
	}

	/* create clone because function is called more than once */
	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
464
	if (skb) {
465 466
		batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
		batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
467
				   skb->len + ETH_HLEN);
468
		batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
469
	}
470 471 472
}

/* send a batman ogm packet */
473
static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
474 475
{
	struct net_device *soft_iface;
476 477
	struct batadv_priv *bat_priv;
	struct batadv_hard_iface *primary_if = NULL;
478 479

	if (!forw_packet->if_incoming) {
480
		pr_err("Error - can't forward packet: incoming iface not specified\n");
481 482 483 484 485 486
		goto out;
	}

	soft_iface = forw_packet->if_incoming->soft_iface;
	bat_priv = netdev_priv(soft_iface);

487
	if (WARN_ON(!forw_packet->if_outgoing))
488 489
		goto out;

490
	if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface))
491 492
		goto out;

493
	if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
494 495
		goto out;

496 497 498
	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (!primary_if)
		goto out;
499

500 501
	/* only for one specific outgoing interface */
	batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
502 503 504

out:
	if (primary_if)
505
		batadv_hardif_free_ref(primary_if);
506 507
}

508 509 510 511 512 513 514
/**
 * batadv_iv_ogm_can_aggregate - find out if an OGM can be aggregated on an
 *  existing forward packet
 * @new_bat_ogm_packet: OGM packet to be aggregated
 * @bat_priv: the bat priv with all the soft interface information
 * @packet_len: (total) length of the OGM
 * @send_time: timestamp (jiffies) when the packet is to be sent
515
 * @directlink: true if this is a direct link packet
516 517 518 519 520 521
 * @if_incoming: interface where the packet was received
 * @if_outgoing: interface for which the retransmission should be considered
 * @forw_packet: the forwarded packet which should be checked
 *
 * Returns true if new_packet can be aggregated with forw_packet
 */
522
static bool
523
batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
524
			    struct batadv_priv *bat_priv,
525 526
			    int packet_len, unsigned long send_time,
			    bool directlink,
527
			    const struct batadv_hard_iface *if_incoming,
528
			    const struct batadv_hard_iface *if_outgoing,
529
			    const struct batadv_forw_packet *forw_packet)
530
{
531
	struct batadv_ogm_packet *batadv_ogm_packet;
532
	int aggregated_bytes = forw_packet->packet_len + packet_len;
533
	struct batadv_hard_iface *primary_if = NULL;
534
	bool res = false;
535
	unsigned long aggregation_end_time;
536

537
	batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
538 539
	aggregation_end_time = send_time;
	aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
540

541
	/* we can aggregate the current packet to this aggregated packet
542 543 544 545 546 547 548
	 * if:
	 *
	 * - the send time is within our MAX_AGGREGATION_MS time
	 * - the resulting packet wont be bigger than
	 *   MAX_AGGREGATION_BYTES
	 */
	if (time_before(send_time, forw_packet->send_time) &&
549 550
	    time_after_eq(aggregation_end_time, forw_packet->send_time) &&
	    (aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) {
551
		/* check aggregation compatibility
552 553 554 555 556 557
		 * -> direct link packets are broadcasted on
		 *    their interface only
		 * -> aggregate packet if the current packet is
		 *    a "global" packet as well as the base
		 *    packet
		 */
558
		primary_if = batadv_primary_if_get_selected(bat_priv);
559 560 561
		if (!primary_if)
			goto out;

562 563 564 565
		/* packet is not leaving on the same interface. */
		if (forw_packet->if_outgoing != if_outgoing)
			goto out;

566
		/* packets without direct link flag and high TTL
567 568
		 * are flooded through the net
		 */
569
		if ((!directlink) &&
570
		    (!(batadv_ogm_packet->flags & BATADV_DIRECTLINK)) &&
571
		    (batadv_ogm_packet->ttl != 1) &&
572 573

		    /* own packets originating non-primary
574 575
		     * interfaces leave only that interface
		     */
576 577 578 579 580 581 582
		    ((!forw_packet->own) ||
		     (forw_packet->if_incoming == primary_if))) {
			res = true;
			goto out;
		}

		/* if the incoming packet is sent via this one
583 584
		 * interface only - we still can aggregate
		 */
585
		if ((directlink) &&
586
		    (new_bat_ogm_packet->ttl == 1) &&
587 588 589 590
		    (forw_packet->if_incoming == if_incoming) &&

		    /* packets from direct neighbors or
		     * own secondary interface packets
591 592
		     * (= secondary interface packets in general)
		     */
593
		    (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
594 595 596 597 598 599 600 601 602
		     (forw_packet->own &&
		      forw_packet->if_incoming != primary_if))) {
			res = true;
			goto out;
		}
	}

out:
	if (primary_if)
603
		batadv_hardif_free_ref(primary_if);
604 605 606
	return res;
}

607 608
/**
 * batadv_iv_ogm_aggregate_new - create a new aggregated packet and add this
609 610 611 612 613 614 615 616 617
 *  packet to it.
 * @packet_buff: pointer to the OGM
 * @packet_len: (total) length of the OGM
 * @send_time: timestamp (jiffies) when the packet is to be sent
 * @direct_link: whether this OGM has direct link status
 * @if_incoming: interface where the packet was received
 * @if_outgoing: interface for which the retransmission should be considered
 * @own_packet: true if it is a self-generated ogm
 */
618 619 620
static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
					int packet_len, unsigned long send_time,
					bool direct_link,
621
					struct batadv_hard_iface *if_incoming,
622
					struct batadv_hard_iface *if_outgoing,
623
					int own_packet)
624
{
625 626
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_forw_packet *forw_packet_aggr;
627
	unsigned char *skb_buff;
628
	unsigned int skb_size;
629 630 631 632

	if (!atomic_inc_not_zero(&if_incoming->refcount))
		return;

633 634 635
	if (!atomic_inc_not_zero(&if_outgoing->refcount))
		goto out_free_incoming;

636 637
	/* own packet should always be scheduled */
	if (!own_packet) {
638
		if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
639
			batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
640
				   "batman packet queue full\n");
641 642 643 644 645 646 647 648 649 650 651 652
			goto out;
		}
	}

	forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
	if (!forw_packet_aggr) {
		if (!own_packet)
			atomic_inc(&bat_priv->batman_queue_left);
		goto out;
	}

	if ((atomic_read(&bat_priv->aggregated_ogms)) &&
653
	    (packet_len < BATADV_MAX_AGGREGATION_BYTES))
654
		skb_size = BATADV_MAX_AGGREGATION_BYTES;
655
	else
656 657
		skb_size = packet_len;

658
	skb_size += ETH_HLEN;
659

660
	forw_packet_aggr->skb = netdev_alloc_skb_ip_align(NULL, skb_size);
661 662 663 664 665 666
	if (!forw_packet_aggr->skb) {
		if (!own_packet)
			atomic_inc(&bat_priv->batman_queue_left);
		kfree(forw_packet_aggr);
		goto out;
	}
667
	forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
668
	skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
669 670 671 672 673 674 675

	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
	forw_packet_aggr->packet_len = packet_len;
	memcpy(skb_buff, packet_buff, packet_len);

	forw_packet_aggr->own = own_packet;
	forw_packet_aggr->if_incoming = if_incoming;
676
	forw_packet_aggr->if_outgoing = if_outgoing;
677
	forw_packet_aggr->num_packets = 0;
678
	forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
679 680 681 682 683 684 685 686 687 688 689 690 691
	forw_packet_aggr->send_time = send_time;

	/* save packet direct link flag status */
	if (direct_link)
		forw_packet_aggr->direct_link_flags |= 1;

	/* add new packet to packet list */
	spin_lock_bh(&bat_priv->forw_bat_list_lock);
	hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
	spin_unlock_bh(&bat_priv->forw_bat_list_lock);

	/* start timer for this packet */
	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
692
			  batadv_send_outstanding_bat_ogm_packet);
693
	queue_delayed_work(batadv_event_workqueue,
694 695 696 697 698
			   &forw_packet_aggr->delayed_work,
			   send_time - jiffies);

	return;
out:
699 700
	batadv_hardif_free_ref(if_outgoing);
out_free_incoming:
701
	batadv_hardif_free_ref(if_incoming);
702 703 704
}

/* aggregate a new packet into the existing ogm packet */
705
static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
706 707
				    const unsigned char *packet_buff,
				    int packet_len, bool direct_link)
708 709
{
	unsigned char *skb_buff;
710
	unsigned long new_direct_link_flag;
711 712 713 714 715 716 717

	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
	memcpy(skb_buff, packet_buff, packet_len);
	forw_packet_aggr->packet_len += packet_len;
	forw_packet_aggr->num_packets++;

	/* save packet direct link flag status */
718 719 720 721
	if (direct_link) {
		new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
		forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
	}
722 723
}

724 725 726 727 728 729 730 731 732 733
/**
 * batadv_iv_ogm_queue_add - queue up an OGM for transmission
 * @bat_priv: the bat priv with all the soft interface information
 * @packet_buff: pointer to the OGM
 * @packet_len: (total) length of the OGM
 * @if_incoming: interface where the packet was received
 * @if_outgoing: interface for which the retransmission should be considered
 * @own_packet: true if it is a self-generated ogm
 * @send_time: timestamp (jiffies) when the packet is to be sent
 */
734
static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
735 736
				    unsigned char *packet_buff,
				    int packet_len,
737
				    struct batadv_hard_iface *if_incoming,
738
				    struct batadv_hard_iface *if_outgoing,
739
				    int own_packet, unsigned long send_time)
740
{
741
	/* _aggr -> pointer to the packet we want to aggregate with
742 743
	 * _pos -> pointer to the position in the queue
	 */
744 745
	struct batadv_forw_packet *forw_packet_aggr = NULL;
	struct batadv_forw_packet *forw_packet_pos = NULL;
746
	struct batadv_ogm_packet *batadv_ogm_packet;
747
	bool direct_link;
748
	unsigned long max_aggregation_jiffies;
749

750 751
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
	direct_link = batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0;
752
	max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
753 754 755 756 757

	/* find position for the packet in the forward queue */
	spin_lock_bh(&bat_priv->forw_bat_list_lock);
	/* own packets are not to be aggregated */
	if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
758
		hlist_for_each_entry(forw_packet_pos,
759
				     &bat_priv->forw_bat_list, list) {
760
			if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
761 762 763
							bat_priv, packet_len,
							send_time, direct_link,
							if_incoming,
764
							if_outgoing,
765
							forw_packet_pos)) {
766 767 768 769 770 771 772
				forw_packet_aggr = forw_packet_pos;
				break;
			}
		}
	}

	/* nothing to aggregate with - either aggregation disabled or no
773 774
	 * suitable aggregation packet found
	 */
775 776 777 778
	if (!forw_packet_aggr) {
		/* the following section can run without the lock */
		spin_unlock_bh(&bat_priv->forw_bat_list_lock);

779
		/* if we could not aggregate this packet with one of the others
780 781 782
		 * we hold it back for a while, so that it might be aggregated
		 * later on
		 */
783 784
		if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
			send_time += max_aggregation_jiffies;
785

786 787
		batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
					    send_time, direct_link,
788 789
					    if_incoming, if_outgoing,
					    own_packet);
790
	} else {
791 792
		batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
					packet_len, direct_link);
793 794 795 796
		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
	}
}

797
static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
798
				  const struct ethhdr *ethhdr,
799
				  struct batadv_ogm_packet *batadv_ogm_packet,
800 801
				  bool is_single_hop_neigh,
				  bool is_from_best_next_hop,
802 803
				  struct batadv_hard_iface *if_incoming,
				  struct batadv_hard_iface *if_outgoing)
804
{
805
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
806
	uint16_t tvlv_len;
807

808
	if (batadv_ogm_packet->ttl <= 1) {
809
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
810 811 812
		return;
	}

813 814 815 816 817 818 819 820
	if (!is_from_best_next_hop) {
		/* Mark the forwarded packet when it is not coming from our
		 * best next hop. We still need to forward the packet for our
		 * neighbor link quality detection to work in case the packet
		 * originated from a single hop neighbor. Otherwise we can
		 * simply drop the ogm.
		 */
		if (is_single_hop_neigh)
821
			batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
822 823 824
		else
			return;
	}
825

826
	tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
827

828
	batadv_ogm_packet->ttl--;
829
	ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
830 831

	/* apply hop penalty */
832
	batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
833
						   bat_priv);
834

835
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
836
		   "Forwarding packet: tq: %i, ttl: %i\n",
837
		   batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
838 839

	/* switch of primaries first hop flag when forwarding */
840
	batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP;
841
	if (is_single_hop_neigh)
842
		batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
843
	else
844
		batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
845

846
	batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
847
				BATADV_OGM_HLEN + tvlv_len,
848 849
				if_incoming, if_outgoing, 0,
				batadv_iv_ogm_fwd_send_time());
850 851
}

852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
/**
 * batadv_iv_ogm_slide_own_bcast_window - bitshift own OGM broadcast windows for
 * the given interface
 * @hard_iface: the interface for which the windows have to be shifted
 */
static void
batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
{
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	struct hlist_head *head;
	struct batadv_orig_node *orig_node;
	unsigned long *word;
	uint32_t i;
	size_t word_index;
	uint8_t *w;
868
	int if_num;
869 870 871 872 873 874

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
875
			spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
876
			word_index = hard_iface->if_num * BATADV_NUM_WORDS;
877
			word = &orig_node->bat_iv.bcast_own[word_index];
878 879

			batadv_bit_get_packet(bat_priv, word, 1, 0);
880 881
			if_num = hard_iface->if_num;
			w = &orig_node->bat_iv.bcast_own_sum[if_num];
882
			*w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
883
			spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
884 885 886 887 888
		}
		rcu_read_unlock();
	}
}

889
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
890
{
891
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
892
	unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
893
	struct batadv_ogm_packet *batadv_ogm_packet;
894
	struct batadv_hard_iface *primary_if, *tmp_hard_iface;
895
	int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
896
	uint32_t seqno;
897
	uint16_t tvlv_len = 0;
898
	unsigned long send_time;
899

900
	primary_if = batadv_primary_if_get_selected(bat_priv);
901

902 903 904 905 906
	if (hard_iface == primary_if) {
		/* tt changes have to be committed before the tvlv data is
		 * appended as it may alter the tt tvlv container
		 */
		batadv_tt_local_commit_changes(bat_priv);
907 908 909
		tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
							    ogm_buff_len,
							    BATADV_OGM_HLEN);
910
	}
911

912
	batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
913
	batadv_ogm_packet->tvlv_len = htons(tvlv_len);
914 915

	/* change sequence number to network order */
916
	seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
917
	batadv_ogm_packet->seqno = htonl(seqno);
918
	atomic_inc(&hard_iface->bat_iv.ogm_seqno);
919

920
	batadv_iv_ogm_slide_own_bcast_window(hard_iface);
921

922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
	send_time = batadv_iv_ogm_emit_send_time(bat_priv);

	if (hard_iface != primary_if) {
		/* OGMs from secondary interfaces are only scheduled on their
		 * respective interfaces.
		 */
		batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
					hard_iface, hard_iface, 1, send_time);
		goto out;
	}

	/* OGMs from primary interfaces are scheduled on all
	 * interfaces.
	 */
	rcu_read_lock();
	list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
		if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
				continue;
		batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
					*ogm_buff_len, hard_iface,
					tmp_hard_iface, 1, send_time);
	}
	rcu_read_unlock();

out:
947
	if (primary_if)
948
		batadv_hardif_free_ref(primary_if);
949 950
}

951 952 953 954 955
/**
 * batadv_iv_ogm_orig_update - use OGM to update corresponding data in an
 *  originator
 * @bat_priv: the bat priv with all the soft interface information
 * @orig_node: the orig node who originally emitted the ogm packet
956
 * @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
957 958 959 960 961 962
 * @ethhdr: Ethernet header of the OGM
 * @batadv_ogm_packet: the ogm packet
 * @if_incoming: interface where the packet was received
 * @if_outgoing: interface for which the retransmission should be considered
 * @dup_status: the duplicate status of this ogm packet.
 */
963
static void
964 965
batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
			  struct batadv_orig_node *orig_node,
966
			  struct batadv_orig_ifinfo *orig_ifinfo,
967
			  const struct ethhdr *ethhdr,
968
			  const struct batadv_ogm_packet *batadv_ogm_packet,
969
			  struct batadv_hard_iface *if_incoming,
970
			  struct batadv_hard_iface *if_outgoing,
971
			  enum batadv_dup_status dup_status)
972
{
973 974
	struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
	struct batadv_neigh_ifinfo *router_ifinfo = NULL;
975 976 977
	struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
	struct batadv_neigh_node *router = NULL;
	struct batadv_orig_node *orig_node_tmp;
978
	int if_num;
979
	uint8_t sum_orig, sum_neigh;
980
	uint8_t *neigh_addr;
981
	uint8_t tq_avg;
982

983
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
984
		   "update_originator(): Searching and updating originator entry of received packet\n");
985 986

	rcu_read_lock();
987
	hlist_for_each_entry_rcu(tmp_neigh_node,
988
				 &orig_node->neigh_list, list) {
989 990 991 992
		neigh_addr = tmp_neigh_node->addr;
		if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
		    tmp_neigh_node->if_incoming == if_incoming &&
		    atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
993
			if (WARN(neigh_node, "too many matching neigh_nodes"))
994
				batadv_neigh_node_free_ref(neigh_node);
995 996 997 998
			neigh_node = tmp_neigh_node;
			continue;
		}

999
		if (dup_status != BATADV_NO_DUP)
1000 1001
			continue;

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
		/* only update the entry for this outgoing interface */
		neigh_ifinfo = batadv_neigh_ifinfo_get(tmp_neigh_node,
						       if_outgoing);
		if (!neigh_ifinfo)
			continue;

		spin_lock_bh(&tmp_neigh_node->ifinfo_lock);
		batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
				       &neigh_ifinfo->bat_iv.tq_index, 0);
		tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
		neigh_ifinfo->bat_iv.tq_avg = tq_avg;
		spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);

		batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
		neigh_ifinfo = NULL;
1017 1018 1019
	}

	if (!neigh_node) {
1020
		struct batadv_orig_node *orig_tmp;
1021

1022
		orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
1023 1024 1025
		if (!orig_tmp)
			goto unlock;

1026 1027
		neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
						     ethhdr->h_source,
1028
						     orig_node, orig_tmp);
1029

1030
		batadv_orig_node_free_ref(orig_tmp);
1031 1032 1033
		if (!neigh_node)
			goto unlock;
	} else
1034
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1035
			   "Updating existing last-hop neighbor of originator\n");
1036 1037

	rcu_read_unlock();
1038 1039 1040
	neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
	if (!neigh_ifinfo)
		goto out;
1041

1042
	neigh_node->last_seen = jiffies;
1043

1044 1045 1046
	spin_lock_bh(&neigh_node->ifinfo_lock);
	batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
			       &neigh_ifinfo->bat_iv.tq_index,
1047
			       batadv_ogm_packet->tq);
1048 1049 1050
	tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
	neigh_ifinfo->bat_iv.tq_avg = tq_avg;
	spin_unlock_bh(&neigh_node->ifinfo_lock);
1051

1052
	if (dup_status == BATADV_NO_DUP) {
1053
		orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1054
		neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1055 1056 1057
	}

	/* if this neighbor already is our next hop there is nothing
1058 1059
	 * to change
	 */
1060
	router = batadv_orig_router_get(orig_node, if_outgoing);
1061
	if (router == neigh_node)
1062
		goto out;
1063

1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
	if (router) {
		router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
		if (!router_ifinfo)
			goto out;

		/* if this neighbor does not offer a better TQ we won't
		 * consider it
		 */
		if (router_ifinfo->bat_iv.tq_avg > neigh_ifinfo->bat_iv.tq_avg)
			goto out;
	}
1075 1076

	/* if the TQ is the same and the link not more symmetric we
1077 1078
	 * won't consider it either
	 */
1079 1080
	if (router_ifinfo &&
	    (neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg)) {
1081
		orig_node_tmp = router->orig_node;
1082
		spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1083
		if_num = router->if_incoming->if_num;
1084 1085
		sum_orig = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
		spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1086 1087

		orig_node_tmp = neigh_node->orig_node;
1088
		spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1089
		if_num = neigh_node->if_incoming->if_num;
1090 1091
		sum_neigh = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
		spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1092

1093
		if (sum_orig >= sum_neigh)
1094
			goto out;
1095 1096
	}

1097
	batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
1098 1099 1100 1101 1102 1103
	goto out;

unlock:
	rcu_read_unlock();
out:
	if (neigh_node)
1104
		batadv_neigh_node_free_ref(neigh_node);
1105
	if (router)
1106
		batadv_neigh_node_free_ref(router);
1107 1108 1109 1110
	if (neigh_ifinfo)
		batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
	if (router_ifinfo)
		batadv_neigh_ifinfo_free_ref(router_ifinfo);
1111 1112
}

1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
/**
 * batadv_iv_ogm_calc_tq - calculate tq for current received ogm packet
 * @orig_node: the orig node who originally emitted the ogm packet
 * @orig_neigh_node: the orig node struct of the neighbor who sent the packet
 * @batadv_ogm_packet: the ogm packet
 * @if_incoming: interface where the packet was received
 * @if_outgoing: interface for which the retransmission should be considered
 *
 * Returns 1 if the link can be considered bidirectional, 0 otherwise
 */
1123 1124
static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
				 struct batadv_orig_node *orig_neigh_node,
1125
				 struct batadv_ogm_packet *batadv_ogm_packet,
1126 1127
				 struct batadv_hard_iface *if_incoming,
				 struct batadv_hard_iface *if_outgoing)
1128
{
1129 1130
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
1131
	struct batadv_neigh_ifinfo *neigh_ifinfo;
1132
	uint8_t total_count;
1133 1134
	uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
	unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1135
	int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
1136
	unsigned int combined_tq;
S
Simon Wunderlich 已提交
1137
	int tq_iface_penalty;
1138 1139 1140

	/* find corresponding one hop neighbor */
	rcu_read_lock();
1141
	hlist_for_each_entry_rcu(tmp_neigh_node,
1142
				 &orig_neigh_node->neigh_list, list) {
1143 1144
		if (!batadv_compare_eth(tmp_neigh_node->addr,
					orig_neigh_node->orig))
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
			continue;

		if (tmp_neigh_node->if_incoming != if_incoming)
			continue;

		if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
			continue;

		neigh_node = tmp_neigh_node;
		break;
	}
	rcu_read_unlock();

	if (!neigh_node)
1159 1160 1161
		neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
						     orig_neigh_node->orig,
						     orig_neigh_node,
1162
						     orig_neigh_node);
1163 1164 1165 1166

	if (!neigh_node)
		goto out;

1167
	/* if orig_node is direct neighbor update neigh_node last_seen */
1168
	if (orig_node == orig_neigh_node)
1169
		neigh_node->last_seen = jiffies;
1170

1171
	orig_node->last_seen = jiffies;
1172 1173

	/* find packet count of corresponding one hop neighbor */
1174 1175 1176
	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
	if_num = if_incoming->if_num;
	orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
1177 1178 1179 1180 1181 1182 1183
	neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
	if (neigh_ifinfo) {
		neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count;
		batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
	} else {
		neigh_rq_count = 0;
	}
1184
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1185 1186

	/* pay attention to not get a value bigger than 100 % */
1187 1188 1189 1190
	if (orig_eq_count > neigh_rq_count)
		total_count = neigh_rq_count;
	else
		total_count = orig_eq_count;
1191

1192 1193 1194
	/* if we have too few packets (too less data) we set tq_own to zero
	 * if we receive too few packets it is not considered bidirectional
	 */
1195 1196
	if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
	    neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
1197 1198 1199 1200
		tq_own = 0;
	else
		/* neigh_node->real_packet_count is never zero as we
		 * only purge old information when getting new
1201 1202
		 * information
		 */
1203
		tq_own = (BATADV_TQ_MAX_VALUE * total_count) /	neigh_rq_count;
1204

1205
	/* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
1206 1207 1208 1209
	 * affect the nearly-symmetric links only a little, but
	 * punishes asymmetric links more.  This will give a value
	 * between 0 and TQ_MAX_VALUE
	 */
1210 1211 1212 1213 1214 1215 1216 1217 1218
	neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
	neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv;
	neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE *
			    BATADV_TQ_LOCAL_WINDOW_SIZE *
			    BATADV_TQ_LOCAL_WINDOW_SIZE;
	inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
	inv_asym_penalty /= neigh_rq_max_cube;
	tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;

S
Simon Wunderlich 已提交
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
	/* penalize if the OGM is forwarded on the same interface. WiFi
	 * interfaces and other half duplex devices suffer from throughput
	 * drops as they can't send and receive at the same time.
	 */
	tq_iface_penalty = BATADV_TQ_MAX_VALUE;
	if (if_outgoing && (if_incoming == if_outgoing) &&
	    batadv_is_wifi_netdev(if_outgoing->net_dev))
		tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE,
						      bat_priv);

	combined_tq = batadv_ogm_packet->tq *
		      tq_own *
		      tq_asym_penalty *
		      tq_iface_penalty;
	combined_tq /= BATADV_TQ_MAX_VALUE *
		       BATADV_TQ_MAX_VALUE *
		       BATADV_TQ_MAX_VALUE;
1236
	batadv_ogm_packet->tq = combined_tq;
1237

1238
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
S
Simon Wunderlich 已提交
1239
		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
1240
		   orig_node->orig, orig_neigh_node->orig, total_count,
S
Simon Wunderlich 已提交
1241 1242 1243
		   neigh_rq_count, tq_own, tq_asym_penalty, tq_iface_penalty,
		   batadv_ogm_packet->tq, if_incoming->net_dev->name,
		   if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
1244 1245

	/* if link has the minimum required transmission quality
1246 1247
	 * consider it bidirectional
	 */
1248
	if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
1249 1250 1251 1252
		ret = 1;

out:
	if (neigh_node)
1253
		batadv_neigh_node_free_ref(neigh_node);
1254 1255 1256
	return ret;
}

1257 1258 1259 1260 1261 1262
/**
 * batadv_iv_ogm_update_seqnos -  process a batman packet for all interfaces,
 *  adjust the sequence number and find out whether it is a duplicate
 * @ethhdr: ethernet header of the packet
 * @batadv_ogm_packet: OGM packet to be considered
 * @if_incoming: interface on which the OGM packet was received
1263
 * @if_outgoing: interface for which the retransmission should be considered
1264 1265
 *
 * Returns duplicate status as enum batadv_dup_status
1266
 */
1267
static enum batadv_dup_status
1268
batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1269
			    const struct batadv_ogm_packet *batadv_ogm_packet,
1270 1271
			    const struct batadv_hard_iface *if_incoming,
			    struct batadv_hard_iface *if_outgoing)
1272
{
1273 1274
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_orig_node *orig_node;
1275
	struct batadv_orig_ifinfo *orig_ifinfo = NULL;
1276 1277
	struct batadv_neigh_node *neigh_node;
	struct batadv_neigh_ifinfo *neigh_ifinfo;
1278
	int is_dup;
1279 1280
	int32_t seq_diff;
	int need_update = 0;
1281 1282
	int set_mark;
	enum batadv_dup_status ret = BATADV_NO_DUP;
1283
	uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
1284
	uint8_t *neigh_addr;
1285
	uint8_t packet_count;
1286
	unsigned long *bitmap;
1287

1288
	orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1289
	if (!orig_node)
1290
		return BATADV_NO_DUP;
1291

1292 1293 1294 1295 1296 1297
	orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
	if (WARN_ON(!orig_ifinfo)) {
		batadv_orig_node_free_ref(orig_node);
		return 0;
	}

1298
	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1299
	seq_diff = seqno - orig_ifinfo->last_real_seqno;
1300 1301

	/* signalize caller that the packet is to be dropped. */
1302
	if (!hlist_empty(&orig_node->neigh_list) &&
1303
	    batadv_window_protected(bat_priv, seq_diff,
1304
				    &orig_ifinfo->batman_seqno_reset)) {
1305
		ret = BATADV_PROTECTED;
1306
		goto out;
1307
	}
1308 1309

	rcu_read_lock();
1310 1311 1312 1313 1314 1315 1316 1317
	hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
		neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node,
						       if_outgoing);
		if (!neigh_ifinfo)
			continue;

		neigh_addr = neigh_node->addr;
		is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
1318
					 orig_ifinfo->last_real_seqno,
1319 1320
					 seqno);

1321
		if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1322
		    neigh_node->if_incoming == if_incoming) {
1323
			set_mark = 1;
1324 1325 1326
			if (is_dup)
				ret = BATADV_NEIGH_DUP;
		} else {
1327
			set_mark = 0;
1328 1329 1330
			if (is_dup && (ret != BATADV_NEIGH_DUP))
				ret = BATADV_ORIG_DUP;
		}
1331 1332

		/* if the window moved, set the update flag. */
1333
		bitmap = neigh_ifinfo->bat_iv.real_bits;
1334
		need_update |= batadv_bit_get_packet(bat_priv, bitmap,
1335
						     seq_diff, set_mark);
1336

1337
		packet_count = bitmap_weight(bitmap,
1338
					     BATADV_TQ_LOCAL_WINDOW_SIZE);
1339 1340
		neigh_ifinfo->bat_iv.real_packet_count = packet_count;
		batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
1341 1342 1343 1344
	}
	rcu_read_unlock();

	if (need_update) {
1345
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1346 1347 1348 1349
			   "%s updating last_seqno: old %u, new %u\n",
			   if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
			   orig_ifinfo->last_real_seqno, seqno);
		orig_ifinfo->last_real_seqno = seqno;
1350 1351 1352
	}

out:
1353
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1354
	batadv_orig_node_free_ref(orig_node);
1355 1356
	if (orig_ifinfo)
		batadv_orig_ifinfo_free_ref(orig_ifinfo);
1357 1358 1359
	return ret;
}

1360 1361 1362
/**
 * batadv_iv_ogm_process_per_outif - process a batman iv OGM for an outgoing if
 * @skb: the skb containing the OGM
1363
 * @ogm_offset: offset from skb->data to start of ogm header
1364 1365 1366 1367 1368 1369 1370 1371 1372
 * @orig_node: the (cached) orig node for the originator of this OGM
 * @if_incoming: the interface where this packet was received
 * @if_outgoing: the interface for which the packet should be considered
 */
static void
batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
				struct batadv_orig_node *orig_node,
				struct batadv_hard_iface *if_incoming,
				struct batadv_hard_iface *if_outgoing)
1373
{
1374 1375
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_neigh_node *router = NULL, *router_router = NULL;
1376 1377
	struct batadv_orig_node *orig_neigh_node;
	struct batadv_orig_ifinfo *orig_ifinfo;
1378
	struct batadv_neigh_node *orig_neigh_router = NULL;
1379
	struct batadv_neigh_ifinfo *router_ifinfo = NULL;
1380
	struct batadv_ogm_packet *ogm_packet;
1381
	enum batadv_dup_status dup_status;
1382 1383 1384 1385 1386
	bool is_from_best_next_hop = false;
	bool is_single_hop_neigh = false;
	bool sameseq, similar_ttl;
	struct sk_buff *skb_priv;
	struct ethhdr *ethhdr;
1387
	uint8_t *prev_sender;
1388
	int is_bidirect;
1389

1390 1391
	/* create a private copy of the skb, as some functions change tq value
	 * and/or flags.
1392
	 */
1393 1394
	skb_priv = skb_copy(skb, GFP_ATOMIC);
	if (!skb_priv)
1395 1396
		return;

1397 1398
	ethhdr = eth_hdr(skb_priv);
	ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
1399

1400 1401 1402
	dup_status = batadv_iv_ogm_update_seqnos(ethhdr, ogm_packet,
						 if_incoming, if_outgoing);
	if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
1403
		is_single_hop_neigh = true;
1404

1405
	if (dup_status == BATADV_PROTECTED) {
1406
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1407 1408
			   "Drop packet: packet within seqno protection time (sender: %pM)\n",
			   ethhdr->h_source);
1409 1410 1411
		goto out;
	}

1412
	if (ogm_packet->tq == 0) {
1413
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1414
			   "Drop packet: originator packet with tq equal 0\n");
1415 1416 1417
		goto out;
	}

1418
	router = batadv_orig_router_get(orig_node, if_outgoing);
1419
	if (router) {
1420 1421 1422
		router_router = batadv_orig_router_get(router->orig_node,
						       if_outgoing);
		router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1423
	}
1424

1425
	if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
1426
	    (batadv_compare_eth(router->addr, ethhdr->h_source)))
1427 1428
		is_from_best_next_hop = true;

1429
	prev_sender = ogm_packet->prev_sender;
1430 1431
	/* avoid temporary routing loops */
	if (router && router_router &&
1432
	    (batadv_compare_eth(router->addr, prev_sender)) &&
1433
	    !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
1434
	    (batadv_compare_eth(router->addr, router_router->addr))) {
1435
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1436 1437
			   "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
			   ethhdr->h_source);
1438 1439 1440
		goto out;
	}

1441 1442
	if (if_outgoing == BATADV_IF_DEFAULT)
		batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
1443

1444
	/* if sender is a direct neighbor the sender mac equals
1445 1446
	 * originator mac
	 */
1447 1448 1449
	if (is_single_hop_neigh)
		orig_neigh_node = orig_node;
	else
1450 1451
		orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
							 ethhdr->h_source);
1452

1453 1454 1455
	if (!orig_neigh_node)
		goto out;

1456 1457
	/* Update nc_nodes of the originator */
	batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
1458
				 ogm_packet, is_single_hop_neigh);
1459

1460 1461
	orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
						   if_outgoing);
1462 1463

	/* drop packet if sender is not a direct neighbor and if we
1464 1465
	 * don't route towards it
	 */
1466
	if (!is_single_hop_neigh && (!orig_neigh_router)) {
1467
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1468
			   "Drop packet: OGM via unknown neighbor!\n");
1469 1470 1471
		goto out_neigh;
	}

1472
	is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1473 1474
					    ogm_packet, if_incoming,
					    if_outgoing);
1475 1476

	/* update ranking if it is not a duplicate or has the same
1477 1478
	 * seqno and similar ttl as the non-duplicate
	 */
1479 1480 1481 1482 1483 1484 1485
	orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
	if (!orig_ifinfo)
		goto out_neigh;

	sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
	similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;

1486
	if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
1487 1488 1489 1490 1491 1492 1493
			    (sameseq && similar_ttl))) {
		batadv_iv_ogm_orig_update(bat_priv, orig_node,
					  orig_ifinfo, ethhdr,
					  ogm_packet, if_incoming,
					  if_outgoing, dup_status);
	}
	batadv_orig_ifinfo_free_ref(orig_ifinfo);
1494

1495 1496 1497 1498
	/* only forward for specific interface, not for the default one. */
	if (if_outgoing == BATADV_IF_DEFAULT)
		goto out_neigh;

1499 1500
	/* is single hop (direct) neighbor */
	if (is_single_hop_neigh) {
1501 1502 1503 1504 1505 1506 1507 1508 1509
		/* OGMs from secondary interfaces should only scheduled once
		 * per interface where it has been received, not multiple times
		 */
		if ((ogm_packet->ttl <= 2) &&
		    (if_incoming != if_outgoing)) {
			batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
				   "Drop packet: OGM from secondary interface and wrong outgoing interface\n");
			goto out_neigh;
		}
1510
		/* mark direct link on incoming interface */
1511
		batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1512
				      is_single_hop_neigh,
1513 1514
				      is_from_best_next_hop, if_incoming,
				      if_outgoing);
1515

1516
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1517
			   "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1518 1519 1520 1521
		goto out_neigh;
	}

	/* multihop originator */
1522
	if (!is_bidirect) {
1523
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1524
			   "Drop packet: not received via bidirectional link\n");
1525 1526 1527
		goto out_neigh;
	}

1528
	if (dup_status == BATADV_NEIGH_DUP) {
1529
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1530
			   "Drop packet: duplicate packet received\n");
1531 1532 1533
		goto out_neigh;
	}

1534
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1535
		   "Forwarding packet: rebroadcast originator packet\n");
1536
	batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1537
			      is_single_hop_neigh, is_from_best_next_hop,
1538
			      if_incoming, if_outgoing);
1539 1540 1541

out_neigh:
	if ((orig_neigh_node) && (!is_single_hop_neigh))
1542
		batadv_orig_node_free_ref(orig_neigh_node);
1543
out:
1544 1545
	if (router_ifinfo)
		batadv_neigh_ifinfo_free_ref(router_ifinfo);
1546
	if (router)
1547
		batadv_neigh_node_free_ref(router);
1548
	if (router_router)
1549
		batadv_neigh_node_free_ref(router_router);
1550
	if (orig_neigh_router)
1551
		batadv_neigh_node_free_ref(orig_neigh_router);
1552

1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661
	kfree_skb(skb_priv);
}

/**
 * batadv_iv_ogm_process - process an incoming batman iv OGM
 * @skb: the skb containing the OGM
 * @ogm_offset: offset to the OGM which should be processed (for aggregates)
 * @if_incoming: the interface where this packet was receved
 */
static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
				  struct batadv_hard_iface *if_incoming)
{
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_orig_node *orig_neigh_node, *orig_node;
	struct batadv_hard_iface *hard_iface;
	struct batadv_ogm_packet *ogm_packet;
	uint32_t if_incoming_seqno;
	bool has_directlink_flag;
	struct ethhdr *ethhdr;
	bool is_my_oldorig = false;
	bool is_my_addr = false;
	bool is_my_orig = false;

	ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
	ethhdr = eth_hdr(skb);

	/* Silently drop when the batman packet is actually not a
	 * correct packet.
	 *
	 * This might happen if a packet is padded (e.g. Ethernet has a
	 * minimum frame length of 64 byte) and the aggregation interprets
	 * it as an additional length.
	 *
	 * TODO: A more sane solution would be to have a bit in the
	 * batadv_ogm_packet to detect whether the packet is the last
	 * packet in an aggregation.  Here we expect that the padding
	 * is always zero (or not 0x01)
	 */
	if (ogm_packet->packet_type != BATADV_IV_OGM)
		return;

	/* could be changed by schedule_own_packet() */
	if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);

	if (ogm_packet->flags & BATADV_DIRECTLINK)
		has_directlink_flag = true;
	else
		has_directlink_flag = false;

	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
		   "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",
		   ethhdr->h_source, if_incoming->net_dev->name,
		   if_incoming->net_dev->dev_addr, ogm_packet->orig,
		   ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
		   ogm_packet->tq, ogm_packet->ttl,
		   ogm_packet->version, has_directlink_flag);

	rcu_read_lock();
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
		if (hard_iface->if_status != BATADV_IF_ACTIVE)
			continue;

		if (hard_iface->soft_iface != if_incoming->soft_iface)
			continue;

		if (batadv_compare_eth(ethhdr->h_source,
				       hard_iface->net_dev->dev_addr))
			is_my_addr = true;

		if (batadv_compare_eth(ogm_packet->orig,
				       hard_iface->net_dev->dev_addr))
			is_my_orig = true;

		if (batadv_compare_eth(ogm_packet->prev_sender,
				       hard_iface->net_dev->dev_addr))
			is_my_oldorig = true;
	}
	rcu_read_unlock();

	if (is_my_addr) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Drop packet: received my own broadcast (sender: %pM)\n",
			   ethhdr->h_source);
		return;
	}

	if (is_my_orig) {
		unsigned long *word;
		int offset;
		int32_t bit_pos;
		int16_t if_num;
		uint8_t *weight;

		orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
							 ethhdr->h_source);
		if (!orig_neigh_node)
			return;

		/* neighbor has to indicate direct link and it has to
		 * come via the corresponding interface
		 * save packet seqno for bidirectional check
		 */
		if (has_directlink_flag &&
		    batadv_compare_eth(if_incoming->net_dev->dev_addr,
				       ogm_packet->orig)) {
			if_num = if_incoming->if_num;
			offset = if_num * BATADV_NUM_WORDS;

			spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1662
			word = &orig_neigh_node->bat_iv.bcast_own[offset];
1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
			bit_pos = if_incoming_seqno - 2;
			bit_pos -= ntohl(ogm_packet->seqno);
			batadv_set_bit(word, bit_pos);
			weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num];
			*weight = bitmap_weight(word,
						BATADV_TQ_LOCAL_WINDOW_SIZE);
			spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
		}

		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Drop packet: originator packet from myself (via neighbor)\n");
		batadv_orig_node_free_ref(orig_neigh_node);
		return;
	}

	if (is_my_oldorig) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
			   ethhdr->h_source);
		return;
	}

	if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
			   ethhdr->h_source);
		return;
	}

	orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
	if (!orig_node)
		return;

	batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
					if_incoming, BATADV_IF_DEFAULT);

	rcu_read_lock();
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
		if (hard_iface->if_status != BATADV_IF_ACTIVE)
			continue;

		if (hard_iface->soft_iface != bat_priv->soft_iface)
			continue;

		batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
						if_incoming, hard_iface);
	}
	rcu_read_unlock();

1712
	batadv_orig_node_free_ref(orig_node);
1713 1714
}

1715
static int batadv_iv_ogm_receive(struct sk_buff *skb,
1716
				 struct batadv_hard_iface *if_incoming)
1717
{
1718
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1719
	struct batadv_ogm_packet *ogm_packet;
1720
	uint8_t *packet_pos;
1721
	int ogm_offset;
1722
	bool ret;
1723

1724
	ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1725 1726
	if (!ret)
		return NET_RX_DROP;
1727

1728 1729 1730
	/* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
	 * that does not have B.A.T.M.A.N. IV enabled ?
	 */
1731
	if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit)
1732 1733
		return NET_RX_DROP;

1734 1735
	batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1736 1737
			   skb->len + ETH_HLEN);

1738 1739
	ogm_offset = 0;
	ogm_packet = (struct batadv_ogm_packet *)skb->data;
1740 1741

	/* unpack the aggregated packets and process them one by one */
1742 1743 1744
	while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
					 ogm_packet->tvlv_len)) {
		batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
1745

1746 1747
		ogm_offset += BATADV_OGM_HLEN;
		ogm_offset += ntohs(ogm_packet->tvlv_len);
1748

1749 1750
		packet_pos = skb->data + ogm_offset;
		ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1751
	}
1752 1753 1754

	kfree_skb(skb);
	return NET_RX_SUCCESS;
1755
}
1756

1757 1758
/**
 * batadv_iv_ogm_orig_print_neigh - print neighbors for the originator table
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
 * @orig_node: the orig_node for which the neighbors are printed
 * @if_outgoing: outgoing interface for these entries
 * @seq: debugfs table seq_file struct
 *
 * Must be called while holding an rcu lock.
 */
static void
batadv_iv_ogm_orig_print_neigh(struct batadv_orig_node *orig_node,
			       struct batadv_hard_iface *if_outgoing,
			       struct seq_file *seq)
{
	struct batadv_neigh_node *neigh_node;
	struct batadv_neigh_ifinfo *n_ifinfo;

	hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
		n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
		if (!n_ifinfo)
			continue;

		seq_printf(seq, " %pM (%3i)",
			   neigh_node->addr,
			   n_ifinfo->bat_iv.tq_avg);

		batadv_neigh_ifinfo_free_ref(n_ifinfo);
	}
}

1786 1787 1788 1789
/**
 * batadv_iv_ogm_orig_print - print the originator table
 * @bat_priv: the bat priv with all the soft interface information
 * @seq: debugfs table seq_file struct
1790
 * @if_outgoing: the outgoing interface for which this should be printed
1791 1792
 */
static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
1793 1794
				     struct seq_file *seq,
				     struct batadv_hard_iface *if_outgoing)
1795
{
1796
	struct batadv_neigh_node *neigh_node;
1797 1798 1799
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	int last_seen_msecs, last_seen_secs;
	struct batadv_orig_node *orig_node;
1800
	struct batadv_neigh_ifinfo *n_ifinfo;
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
	unsigned long last_seen_jiffies;
	struct hlist_head *head;
	int batman_count = 0;
	uint32_t i;

	seq_printf(seq, "  %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
		   "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
		   "Nexthop", "outgoingIF", "Potential nexthops");

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1815
			neigh_node = batadv_orig_router_get(orig_node,
1816
							    if_outgoing);
1817 1818 1819
			if (!neigh_node)
				continue;

1820
			n_ifinfo = batadv_neigh_ifinfo_get(neigh_node,
1821
							   if_outgoing);
1822 1823 1824 1825
			if (!n_ifinfo)
				goto next;

			if (n_ifinfo->bat_iv.tq_avg == 0)
1826 1827 1828 1829 1830 1831 1832 1833 1834
				goto next;

			last_seen_jiffies = jiffies - orig_node->last_seen;
			last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
			last_seen_secs = last_seen_msecs / 1000;
			last_seen_msecs = last_seen_msecs % 1000;

			seq_printf(seq, "%pM %4i.%03is   (%3i) %pM [%10s]:",
				   orig_node->orig, last_seen_secs,
1835
				   last_seen_msecs, n_ifinfo->bat_iv.tq_avg,
1836 1837 1838
				   neigh_node->addr,
				   neigh_node->if_incoming->net_dev->name);

1839 1840
			batadv_iv_ogm_orig_print_neigh(orig_node, if_outgoing,
						       seq);
1841 1842 1843 1844 1845
			seq_puts(seq, "\n");
			batman_count++;

next:
			batadv_neigh_node_free_ref(neigh_node);
1846 1847
			if (n_ifinfo)
				batadv_neigh_ifinfo_free_ref(n_ifinfo);
1848 1849 1850 1851 1852 1853 1854 1855
		}
		rcu_read_unlock();
	}

	if (batman_count == 0)
		seq_puts(seq, "No batman nodes in range ...\n");
}

1856 1857 1858
/**
 * batadv_iv_ogm_neigh_cmp - compare the metrics of two neighbors
 * @neigh1: the first neighbor object of the comparison
1859
 * @if_outgoing1: outgoing interface for the first neighbor
1860
 * @neigh2: the second neighbor object of the comparison
1861
 * @if_outgoing2: outgoing interface for the second neighbor
1862 1863 1864 1865 1866
 *
 * Returns a value less, equal to or greater than 0 if the metric via neigh1 is
 * lower, the same as or higher than the metric via neigh2
 */
static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
1867 1868 1869
				   struct batadv_hard_iface *if_outgoing1,
				   struct batadv_neigh_node *neigh2,
				   struct batadv_hard_iface *if_outgoing2)
1870
{
1871
	struct batadv_neigh_ifinfo *neigh1_ifinfo, *neigh2_ifinfo;
1872
	uint8_t tq1, tq2;
1873 1874 1875 1876
	int diff;

	neigh1_ifinfo = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
	neigh2_ifinfo = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
1877

1878 1879 1880 1881
	if (!neigh1_ifinfo || !neigh2_ifinfo) {
		diff = 0;
		goto out;
	}
1882

1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893
	tq1 = neigh1_ifinfo->bat_iv.tq_avg;
	tq2 = neigh2_ifinfo->bat_iv.tq_avg;
	diff = tq1 - tq2;

out:
	if (neigh1_ifinfo)
		batadv_neigh_ifinfo_free_ref(neigh1_ifinfo);
	if (neigh2_ifinfo)
		batadv_neigh_ifinfo_free_ref(neigh2_ifinfo);

	return diff;
1894 1895
}

1896 1897 1898 1899
/**
 * batadv_iv_ogm_neigh_is_eob - check if neigh1 is equally good or better than
 *  neigh2 from the metric prospective
 * @neigh1: the first neighbor object of the comparison
1900
 * @if_outgoing1: outgoing interface for the first neighbor
1901
 * @neigh2: the second neighbor object of the comparison
1902
 * @if_outgoing2: outgoing interface for the second neighbor
1903
 *
1904 1905
 * Returns true if the metric via neigh1 is equally good or better than
 * the metric via neigh2, false otherwise.
1906
 */
1907 1908 1909 1910 1911
static bool
batadv_iv_ogm_neigh_is_eob(struct batadv_neigh_node *neigh1,
			   struct batadv_hard_iface *if_outgoing1,
			   struct batadv_neigh_node *neigh2,
			   struct batadv_hard_iface *if_outgoing2)
1912
{
1913 1914 1915
	struct batadv_neigh_ifinfo *neigh1_ifinfo, *neigh2_ifinfo;
	uint8_t tq1, tq2;
	bool ret;
1916

1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936
	neigh1_ifinfo = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
	neigh2_ifinfo = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);

	/* we can't say that the metric is better */
	if (!neigh1_ifinfo || !neigh2_ifinfo) {
		ret = false;
		goto out;
	}

	tq1 = neigh1_ifinfo->bat_iv.tq_avg;
	tq2 = neigh2_ifinfo->bat_iv.tq_avg;
	ret = (tq1 - tq2) > -BATADV_TQ_SIMILARITY_THRESHOLD;

out:
	if (neigh1_ifinfo)
		batadv_neigh_ifinfo_free_ref(neigh1_ifinfo);
	if (neigh2_ifinfo)
		batadv_neigh_ifinfo_free_ref(neigh2_ifinfo);

	return ret;
1937 1938
}

1939
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
1940
	.name = "BATMAN_IV",
1941 1942 1943 1944 1945 1946
	.bat_iface_enable = batadv_iv_ogm_iface_enable,
	.bat_iface_disable = batadv_iv_ogm_iface_disable,
	.bat_iface_update_mac = batadv_iv_ogm_iface_update_mac,
	.bat_primary_iface_set = batadv_iv_ogm_primary_iface_set,
	.bat_ogm_schedule = batadv_iv_ogm_schedule,
	.bat_ogm_emit = batadv_iv_ogm_emit,
1947
	.bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
1948
	.bat_neigh_is_equiv_or_better = batadv_iv_ogm_neigh_is_eob,
1949
	.bat_orig_print = batadv_iv_ogm_orig_print,
1950 1951 1952
	.bat_orig_free = batadv_iv_ogm_orig_free,
	.bat_orig_add_if = batadv_iv_ogm_orig_add_if,
	.bat_orig_del_if = batadv_iv_ogm_orig_del_if,
1953 1954
};

1955
int __init batadv_iv_init(void)
1956
{
1957 1958 1959
	int ret;

	/* batman originator packet */
1960 1961
	ret = batadv_recv_handler_register(BATADV_IV_OGM,
					   batadv_iv_ogm_receive);
1962 1963 1964
	if (ret < 0)
		goto out;

1965
	ret = batadv_algo_register(&batadv_batman_iv);
1966 1967 1968 1969 1970 1971
	if (ret < 0)
		goto handler_unregister;

	goto out;

handler_unregister:
1972
	batadv_recv_handler_unregister(BATADV_IV_OGM);
1973 1974
out:
	return ret;
1975
}