bat_iv_ogm.c 49.7 KB
Newer Older
1
/* Copyright (C) 2007-2013 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44

/**
 * batadv_dup_status - duplicate status
 * @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,
};

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 86
/**
 * 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);
}
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
/**
 * 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;
	size_t data_size, old_size;
	int ret = -ENOMEM;

	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);

	data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS;
	old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS;
	data_ptr = kmalloc(data_size, GFP_ATOMIC);
	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;

	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
	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;
	data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
	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;

	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
	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 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
/**
 * 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)
		goto free_bcast_own;

	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)
		goto free_bcast_own;

	return orig_node;

free_bcast_own:
	kfree(orig_node->bat_iv.bcast_own);
free_orig_node:
	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;
270

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

275
	spin_lock_init(&neigh_node->bat_iv.lq_update_lock);
276

277 278 279
	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);
280 281 282 283 284 285 286 287 288

	spin_lock_bh(&orig_node->neigh_list_lock);
	hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
	spin_unlock_bh(&orig_node->neigh_list_lock);

out:
	return neigh_node;
}

289
static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
290
{
291
	struct batadv_ogm_packet *batadv_ogm_packet;
292
	unsigned char *ogm_buff;
293
	uint32_t random_seqno;
294
	int res = -ENOMEM;
295 296 297

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

300 301 302
	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)
303 304
		goto out;

305 306 307
	hard_iface->bat_iv.ogm_buff = ogm_buff;

	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
308 309 310
	batadv_ogm_packet->packet_type = BATADV_IV_OGM;
	batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
	batadv_ogm_packet->ttl = 2;
311
	batadv_ogm_packet->flags = BATADV_NO_FLAGS;
312
	batadv_ogm_packet->reserved = 0;
313
	batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
314 315 316 317 318

	res = 0;

out:
	return res;
319 320
}

321
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
322
{
323 324
	kfree(hard_iface->bat_iv.ogm_buff);
	hard_iface->bat_iv.ogm_buff = NULL;
325 326
}

327
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
328
{
329
	struct batadv_ogm_packet *batadv_ogm_packet;
330
	unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
331

332
	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
333
	memcpy(batadv_ogm_packet->orig,
334
	       hard_iface->net_dev->dev_addr, ETH_ALEN);
335
	memcpy(batadv_ogm_packet->prev_sender,
336
	       hard_iface->net_dev->dev_addr, ETH_ALEN);
337 338
}

339 340
static void
batadv_iv_ogm_primary_iface_set(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
	batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
347
	batadv_ogm_packet->ttl = BATADV_TTL;
348 349
}

350
/* when do we schedule our own ogm to be sent */
351
static unsigned long
352
batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
353
{
354 355 356
	unsigned int msecs;

	msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
357
	msecs += prandom_u32() % (2 * BATADV_JITTER);
358 359

	return jiffies + msecs_to_jiffies(msecs);
360 361 362
}

/* when do we schedule a ogm packet to be sent */
363
static unsigned long batadv_iv_ogm_fwd_send_time(void)
364
{
365
	return jiffies + msecs_to_jiffies(prandom_u32() % (BATADV_JITTER / 2));
366 367 368
}

/* apply hop penalty for a normal link */
369 370
static uint8_t batadv_hop_penalty(uint8_t tq,
				  const struct batadv_priv *bat_priv)
371 372
{
	int hop_penalty = atomic_read(&bat_priv->hop_penalty);
373 374 375 376 377 378
	int new_tq;

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

	return new_tq;
379 380
}

381
/* is there another aggregated packet here? */
382
static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
383
				     __be16 tvlv_len)
384
{
385 386
	int next_buff_pos = 0;

387
	next_buff_pos += buff_pos + BATADV_OGM_HLEN;
388
	next_buff_pos += ntohs(tvlv_len);
389 390

	return (next_buff_pos <= packet_len) &&
391
	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
392 393
}

394
/* send a batman ogm to a given interface */
395 396
static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
				     struct batadv_hard_iface *hard_iface)
397
{
398
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
399 400 401
	char *fwd_str;
	uint8_t packet_num;
	int16_t buff_pos;
402
	struct batadv_ogm_packet *batadv_ogm_packet;
403
	struct sk_buff *skb;
404
	uint8_t *packet_pos;
405

406
	if (hard_iface->if_status != BATADV_IF_ACTIVE)
407 408 409 410
		return;

	packet_num = 0;
	buff_pos = 0;
411 412
	packet_pos = forw_packet->skb->data;
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
413 414

	/* adjust all flags and log packets */
415
	while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
416
					 batadv_ogm_packet->tvlv_len)) {
417
		/* we might have aggregated direct link packets with an
418 419
		 * ordinary base packet
		 */
420 421
		if (forw_packet->direct_link_flags & BIT(packet_num) &&
		    forw_packet->if_incoming == hard_iface)
422
			batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
423
		else
424
			batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
425

426 427 428 429 430
		if (packet_num > 0 || !forw_packet->own)
			fwd_str = "Forwarding";
		else
			fwd_str = "Sending own";

431
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
432
			   "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
433
			   fwd_str, (packet_num > 0 ? "aggregated " : ""),
434 435
			   batadv_ogm_packet->orig,
			   ntohl(batadv_ogm_packet->seqno),
436
			   batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
437
			   (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
438
			    "on" : "off"),
439
			   hard_iface->net_dev->name,
440
			   hard_iface->net_dev->dev_addr);
441

442
		buff_pos += BATADV_OGM_HLEN;
443
		buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
444
		packet_num++;
445 446
		packet_pos = forw_packet->skb->data + buff_pos;
		batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
447 448 449 450
	}

	/* create clone because function is called more than once */
	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
451
	if (skb) {
452 453
		batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
		batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
454
				   skb->len + ETH_HLEN);
455
		batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
456
	}
457 458 459
}

/* send a batman ogm packet */
460
static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
461
{
462
	struct batadv_hard_iface *hard_iface;
463
	struct net_device *soft_iface;
464 465
	struct batadv_priv *bat_priv;
	struct batadv_hard_iface *primary_if = NULL;
466
	struct batadv_ogm_packet *batadv_ogm_packet;
467
	unsigned char directlink;
468
	uint8_t *packet_pos;
469

470 471
	packet_pos = forw_packet->skb->data;
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
472
	directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
473 474

	if (!forw_packet->if_incoming) {
475
		pr_err("Error - can't forward packet: incoming iface not specified\n");
476 477 478 479 480 481
		goto out;
	}

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

482
	if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
483 484
		goto out;

485
	primary_if = batadv_primary_if_get_selected(bat_priv);
486 487 488
	if (!primary_if)
		goto out;

489 490 491
	/* multihomed peer assumed
	 * non-primary OGMs are only broadcasted on their interface
	 */
492
	if ((directlink && (batadv_ogm_packet->ttl == 1)) ||
493 494
	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
		/* FIXME: what about aggregated packets ? */
495
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
496 497
			   "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
			   (forw_packet->own ? "Sending own" : "Forwarding"),
498 499
			   batadv_ogm_packet->orig,
			   ntohl(batadv_ogm_packet->seqno),
500
			   batadv_ogm_packet->ttl,
501 502
			   forw_packet->if_incoming->net_dev->name,
			   forw_packet->if_incoming->net_dev->dev_addr);
503 504

		/* skb is only used once and than forw_packet is free'd */
505 506
		batadv_send_skb_packet(forw_packet->skb,
				       forw_packet->if_incoming,
507
				       batadv_broadcast_addr);
508 509 510 511 512 513 514
		forw_packet->skb = NULL;

		goto out;
	}

	/* broadcast on every interface */
	rcu_read_lock();
515
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
516 517 518
		if (hard_iface->soft_iface != soft_iface)
			continue;

519
		batadv_iv_ogm_send_to_if(forw_packet, hard_iface);
520 521 522 523 524
	}
	rcu_read_unlock();

out:
	if (primary_if)
525
		batadv_hardif_free_ref(primary_if);
526 527 528
}

/* return true if new_packet can be aggregated with forw_packet */
529
static bool
530
batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
531
			    struct batadv_priv *bat_priv,
532 533
			    int packet_len, unsigned long send_time,
			    bool directlink,
534 535
			    const struct batadv_hard_iface *if_incoming,
			    const struct batadv_forw_packet *forw_packet)
536
{
537
	struct batadv_ogm_packet *batadv_ogm_packet;
538
	int aggregated_bytes = forw_packet->packet_len + packet_len;
539
	struct batadv_hard_iface *primary_if = NULL;
540
	bool res = false;
541
	unsigned long aggregation_end_time;
542

543
	batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
544 545
	aggregation_end_time = send_time;
	aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
546

547
	/* we can aggregate the current packet to this aggregated packet
548 549 550 551 552 553 554
	 * 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) &&
555 556
	    time_after_eq(aggregation_end_time, forw_packet->send_time) &&
	    (aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) {
557
		/* check aggregation compatibility
558 559 560 561 562 563
		 * -> 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
		 */
564
		primary_if = batadv_primary_if_get_selected(bat_priv);
565 566 567 568
		if (!primary_if)
			goto out;

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

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

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

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

out:
	if (primary_if)
605
		batadv_hardif_free_ref(primary_if);
606 607 608 609
	return res;
}

/* create a new aggregated packet and add this packet to it */
610 611 612
static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
					int packet_len, unsigned long send_time,
					bool direct_link,
613
					struct batadv_hard_iface *if_incoming,
614
					int own_packet)
615
{
616 617
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_forw_packet *forw_packet_aggr;
618
	unsigned char *skb_buff;
619
	unsigned int skb_size;
620 621 622 623 624 625

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

	/* own packet should always be scheduled */
	if (!own_packet) {
626
		if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
627
			batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
628
				   "batman packet queue full\n");
629 630 631 632 633 634 635 636 637 638 639 640
			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)) &&
641
	    (packet_len < BATADV_MAX_AGGREGATION_BYTES))
642
		skb_size = BATADV_MAX_AGGREGATION_BYTES;
643
	else
644 645
		skb_size = packet_len;

646
	skb_size += ETH_HLEN;
647

648
	forw_packet_aggr->skb = netdev_alloc_skb_ip_align(NULL, skb_size);
649 650 651 652 653 654
	if (!forw_packet_aggr->skb) {
		if (!own_packet)
			atomic_inc(&bat_priv->batman_queue_left);
		kfree(forw_packet_aggr);
		goto out;
	}
655
	forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
656
	skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
657 658 659 660 661 662 663 664

	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;
	forw_packet_aggr->num_packets = 0;
665
	forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
666 667 668 669 670 671 672 673 674 675 676 677 678
	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,
679
			  batadv_send_outstanding_bat_ogm_packet);
680
	queue_delayed_work(batadv_event_workqueue,
681 682 683 684 685
			   &forw_packet_aggr->delayed_work,
			   send_time - jiffies);

	return;
out:
686
	batadv_hardif_free_ref(if_incoming);
687 688 689
}

/* aggregate a new packet into the existing ogm packet */
690
static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
691 692
				    const unsigned char *packet_buff,
				    int packet_len, bool direct_link)
693 694
{
	unsigned char *skb_buff;
695
	unsigned long new_direct_link_flag;
696 697 698 699 700 701 702

	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 */
703 704 705 706
	if (direct_link) {
		new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
		forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
	}
707 708
}

709
static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
710 711
				    unsigned char *packet_buff,
				    int packet_len,
712
				    struct batadv_hard_iface *if_incoming,
713
				    int own_packet, unsigned long send_time)
714
{
715
	/* _aggr -> pointer to the packet we want to aggregate with
716 717
	 * _pos -> pointer to the position in the queue
	 */
718 719
	struct batadv_forw_packet *forw_packet_aggr = NULL;
	struct batadv_forw_packet *forw_packet_pos = NULL;
720
	struct batadv_ogm_packet *batadv_ogm_packet;
721
	bool direct_link;
722
	unsigned long max_aggregation_jiffies;
723

724 725
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
	direct_link = batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0;
726
	max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
727 728 729 730 731

	/* 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)) {
732
		hlist_for_each_entry(forw_packet_pos,
733
				     &bat_priv->forw_bat_list, list) {
734
			if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
735 736 737 738
							bat_priv, packet_len,
							send_time, direct_link,
							if_incoming,
							forw_packet_pos)) {
739 740 741 742 743 744 745
				forw_packet_aggr = forw_packet_pos;
				break;
			}
		}
	}

	/* nothing to aggregate with - either aggregation disabled or no
746 747
	 * suitable aggregation packet found
	 */
748 749 750 751
	if (!forw_packet_aggr) {
		/* the following section can run without the lock */
		spin_unlock_bh(&bat_priv->forw_bat_list_lock);

752
		/* if we could not aggregate this packet with one of the others
753 754 755
		 * we hold it back for a while, so that it might be aggregated
		 * later on
		 */
756 757
		if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
			send_time += max_aggregation_jiffies;
758

759 760 761
		batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
					    send_time, direct_link,
					    if_incoming, own_packet);
762
	} else {
763 764
		batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
					packet_len, direct_link);
765 766 767 768
		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
	}
}

769
static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
770
				  const struct ethhdr *ethhdr,
771
				  struct batadv_ogm_packet *batadv_ogm_packet,
772 773
				  bool is_single_hop_neigh,
				  bool is_from_best_next_hop,
774
				  struct batadv_hard_iface *if_incoming)
775
{
776
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
777
	uint16_t tvlv_len;
778

779
	if (batadv_ogm_packet->ttl <= 1) {
780
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
781 782 783
		return;
	}

784 785 786 787 788 789 790 791
	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)
792
			batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
793 794 795
		else
			return;
	}
796

797
	tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
798

799
	batadv_ogm_packet->ttl--;
800
	memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
801 802

	/* apply hop penalty */
803
	batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
804
						   bat_priv);
805

806
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
807
		   "Forwarding packet: tq: %i, ttl: %i\n",
808
		   batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
809 810

	/* switch of primaries first hop flag when forwarding */
811
	batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP;
812
	if (is_single_hop_neigh)
813
		batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
814
	else
815
		batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
816

817
	batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
818
				BATADV_OGM_HLEN + tvlv_len,
819
				if_incoming, 0, batadv_iv_ogm_fwd_send_time());
820 821
}

822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
/**
 * 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;
838
	int if_num;
839 840 841 842 843 844

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

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
845
			spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
846
			word_index = hard_iface->if_num * BATADV_NUM_WORDS;
847
			word = &(orig_node->bat_iv.bcast_own[word_index]);
848 849

			batadv_bit_get_packet(bat_priv, word, 1, 0);
850 851
			if_num = hard_iface->if_num;
			w = &orig_node->bat_iv.bcast_own_sum[if_num];
852
			*w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
853
			spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
854 855 856 857 858
		}
		rcu_read_unlock();
	}
}

859
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
860
{
861
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
862
	unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
863
	struct batadv_ogm_packet *batadv_ogm_packet;
864
	struct batadv_hard_iface *primary_if;
865
	int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
866
	uint32_t seqno;
867
	uint16_t tvlv_len = 0;
868

869
	primary_if = batadv_primary_if_get_selected(bat_priv);
870

871 872 873 874 875
	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);
876 877 878
		tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
							    ogm_buff_len,
							    BATADV_OGM_HLEN);
879
	}
880

881
	batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
882
	batadv_ogm_packet->tvlv_len = htons(tvlv_len);
883 884

	/* change sequence number to network order */
885
	seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
886
	batadv_ogm_packet->seqno = htonl(seqno);
887
	atomic_inc(&hard_iface->bat_iv.ogm_seqno);
888

889
	batadv_iv_ogm_slide_own_bcast_window(hard_iface);
890 891
	batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
				hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
892
				batadv_iv_ogm_emit_send_time(bat_priv));
893 894

	if (primary_if)
895
		batadv_hardif_free_ref(primary_if);
896 897
}

898
static void
899 900
batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
			  struct batadv_orig_node *orig_node,
901
			  const struct ethhdr *ethhdr,
902
			  const struct batadv_ogm_packet *batadv_ogm_packet,
903
			  struct batadv_hard_iface *if_incoming,
904
			  const unsigned char *tt_buff,
905
			  enum batadv_dup_status dup_status)
906
{
907 908 909
	struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
	struct batadv_neigh_node *router = NULL;
	struct batadv_orig_node *orig_node_tmp;
910
	int if_num;
911
	uint8_t sum_orig, sum_neigh;
912
	uint8_t *neigh_addr;
913
	uint8_t tq_avg;
914

915
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
916
		   "update_originator(): Searching and updating originator entry of received packet\n");
917 918

	rcu_read_lock();
919
	hlist_for_each_entry_rcu(tmp_neigh_node,
920
				 &orig_node->neigh_list, list) {
921 922 923 924
		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)) {
925
			if (WARN(neigh_node, "too many matching neigh_nodes"))
926
				batadv_neigh_node_free_ref(neigh_node);
927 928 929 930
			neigh_node = tmp_neigh_node;
			continue;
		}

931
		if (dup_status != BATADV_NO_DUP)
932 933
			continue;

934 935 936 937 938 939
		spin_lock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
		batadv_ring_buffer_set(tmp_neigh_node->bat_iv.tq_recv,
				       &tmp_neigh_node->bat_iv.tq_index, 0);
		tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->bat_iv.tq_recv);
		tmp_neigh_node->bat_iv.tq_avg = tq_avg;
		spin_unlock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
940 941 942
	}

	if (!neigh_node) {
943
		struct batadv_orig_node *orig_tmp;
944

945
		orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
946 947 948
		if (!orig_tmp)
			goto unlock;

949 950
		neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
						     ethhdr->h_source,
951
						     orig_node, orig_tmp);
952

953
		batadv_orig_node_free_ref(orig_tmp);
954 955 956
		if (!neigh_node)
			goto unlock;
	} else
957
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
958
			   "Updating existing last-hop neighbor of originator\n");
959 960 961

	rcu_read_unlock();

962
	neigh_node->last_seen = jiffies;
963

964 965 966
	spin_lock_bh(&neigh_node->bat_iv.lq_update_lock);
	batadv_ring_buffer_set(neigh_node->bat_iv.tq_recv,
			       &neigh_node->bat_iv.tq_index,
967
			       batadv_ogm_packet->tq);
968 969 970
	tq_avg = batadv_ring_buffer_avg(neigh_node->bat_iv.tq_recv);
	neigh_node->bat_iv.tq_avg = tq_avg;
	spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock);
971

972
	if (dup_status == BATADV_NO_DUP) {
973 974
		orig_node->last_ttl = batadv_ogm_packet->ttl;
		neigh_node->last_ttl = batadv_ogm_packet->ttl;
975 976 977
	}

	/* if this neighbor already is our next hop there is nothing
978 979
	 * to change
	 */
980
	router = batadv_orig_node_get_router(orig_node);
981
	if (router == neigh_node)
982
		goto out;
983 984

	/* if this neighbor does not offer a better TQ we won't consider it */
985
	if (router && (router->bat_iv.tq_avg > neigh_node->bat_iv.tq_avg))
986
		goto out;
987 988

	/* if the TQ is the same and the link not more symmetric we
989 990
	 * won't consider it either
	 */
991
	if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) {
992
		orig_node_tmp = router->orig_node;
993
		spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
994
		if_num = router->if_incoming->if_num;
995 996
		sum_orig = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
		spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
997 998

		orig_node_tmp = neigh_node->orig_node;
999
		spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1000
		if_num = neigh_node->if_incoming->if_num;
1001 1002
		sum_neigh = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
		spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
1003

1004
		if (sum_orig >= sum_neigh)
1005
			goto out;
1006 1007
	}

1008
	batadv_update_route(bat_priv, orig_node, neigh_node);
1009 1010 1011 1012 1013 1014
	goto out;

unlock:
	rcu_read_unlock();
out:
	if (neigh_node)
1015
		batadv_neigh_node_free_ref(neigh_node);
1016
	if (router)
1017
		batadv_neigh_node_free_ref(router);
1018 1019
}

1020 1021
static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
				 struct batadv_orig_node *orig_neigh_node,
1022
				 struct batadv_ogm_packet *batadv_ogm_packet,
1023
				 struct batadv_hard_iface *if_incoming)
1024
{
1025 1026
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
1027
	uint8_t total_count;
1028 1029
	uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
	unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1030
	int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
1031
	unsigned int combined_tq;
1032 1033 1034

	/* find corresponding one hop neighbor */
	rcu_read_lock();
1035
	hlist_for_each_entry_rcu(tmp_neigh_node,
1036
				 &orig_neigh_node->neigh_list, list) {
1037 1038
		if (!batadv_compare_eth(tmp_neigh_node->addr,
					orig_neigh_node->orig))
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
			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)
1053 1054 1055
		neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
						     orig_neigh_node->orig,
						     orig_neigh_node,
1056
						     orig_neigh_node);
1057 1058 1059 1060

	if (!neigh_node)
		goto out;

1061
	/* if orig_node is direct neighbor update neigh_node last_seen */
1062
	if (orig_node == orig_neigh_node)
1063
		neigh_node->last_seen = jiffies;
1064

1065
	orig_node->last_seen = jiffies;
1066 1067

	/* find packet count of corresponding one hop neighbor */
1068 1069 1070
	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];
1071
	neigh_rq_count = neigh_node->bat_iv.real_packet_count;
1072
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1073 1074

	/* pay attention to not get a value bigger than 100 % */
1075 1076 1077 1078
	if (orig_eq_count > neigh_rq_count)
		total_count = neigh_rq_count;
	else
		total_count = orig_eq_count;
1079

1080 1081 1082
	/* 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
	 */
1083 1084
	if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
	    neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
1085 1086 1087 1088
		tq_own = 0;
	else
		/* neigh_node->real_packet_count is never zero as we
		 * only purge old information when getting new
1089 1090
		 * information
		 */
1091
		tq_own = (BATADV_TQ_MAX_VALUE * total_count) /	neigh_rq_count;
1092

1093
	/* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
1094 1095 1096 1097
	 * affect the nearly-symmetric links only a little, but
	 * punishes asymmetric links more.  This will give a value
	 * between 0 and TQ_MAX_VALUE
	 */
1098 1099 1100 1101 1102 1103 1104 1105 1106
	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;

1107
	combined_tq = batadv_ogm_packet->tq * tq_own * tq_asym_penalty;
1108
	combined_tq /= BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE;
1109
	batadv_ogm_packet->tq = combined_tq;
1110

1111
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1112 1113 1114
		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
		   orig_node->orig, orig_neigh_node->orig, total_count,
		   neigh_rq_count, tq_own,
1115
		   tq_asym_penalty, batadv_ogm_packet->tq);
1116 1117

	/* if link has the minimum required transmission quality
1118 1119
	 * consider it bidirectional
	 */
1120
	if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
1121 1122 1123 1124
		ret = 1;

out:
	if (neigh_node)
1125
		batadv_neigh_node_free_ref(neigh_node);
1126 1127 1128
	return ret;
}

1129 1130 1131 1132 1133 1134 1135 1136
/**
 * 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
 *
 * Returns duplicate status as enum batadv_dup_status
1137
 */
1138
static enum batadv_dup_status
1139
batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1140
			    const struct batadv_ogm_packet *batadv_ogm_packet,
1141
			    const struct batadv_hard_iface *if_incoming)
1142
{
1143 1144 1145
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_orig_node *orig_node;
	struct batadv_neigh_node *tmp_neigh_node;
1146
	int is_dup;
1147 1148
	int32_t seq_diff;
	int need_update = 0;
1149 1150
	int set_mark;
	enum batadv_dup_status ret = BATADV_NO_DUP;
1151
	uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
1152
	uint8_t *neigh_addr;
1153
	uint8_t packet_count;
1154
	unsigned long *bitmap;
1155

1156
	orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1157
	if (!orig_node)
1158
		return BATADV_NO_DUP;
1159

1160
	spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1161
	seq_diff = seqno - orig_node->last_real_seqno;
1162 1163

	/* signalize caller that the packet is to be dropped. */
1164
	if (!hlist_empty(&orig_node->neigh_list) &&
1165
	    batadv_window_protected(bat_priv, seq_diff,
1166 1167
				    &orig_node->batman_seqno_reset)) {
		ret = BATADV_PROTECTED;
1168
		goto out;
1169
	}
1170 1171

	rcu_read_lock();
1172
	hlist_for_each_entry_rcu(tmp_neigh_node,
1173
				 &orig_node->neigh_list, list) {
1174
		neigh_addr = tmp_neigh_node->addr;
1175
		is_dup = batadv_test_bit(tmp_neigh_node->bat_iv.real_bits,
1176 1177 1178
					 orig_node->last_real_seqno,
					 seqno);

1179
		if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1180
		    tmp_neigh_node->if_incoming == if_incoming) {
1181
			set_mark = 1;
1182 1183 1184
			if (is_dup)
				ret = BATADV_NEIGH_DUP;
		} else {
1185
			set_mark = 0;
1186 1187 1188
			if (is_dup && (ret != BATADV_NEIGH_DUP))
				ret = BATADV_ORIG_DUP;
		}
1189 1190

		/* if the window moved, set the update flag. */
1191 1192
		bitmap = tmp_neigh_node->bat_iv.real_bits;
		need_update |= batadv_bit_get_packet(bat_priv, bitmap,
1193
						     seq_diff, set_mark);
1194

1195
		packet_count = bitmap_weight(tmp_neigh_node->bat_iv.real_bits,
1196
					     BATADV_TQ_LOCAL_WINDOW_SIZE);
1197
		tmp_neigh_node->bat_iv.real_packet_count = packet_count;
1198 1199 1200 1201
	}
	rcu_read_unlock();

	if (need_update) {
1202
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1203 1204
			   "updating last_seqno: old %u, new %u\n",
			   orig_node->last_real_seqno, seqno);
1205
		orig_node->last_real_seqno = seqno;
1206 1207 1208
	}

out:
1209
	spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1210
	batadv_orig_node_free_ref(orig_node);
1211 1212 1213
	return ret;
}

1214
static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1215
				  struct batadv_ogm_packet *batadv_ogm_packet,
1216
				  const unsigned char *tt_buff,
1217
				  struct batadv_hard_iface *if_incoming)
1218
{
1219 1220
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_hard_iface *hard_iface;
1221
	struct batadv_orig_node *orig_neigh_node, *orig_node, *orig_node_tmp;
1222 1223
	struct batadv_neigh_node *router = NULL, *router_router = NULL;
	struct batadv_neigh_node *orig_neigh_router = NULL;
1224 1225
	int has_directlink_flag;
	int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
1226
	int is_bidirect;
1227
	bool is_single_hop_neigh = false;
1228
	bool is_from_best_next_hop = false;
1229 1230
	int sameseq, similar_ttl;
	enum batadv_dup_status dup_status;
1231
	uint32_t if_incoming_seqno;
1232
	uint8_t *prev_sender;
1233 1234 1235 1236 1237 1238 1239 1240 1241

	/* 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
1242
	 * batadv_ogm_packet to detect whether the packet is the last
1243 1244 1245
	 * packet in an aggregation.  Here we expect that the padding
	 * is always zero (or not 0x01)
	 */
1246
	if (batadv_ogm_packet->packet_type != BATADV_IV_OGM)
1247 1248 1249
		return;

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

1252
	if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
1253 1254 1255
		has_directlink_flag = 1;
	else
		has_directlink_flag = 0;
1256

1257
	if (batadv_compare_eth(ethhdr->h_source, batadv_ogm_packet->orig))
1258
		is_single_hop_neigh = true;
1259

1260
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1261
		   "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",
1262
		   ethhdr->h_source, if_incoming->net_dev->name,
1263 1264
		   if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
		   batadv_ogm_packet->prev_sender,
1265
		   ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
1266 1267
		   batadv_ogm_packet->ttl,
		   batadv_ogm_packet->version, has_directlink_flag);
1268 1269

	rcu_read_lock();
1270
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1271
		if (hard_iface->if_status != BATADV_IF_ACTIVE)
1272 1273 1274 1275 1276
			continue;

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

1277 1278
		if (batadv_compare_eth(ethhdr->h_source,
				       hard_iface->net_dev->dev_addr))
1279 1280
			is_my_addr = 1;

1281
		if (batadv_compare_eth(batadv_ogm_packet->orig,
1282
				       hard_iface->net_dev->dev_addr))
1283 1284
			is_my_orig = 1;

1285
		if (batadv_compare_eth(batadv_ogm_packet->prev_sender,
1286
				       hard_iface->net_dev->dev_addr))
1287 1288 1289 1290 1291
			is_my_oldorig = 1;
	}
	rcu_read_unlock();

	if (is_my_addr) {
1292
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1293 1294
			   "Drop packet: received my own broadcast (sender: %pM)\n",
			   ethhdr->h_source);
1295 1296 1297 1298 1299 1300
		return;
	}

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

1305 1306
		orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
							 ethhdr->h_source);
1307 1308 1309 1310
		if (!orig_neigh_node)
			return;

		/* neighbor has to indicate direct link and it has to
1311 1312 1313
		 * come via the corresponding interface
		 * save packet seqno for bidirectional check
		 */
1314
		if (has_directlink_flag &&
1315
		    batadv_compare_eth(if_incoming->net_dev->dev_addr,
1316
				       batadv_ogm_packet->orig)) {
1317 1318
			if_num = if_incoming->if_num;
			offset = if_num * BATADV_NUM_WORDS;
1319

1320 1321
			spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
			word = &(orig_neigh_node->bat_iv.bcast_own[offset]);
1322
			bit_pos = if_incoming_seqno - 2;
1323
			bit_pos -= ntohl(batadv_ogm_packet->seqno);
1324
			batadv_set_bit(word, bit_pos);
1325
			weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num];
1326 1327
			*weight = bitmap_weight(word,
						BATADV_TQ_LOCAL_WINDOW_SIZE);
1328
			spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1329 1330
		}

1331
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1332
			   "Drop packet: originator packet from myself (via neighbor)\n");
1333
		batadv_orig_node_free_ref(orig_neigh_node);
1334 1335 1336 1337
		return;
	}

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

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

1351
	orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1352 1353 1354
	if (!orig_node)
		return;

1355 1356
	dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
						 if_incoming);
1357

1358
	if (dup_status == BATADV_PROTECTED) {
1359
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1360 1361
			   "Drop packet: packet within seqno protection time (sender: %pM)\n",
			   ethhdr->h_source);
1362 1363 1364
		goto out;
	}

1365
	if (batadv_ogm_packet->tq == 0) {
1366
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1367
			   "Drop packet: originator packet with tq equal 0\n");
1368 1369 1370
		goto out;
	}

1371
	router = batadv_orig_node_get_router(orig_node);
1372 1373 1374 1375
	if (router) {
		orig_node_tmp = router->orig_node;
		router_router = batadv_orig_node_get_router(orig_node_tmp);
	}
1376

1377
	if ((router && router->bat_iv.tq_avg != 0) &&
1378
	    (batadv_compare_eth(router->addr, ethhdr->h_source)))
1379 1380
		is_from_best_next_hop = true;

1381
	prev_sender = batadv_ogm_packet->prev_sender;
1382 1383
	/* avoid temporary routing loops */
	if (router && router_router &&
1384
	    (batadv_compare_eth(router->addr, prev_sender)) &&
1385
	    !(batadv_compare_eth(batadv_ogm_packet->orig, prev_sender)) &&
1386
	    (batadv_compare_eth(router->addr, router_router->addr))) {
1387
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1388 1389
			   "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
			   ethhdr->h_source);
1390 1391 1392
		goto out;
	}

1393 1394
	batadv_tvlv_ogm_receive(bat_priv, batadv_ogm_packet, orig_node);

1395
	/* if sender is a direct neighbor the sender mac equals
1396 1397
	 * originator mac
	 */
1398 1399 1400
	if (is_single_hop_neigh)
		orig_neigh_node = orig_node;
	else
1401 1402
		orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
							 ethhdr->h_source);
1403

1404 1405 1406
	if (!orig_neigh_node)
		goto out;

1407 1408 1409 1410
	/* Update nc_nodes of the originator */
	batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
				 batadv_ogm_packet, is_single_hop_neigh);

1411
	orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node);
1412 1413

	/* drop packet if sender is not a direct neighbor and if we
1414 1415
	 * don't route towards it
	 */
1416
	if (!is_single_hop_neigh && (!orig_neigh_router)) {
1417
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1418
			   "Drop packet: OGM via unknown neighbor!\n");
1419 1420 1421
		goto out_neigh;
	}

1422
	is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1423
					    batadv_ogm_packet, if_incoming);
1424 1425

	/* update ranking if it is not a duplicate or has the same
1426 1427
	 * seqno and similar ttl as the non-duplicate
	 */
1428
	sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
1429
	similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->ttl;
1430 1431
	if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
			    (sameseq && similar_ttl)))
1432
		batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
1433
					  batadv_ogm_packet, if_incoming,
1434
					  tt_buff, dup_status);
1435 1436 1437 1438

	/* is single hop (direct) neighbor */
	if (is_single_hop_neigh) {
		/* mark direct link on incoming interface */
1439
		batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet,
1440 1441
				      is_single_hop_neigh,
				      is_from_best_next_hop, if_incoming);
1442

1443
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1444
			   "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1445 1446 1447 1448
		goto out_neigh;
	}

	/* multihop originator */
1449
	if (!is_bidirect) {
1450
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1451
			   "Drop packet: not received via bidirectional link\n");
1452 1453 1454
		goto out_neigh;
	}

1455
	if (dup_status == BATADV_NEIGH_DUP) {
1456
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1457
			   "Drop packet: duplicate packet received\n");
1458 1459 1460
		goto out_neigh;
	}

1461
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1462
		   "Forwarding packet: rebroadcast originator packet\n");
1463
	batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet,
1464 1465
			      is_single_hop_neigh, is_from_best_next_hop,
			      if_incoming);
1466 1467 1468

out_neigh:
	if ((orig_neigh_node) && (!is_single_hop_neigh))
1469
		batadv_orig_node_free_ref(orig_neigh_node);
1470 1471
out:
	if (router)
1472
		batadv_neigh_node_free_ref(router);
1473
	if (router_router)
1474
		batadv_neigh_node_free_ref(router_router);
1475
	if (orig_neigh_router)
1476
		batadv_neigh_node_free_ref(orig_neigh_router);
1477

1478
	batadv_orig_node_free_ref(orig_node);
1479 1480
}

1481
static int batadv_iv_ogm_receive(struct sk_buff *skb,
1482
				 struct batadv_hard_iface *if_incoming)
1483
{
1484
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1485
	struct batadv_ogm_packet *batadv_ogm_packet;
1486 1487
	struct ethhdr *ethhdr;
	int buff_pos = 0, packet_len;
1488
	unsigned char *tvlv_buff, *packet_buff;
1489
	uint8_t *packet_pos;
1490
	bool ret;
1491

1492
	ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1493 1494
	if (!ret)
		return NET_RX_DROP;
1495

1496 1497 1498
	/* 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 ?
	 */
1499
	if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit)
1500 1501
		return NET_RX_DROP;

1502 1503
	batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1504 1505
			   skb->len + ETH_HLEN);

1506
	packet_len = skb_headlen(skb);
1507
	ethhdr = eth_hdr(skb);
1508
	packet_buff = skb->data;
1509
	batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
1510 1511

	/* unpack the aggregated packets and process them one by one */
1512
	while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
1513 1514
					 batadv_ogm_packet->tvlv_len)) {
		tvlv_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
1515

1516 1517
		batadv_iv_ogm_process(ethhdr, batadv_ogm_packet,
				      tvlv_buff, if_incoming);
1518

1519
		buff_pos += BATADV_OGM_HLEN;
1520
		buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
1521

1522 1523
		packet_pos = packet_buff + buff_pos;
		batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1524
	}
1525 1526 1527

	kfree_skb(skb);
	return NET_RX_SUCCESS;
1528
}
1529

1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 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
/**
 * 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
 */
static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
				     struct seq_file *seq)
{
	struct batadv_neigh_node *neigh_node, *neigh_node_tmp;
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	int last_seen_msecs, last_seen_secs;
	struct batadv_orig_node *orig_node;
	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) {
			neigh_node = batadv_orig_node_get_router(orig_node);
			if (!neigh_node)
				continue;

			if (neigh_node->bat_iv.tq_avg == 0)
				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,
				   last_seen_msecs, neigh_node->bat_iv.tq_avg,
				   neigh_node->addr,
				   neigh_node->if_incoming->net_dev->name);

			hlist_for_each_entry_rcu(neigh_node_tmp,
						 &orig_node->neigh_list, list) {
				seq_printf(seq, " %pM (%3i)",
					   neigh_node_tmp->addr,
					   neigh_node_tmp->bat_iv.tq_avg);
			}

			seq_puts(seq, "\n");
			batman_count++;

next:
			batadv_neigh_node_free_ref(neigh_node);
		}
		rcu_read_unlock();
	}

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

1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
/**
 * batadv_iv_ogm_neigh_cmp - compare the metrics of two neighbors
 * @neigh1: the first neighbor object of the comparison
 * @neigh2: the second neighbor object of the comparison
 *
 * 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,
				   struct batadv_neigh_node *neigh2)
{
	uint8_t tq1, tq2;

	tq1 = neigh1->bat_iv.tq_avg;
	tq2 = neigh2->bat_iv.tq_avg;

	return tq1 - tq2;
}

1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
/**
 * 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
 * @neigh2: the second neighbor object of the comparison
 *
 * Returns true if the metric via neigh1 is equally good or better than the
 * metric via neigh2, false otherwise.
 */
static bool batadv_iv_ogm_neigh_is_eob(struct batadv_neigh_node *neigh1,
				       struct batadv_neigh_node *neigh2)
{
	int diff = batadv_iv_ogm_neigh_cmp(neigh1, neigh2);

	return diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
}

1630
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
1631
	.name = "BATMAN_IV",
1632 1633 1634 1635 1636 1637
	.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,
1638
	.bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
1639
	.bat_neigh_is_equiv_or_better = batadv_iv_ogm_neigh_is_eob,
1640
	.bat_orig_print = batadv_iv_ogm_orig_print,
1641 1642 1643
	.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,
1644 1645
};

1646
int __init batadv_iv_init(void)
1647
{
1648 1649 1650
	int ret;

	/* batman originator packet */
1651 1652
	ret = batadv_recv_handler_register(BATADV_IV_OGM,
					   batadv_iv_ogm_receive);
1653 1654 1655
	if (ret < 0)
		goto out;

1656
	ret = batadv_algo_register(&batadv_batman_iv);
1657 1658 1659 1660 1661 1662
	if (ret < 0)
		goto handler_unregister;

	goto out;

handler_unregister:
1663
	batadv_recv_handler_unregister(BATADV_IV_OGM);
1664 1665
out:
	return ret;
1666
}