routing.c 26.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 "routing.h"
#include "send.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "icmp_socket.h"
#include "translation-table.h"
#include "originator.h"
26
#include "bridge_loop_avoidance.h"
27
#include "distributed-arp-table.h"
28
#include "network-coding.h"
29
#include "fragmentation.h"
30

31 32
#include <linux/if_vlan.h>

33
static int batadv_route_unicast_packet(struct sk_buff *skb,
34
				       struct batadv_hard_iface *recv_if);
35

36 37 38
static void _batadv_update_route(struct batadv_priv *bat_priv,
				 struct batadv_orig_node *orig_node,
				 struct batadv_neigh_node *neigh_node)
39
{
40
	struct batadv_neigh_node *curr_router;
41

42
	curr_router = batadv_orig_node_get_router(orig_node);
43

44
	/* route deleted */
45
	if ((curr_router) && (!neigh_node)) {
46 47
		batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
			   "Deleting route towards: %pM\n", orig_node->orig);
48
		batadv_tt_global_del_orig(bat_priv, orig_node, -1,
49
					  "Deleted route towards originator");
50

51 52
	/* route added */
	} else if ((!curr_router) && (neigh_node)) {
53
		batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
54 55
			   "Adding route towards: %pM (via %pM)\n",
			   orig_node->orig, neigh_node->addr);
56
	/* route changed */
57
	} else if (neigh_node && curr_router) {
58
		batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
59 60 61
			   "Changing route towards: %pM (now via %pM - was via %pM)\n",
			   orig_node->orig, neigh_node->addr,
			   curr_router->addr);
62 63
	}

64
	if (curr_router)
65
		batadv_neigh_node_free_ref(curr_router);
66 67

	/* increase refcount of new best neighbor */
68 69
	if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount))
		neigh_node = NULL;
70 71 72 73 74 75 76

	spin_lock_bh(&orig_node->neigh_list_lock);
	rcu_assign_pointer(orig_node->router, neigh_node);
	spin_unlock_bh(&orig_node->neigh_list_lock);

	/* decrease refcount of previous best neighbor */
	if (curr_router)
77
		batadv_neigh_node_free_ref(curr_router);
78 79
}

80 81 82
void batadv_update_route(struct batadv_priv *bat_priv,
			 struct batadv_orig_node *orig_node,
			 struct batadv_neigh_node *neigh_node)
83
{
84
	struct batadv_neigh_node *router = NULL;
85 86

	if (!orig_node)
87 88
		goto out;

89
	router = batadv_orig_node_get_router(orig_node);
90

91
	if (router != neigh_node)
92
		_batadv_update_route(bat_priv, orig_node, neigh_node);
93 94 95

out:
	if (router)
96
		batadv_neigh_node_free_ref(router);
97 98 99 100 101 102 103
}

/* checks whether the host restarted and is in the protection time.
 * returns:
 *  0 if the packet is to be accepted
 *  1 if the packet is to be ignored.
 */
104
int batadv_window_protected(struct batadv_priv *bat_priv, int32_t seq_num_diff,
105
			    unsigned long *last_reset)
106
{
107 108 109 110
	if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE ||
	    seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) {
		if (!batadv_has_timed_out(*last_reset,
					  BATADV_RESET_PROTECTION_MS))
111
			return 1;
112 113

		*last_reset = jiffies;
114
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
115
			   "old packet received, start protection\n");
116
	}
117

118 119 120
	return 0;
}

121
bool batadv_check_management_packet(struct sk_buff *skb,
122
				    struct batadv_hard_iface *hard_iface,
123
				    int header_len)
124 125 126 127
{
	struct ethhdr *ethhdr;

	/* drop packet if it has not necessary minimum size */
128 129
	if (unlikely(!pskb_may_pull(skb, header_len)))
		return false;
130

131
	ethhdr = eth_hdr(skb);
132 133 134

	/* packet with broadcast indication but unicast recipient */
	if (!is_broadcast_ether_addr(ethhdr->h_dest))
135
		return false;
136 137 138

	/* packet with broadcast sender address */
	if (is_broadcast_ether_addr(ethhdr->h_source))
139
		return false;
140 141 142

	/* create a copy of the skb, if needed, to modify it. */
	if (skb_cow(skb, 0) < 0)
143
		return false;
144 145 146

	/* keep skb linear */
	if (skb_linearize(skb) < 0)
147
		return false;
148

149
	return true;
150 151
}

152 153 154 155 156 157 158 159
/**
 * batadv_recv_my_icmp_packet - receive an icmp packet locally
 * @bat_priv: the bat priv with all the soft interface information
 * @skb: icmp packet to process
 *
 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
 * otherwise.
 */
160
static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
161
				      struct sk_buff *skb)
162
{
163 164
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node = NULL;
165 166
	struct batadv_icmp_header *icmph;
	int res, ret = NET_RX_DROP;
167

168
	icmph = (struct batadv_icmp_header *)skb->data;
169

170 171 172 173 174 175 176
	switch (icmph->msg_type) {
	case BATADV_ECHO_REPLY:
	case BATADV_DESTINATION_UNREACHABLE:
	case BATADV_TTL_EXCEEDED:
		/* receive the packet */
		if (skb_linearize(skb) < 0)
			break;
177

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
		batadv_socket_receive_packet(icmph, skb->len);
		break;
	case BATADV_ECHO_REQUEST:
		/* answer echo request (ping) */
		primary_if = batadv_primary_if_get_selected(bat_priv);
		if (!primary_if)
			goto out;

		/* get routing information */
		orig_node = batadv_orig_hash_find(bat_priv, icmph->orig);
		if (!orig_node)
			goto out;

		/* create a copy of the skb, if needed, to modify it. */
		if (skb_cow(skb, ETH_HLEN) < 0)
			goto out;

		icmph = (struct batadv_icmp_header *)skb->data;

		memcpy(icmph->dst, icmph->orig, ETH_ALEN);
		memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
		icmph->msg_type = BATADV_ECHO_REPLY;
200
		icmph->ttl = BATADV_TTL;
201 202 203 204 205 206 207 208

		res = batadv_send_skb_to_orig(skb, orig_node, NULL);
		if (res != NET_XMIT_DROP)
			ret = NET_RX_SUCCESS;

		break;
	default:
		/* drop unknown type */
209
		goto out;
210
	}
211
out:
212
	if (primary_if)
213
		batadv_hardif_free_ref(primary_if);
214
	if (orig_node)
215
		batadv_orig_node_free_ref(orig_node);
216 217 218
	return ret;
}

219
static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
220
					 struct sk_buff *skb)
221
{
222 223
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node = NULL;
224
	struct batadv_icmp_packet *icmp_packet;
225
	int ret = NET_RX_DROP;
226

227
	icmp_packet = (struct batadv_icmp_packet *)skb->data;
228 229

	/* send TTL exceeded if packet is an echo request (traceroute) */
230
	if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) {
231
		pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
232
			 icmp_packet->orig, icmp_packet->dst);
233
		goto out;
234 235
	}

236
	primary_if = batadv_primary_if_get_selected(bat_priv);
237
	if (!primary_if)
238
		goto out;
239 240

	/* get routing information */
241
	orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig);
242
	if (!orig_node)
243
		goto out;
244

245
	/* create a copy of the skb, if needed, to modify it. */
246
	if (skb_cow(skb, ETH_HLEN) < 0)
247
		goto out;
248

249
	icmp_packet = (struct batadv_icmp_packet *)skb->data;
250

251 252
	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
	memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr,
253
	       ETH_ALEN);
254 255
	icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
	icmp_packet->ttl = BATADV_TTL;
256

257
	if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
258
		ret = NET_RX_SUCCESS;
259

260
out:
261
	if (primary_if)
262
		batadv_hardif_free_ref(primary_if);
263
	if (orig_node)
264
		batadv_orig_node_free_ref(orig_node);
265 266 267 268
	return ret;
}


269 270
int batadv_recv_icmp_packet(struct sk_buff *skb,
			    struct batadv_hard_iface *recv_if)
271
{
272
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
273 274
	struct batadv_icmp_header *icmph;
	struct batadv_icmp_packet_rr *icmp_packet_rr;
275
	struct ethhdr *ethhdr;
276
	struct batadv_orig_node *orig_node = NULL;
277
	int hdr_size = sizeof(struct batadv_icmp_header);
278
	int ret = NET_RX_DROP;
279 280 281

	/* drop packet if it has not necessary minimum size */
	if (unlikely(!pskb_may_pull(skb, hdr_size)))
282
		goto out;
283

284
	ethhdr = eth_hdr(skb);
285 286 287

	/* packet with unicast indication but broadcast recipient */
	if (is_broadcast_ether_addr(ethhdr->h_dest))
288
		goto out;
289 290 291

	/* packet with broadcast sender address */
	if (is_broadcast_ether_addr(ethhdr->h_source))
292
		goto out;
293 294

	/* not for me */
295
	if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
296
		goto out;
297

298
	icmph = (struct batadv_icmp_header *)skb->data;
299 300

	/* add record route information if not full */
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
	if ((icmph->msg_type == BATADV_ECHO_REPLY ||
	     icmph->msg_type == BATADV_ECHO_REQUEST) &&
	    (skb->len >= sizeof(struct batadv_icmp_packet_rr))) {
		if (skb_linearize(skb) < 0)
			goto out;

		/* create a copy of the skb, if needed, to modify it. */
		if (skb_cow(skb, ETH_HLEN) < 0)
			goto out;

		icmph = (struct batadv_icmp_header *)skb->data;
		icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
		if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
			goto out;

		memcpy(&(icmp_packet_rr->rr[icmp_packet_rr->rr_cur]),
317
		       ethhdr->h_dest, ETH_ALEN);
318
		icmp_packet_rr->rr_cur++;
319 320 321
	}

	/* packet for me */
322 323
	if (batadv_is_my_mac(bat_priv, icmph->dst))
		return batadv_recv_my_icmp_packet(bat_priv, skb);
324 325

	/* TTL exceeded */
326
	if (icmph->ttl < 2)
327
		return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
328 329

	/* get routing information */
330
	orig_node = batadv_orig_hash_find(bat_priv, icmph->dst);
331
	if (!orig_node)
332
		goto out;
333

334
	/* create a copy of the skb, if needed, to modify it. */
335
	if (skb_cow(skb, ETH_HLEN) < 0)
336
		goto out;
337

338
	icmph = (struct batadv_icmp_header *)skb->data;
339

340
	/* decrement ttl */
341
	icmph->ttl--;
342 343

	/* route it */
344
	if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
345
		ret = NET_RX_SUCCESS;
346

347 348
out:
	if (orig_node)
349
		batadv_orig_node_free_ref(orig_node);
350 351 352
	return ret;
}

353 354
/**
 * batadv_check_unicast_packet - Check for malformed unicast packets
355
 * @bat_priv: the bat priv with all the soft interface information
356 357 358 359 360 361 362 363
 * @skb: packet to check
 * @hdr_size: size of header to pull
 *
 * Check for short header and bad addresses in given packet. Returns negative
 * value when check fails and 0 otherwise. The negative value depends on the
 * reason: -ENODATA for bad header, -EBADR for broadcast destination or source,
 * and -EREMOTE for non-local (other host) destination.
 */
364 365
static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
				       struct sk_buff *skb, int hdr_size)
366 367 368 369 370
{
	struct ethhdr *ethhdr;

	/* drop packet if it has not necessary minimum size */
	if (unlikely(!pskb_may_pull(skb, hdr_size)))
371
		return -ENODATA;
372

373
	ethhdr = eth_hdr(skb);
374 375 376

	/* packet with unicast indication but broadcast recipient */
	if (is_broadcast_ether_addr(ethhdr->h_dest))
377
		return -EBADR;
378 379 380

	/* packet with broadcast sender address */
	if (is_broadcast_ether_addr(ethhdr->h_source))
381
		return -EBADR;
382 383

	/* not for me */
384
	if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
385
		return -EREMOTE;
386 387 388 389

	return 0;
}

390 391 392 393 394 395 396 397
/**
 * batadv_find_router - find a suitable router for this originator
 * @bat_priv: the bat priv with all the soft interface information
 * @orig_node: the destination node
 * @recv_if: pointer to interface this packet was received on
 *
 * Returns the router which should be used for this orig_node on
 * this interface, or NULL if not available.
398
 */
399 400 401 402
struct batadv_neigh_node *
batadv_find_router(struct batadv_priv *bat_priv,
		   struct batadv_orig_node *orig_node,
		   const struct batadv_hard_iface *recv_if)
403
{
404
	struct batadv_neigh_node *router;
405 406 407 408

	if (!orig_node)
		return NULL;

409
	router = batadv_orig_node_get_router(orig_node);
410

411 412
	/* TODO: fill this later with new bonding mechanism */

413 414 415
	return router;
}

416
static int batadv_route_unicast_packet(struct sk_buff *skb,
417
				       struct batadv_hard_iface *recv_if)
418
{
419 420
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
	struct batadv_orig_node *orig_node = NULL;
421
	struct batadv_unicast_packet *unicast_packet;
422
	struct ethhdr *ethhdr = eth_hdr(skb);
423
	int res, hdr_len, ret = NET_RX_DROP;
424

425
	unicast_packet = (struct batadv_unicast_packet *)skb->data;
426 427

	/* TTL exceeded */
428
	if (unicast_packet->ttl < 2) {
429 430
		pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
			 ethhdr->h_source, unicast_packet->dest);
431
		goto out;
432 433 434
	}

	/* get routing information */
435
	orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest);
436

437
	if (!orig_node)
438
		goto out;
439 440

	/* create a copy of the skb, if needed, to modify it. */
441
	if (skb_cow(skb, ETH_HLEN) < 0)
442
		goto out;
443 444

	/* decrement ttl */
445
	unicast_packet = (struct batadv_unicast_packet *)skb->data;
446
	unicast_packet->ttl--;
447

448
	switch (unicast_packet->packet_type) {
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
	case BATADV_UNICAST_4ADDR:
		hdr_len = sizeof(struct batadv_unicast_4addr_packet);
		break;
	case BATADV_UNICAST:
		hdr_len = sizeof(struct batadv_unicast_packet);
		break;
	default:
		/* other packet types not supported - yet */
		hdr_len = -1;
		break;
	}

	if (hdr_len > 0)
		batadv_skb_set_priority(skb, hdr_len);

464
	res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
465

466 467 468
	/* translate transmit result into receive result */
	if (res == NET_XMIT_SUCCESS) {
		/* skb was transmitted and consumed */
469 470 471
		batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
		batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
				   skb->len + ETH_HLEN);
472 473 474 475 476

		ret = NET_RX_SUCCESS;
	} else if (res == NET_XMIT_POLICED) {
		/* skb was buffered and consumed */
		ret = NET_RX_SUCCESS;
477
	}
478

479 480
out:
	if (orig_node)
481
		batadv_orig_node_free_ref(orig_node);
482
	return ret;
483 484
}

485 486 487 488 489
/**
 * batadv_reroute_unicast_packet - update the unicast header for re-routing
 * @bat_priv: the bat priv with all the soft interface information
 * @unicast_packet: the unicast header to be updated
 * @dst_addr: the payload destination
490
 * @vid: VLAN identifier
491 492 493 494 495 496 497 498 499 500
 *
 * Search the translation table for dst_addr and update the unicast header with
 * the new corresponding information (originator address where the destination
 * client currently is and its known TTVN)
 *
 * Returns true if the packet header has been updated, false otherwise
 */
static bool
batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
			      struct batadv_unicast_packet *unicast_packet,
501
			      uint8_t *dst_addr, unsigned short vid)
502 503 504 505 506 507
{
	struct batadv_orig_node *orig_node = NULL;
	struct batadv_hard_iface *primary_if = NULL;
	bool ret = false;
	uint8_t *orig_addr, orig_ttvn;

508
	if (batadv_is_my_client(bat_priv, dst_addr, vid)) {
509 510 511 512 513 514
		primary_if = batadv_primary_if_get_selected(bat_priv);
		if (!primary_if)
			goto out;
		orig_addr = primary_if->net_dev->dev_addr;
		orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
	} else {
515 516
		orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr,
						     vid);
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
		if (!orig_node)
			goto out;

		if (batadv_compare_eth(orig_node->orig, unicast_packet->dest))
			goto out;

		orig_addr = orig_node->orig;
		orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
	}

	/* update the packet header */
	memcpy(unicast_packet->dest, orig_addr, ETH_ALEN);
	unicast_packet->ttvn = orig_ttvn;

	ret = true;
out:
	if (primary_if)
		batadv_hardif_free_ref(primary_if);
	if (orig_node)
		batadv_orig_node_free_ref(orig_node);

	return ret;
}

541
static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
542
				     struct sk_buff *skb, int hdr_len) {
543 544
	struct batadv_unicast_packet *unicast_packet;
	struct batadv_hard_iface *primary_if;
545
	struct batadv_orig_node *orig_node;
546
	uint8_t curr_ttvn, old_ttvn;
547
	struct ethhdr *ethhdr;
548
	unsigned short vid;
549
	int is_old_ttvn;
550

551
	/* check if there is enough data before accessing it */
552
	if (pskb_may_pull(skb, hdr_len + ETH_HLEN) < 0)
553 554 555 556
		return 0;

	/* create a copy of the skb (in case of for re-routing) to modify it. */
	if (skb_cow(skb, sizeof(*unicast_packet)) < 0)
557 558
		return 0;

559
	unicast_packet = (struct batadv_unicast_packet *)skb->data;
560
	vid = batadv_get_vid(skb, hdr_len);
561
	ethhdr = (struct ethhdr *)(skb->data + hdr_len);
562

563 564 565 566 567
	/* check if the destination client was served by this node and it is now
	 * roaming. In this case, it means that the node has got a ROAM_ADV
	 * message and that it knows the new destination in the mesh to re-route
	 * the packet to
	 */
568
	if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
569
		if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
570
						  ethhdr->h_dest, vid))
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
			net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
						 bat_priv,
						 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
						 unicast_packet->dest,
						 ethhdr->h_dest);
		/* at this point the mesh destination should have been
		 * substituted with the originator address found in the global
		 * table. If not, let the packet go untouched anyway because
		 * there is nothing the node can do
		 */
		return 1;
	}

	/* retrieve the TTVN known by this node for the packet destination. This
	 * value is used later to check if the node which sent (or re-routed
	 * last time) the packet had an updated information or not
	 */
	curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
589
	if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
590 591
		orig_node = batadv_orig_hash_find(bat_priv,
						  unicast_packet->dest);
592 593 594 595
		/* if it is not possible to find the orig_node representing the
		 * destination, the packet can immediately be dropped as it will
		 * not be possible to deliver it
		 */
596 597 598 599
		if (!orig_node)
			return 0;

		curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
600
		batadv_orig_node_free_ref(orig_node);
601 602
	}

603 604 605
	/* check if the TTVN contained in the packet is fresher than what the
	 * node knows
	 */
606
	is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn);
607 608
	if (!is_old_ttvn)
		return 1;
609

610 611 612 613 614 615
	old_ttvn = unicast_packet->ttvn;
	/* the packet was forged based on outdated network information. Its
	 * destination can possibly be updated and forwarded towards the new
	 * target host
	 */
	if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
616
					  ethhdr->h_dest, vid)) {
617 618 619 620 621 622
		net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
					 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
					 unicast_packet->dest, ethhdr->h_dest,
					 old_ttvn, curr_ttvn);
		return 1;
	}
623

624 625 626 627
	/* the packet has not been re-routed: either the destination is
	 * currently served by this node or there is no destination at all and
	 * it is possible to drop the packet
	 */
628
	if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid))
629
		return 0;
630

631 632 633 634 635 636
	/* update the header in order to let the packet be delivered to this
	 * node's soft interface
	 */
	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (!primary_if)
		return 0;
637

638 639 640 641 642
	memcpy(unicast_packet->dest, primary_if->net_dev->dev_addr, ETH_ALEN);

	batadv_hardif_free_ref(primary_if);

	unicast_packet->ttvn = curr_ttvn;
643 644 645 646

	return 1;
}

647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
/**
 * batadv_recv_unhandled_unicast_packet - receive and process packets which
 *	are in the unicast number space but not yet known to the implementation
 * @skb: unicast tvlv packet to process
 * @recv_if: pointer to interface this packet was received on
 *
 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
 * otherwise.
 */
int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb,
					 struct batadv_hard_iface *recv_if)
{
	struct batadv_unicast_packet *unicast_packet;
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
	int check, hdr_size = sizeof(*unicast_packet);

	check = batadv_check_unicast_packet(bat_priv, skb, hdr_size);
	if (check < 0)
		return NET_RX_DROP;

	/* we don't know about this type, drop it. */
	unicast_packet = (struct batadv_unicast_packet *)skb->data;
	if (batadv_is_my_mac(bat_priv, unicast_packet->dest))
		return NET_RX_DROP;

	return batadv_route_unicast_packet(skb, recv_if);
}

675 676
int batadv_recv_unicast_packet(struct sk_buff *skb,
			       struct batadv_hard_iface *recv_if)
677
{
678
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
679
	struct batadv_unicast_packet *unicast_packet;
680
	struct batadv_unicast_4addr_packet *unicast_4addr_packet;
681 682
	uint8_t *orig_addr;
	struct batadv_orig_node *orig_node = NULL;
683
	int check, hdr_size = sizeof(*unicast_packet);
684
	bool is4addr;
685

686
	unicast_packet = (struct batadv_unicast_packet *)skb->data;
687
	unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
688

689
	is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
690
	/* the caller function should have already pulled 2 bytes */
691
	if (is4addr)
692
		hdr_size = sizeof(*unicast_4addr_packet);
693

694
	/* function returns -EREMOTE for promiscuous packets */
695
	check = batadv_check_unicast_packet(bat_priv, skb, hdr_size);
696 697 698 699 700 701 702 703

	/* Even though the packet is not for us, we might save it to use for
	 * decoding a later received coded packet
	 */
	if (check == -EREMOTE)
		batadv_nc_skb_store_sniffed_unicast(bat_priv, skb);

	if (check < 0)
704
		return NET_RX_DROP;
705
	if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
706 707
		return NET_RX_DROP;

708
	/* packet for me */
709
	if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
710
		if (is4addr) {
711 712
			batadv_dat_inc_counter(bat_priv,
					       unicast_4addr_packet->subtype);
713 714 715
			orig_addr = unicast_4addr_packet->src;
			orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
		}
716

717 718 719 720 721 722 723
		if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
							  hdr_size))
			goto rx_success;
		if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb,
							hdr_size))
			goto rx_success;

724
		batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
725
				    orig_node);
726

727
rx_success:
728 729 730
		if (orig_node)
			batadv_orig_node_free_ref(orig_node);

731 732 733
		return NET_RX_SUCCESS;
	}

734
	return batadv_route_unicast_packet(skb, recv_if);
735 736
}

737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
/**
 * batadv_recv_unicast_tvlv - receive and process unicast tvlv packets
 * @skb: unicast tvlv packet to process
 * @recv_if: pointer to interface this packet was received on
 * @dst_addr: the payload destination
 *
 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
 * otherwise.
 */
int batadv_recv_unicast_tvlv(struct sk_buff *skb,
			     struct batadv_hard_iface *recv_if)
{
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
	struct batadv_unicast_tvlv_packet *unicast_tvlv_packet;
	unsigned char *tvlv_buff;
	uint16_t tvlv_buff_len;
	int hdr_size = sizeof(*unicast_tvlv_packet);
	int ret = NET_RX_DROP;

	if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
		return NET_RX_DROP;

	/* the header is likely to be modified while forwarding */
	if (skb_cow(skb, hdr_size) < 0)
		return NET_RX_DROP;

	/* packet needs to be linearized to access the tvlv content */
	if (skb_linearize(skb) < 0)
		return NET_RX_DROP;

	unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)skb->data;

	tvlv_buff = (unsigned char *)(skb->data + hdr_size);
	tvlv_buff_len = ntohs(unicast_tvlv_packet->tvlv_len);

	if (tvlv_buff_len > skb->len - hdr_size)
		return NET_RX_DROP;

	ret = batadv_tvlv_containers_process(bat_priv, false, NULL,
					     unicast_tvlv_packet->src,
					     unicast_tvlv_packet->dst,
					     tvlv_buff, tvlv_buff_len);

	if (ret != NET_RX_SUCCESS)
		ret = batadv_route_unicast_packet(skb, recv_if);

	return ret;
}
785

786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
/**
 * batadv_recv_frag_packet - process received fragment
 * @skb: the received fragment
 * @recv_if: interface that the skb is received on
 *
 * This function does one of the three following things: 1) Forward fragment, if
 * the assembled packet will exceed our MTU; 2) Buffer fragment, if we till
 * lack further fragments; 3) Merge fragments, if we have all needed parts.
 *
 * Return NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise.
 */
int batadv_recv_frag_packet(struct sk_buff *skb,
			    struct batadv_hard_iface *recv_if)
{
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
	struct batadv_orig_node *orig_node_src = NULL;
	struct batadv_frag_packet *frag_packet;
	int ret = NET_RX_DROP;

	if (batadv_check_unicast_packet(bat_priv, skb,
					sizeof(*frag_packet)) < 0)
		goto out;

	frag_packet = (struct batadv_frag_packet *)skb->data;
	orig_node_src = batadv_orig_hash_find(bat_priv, frag_packet->orig);
	if (!orig_node_src)
		goto out;

	/* Route the fragment if it is not for us and too big to be merged. */
	if (!batadv_is_my_mac(bat_priv, frag_packet->dest) &&
	    batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) {
		ret = NET_RX_SUCCESS;
		goto out;
	}

	batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len);

	/* Add fragment to buffer and merge if possible. */
	if (!batadv_frag_skb_buffer(&skb, orig_node_src))
		goto out;

	/* Deliver merged packet to the appropriate handler, if it was
	 * merged
	 */
	if (skb)
		batadv_batman_skb_recv(skb, recv_if->net_dev,
				       &recv_if->batman_adv_ptype, NULL);

	ret = NET_RX_SUCCESS;

out:
	if (orig_node_src)
		batadv_orig_node_free_ref(orig_node_src);

	return ret;
}

844 845
int batadv_recv_bcast_packet(struct sk_buff *skb,
			     struct batadv_hard_iface *recv_if)
846
{
847 848
	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
	struct batadv_orig_node *orig_node = NULL;
849
	struct batadv_bcast_packet *bcast_packet;
850
	struct ethhdr *ethhdr;
851
	int hdr_size = sizeof(*bcast_packet);
852
	int ret = NET_RX_DROP;
853
	int32_t seq_diff;
854
	uint32_t seqno;
855 856 857

	/* drop packet if it has not necessary minimum size */
	if (unlikely(!pskb_may_pull(skb, hdr_size)))
858
		goto out;
859

860
	ethhdr = eth_hdr(skb);
861 862 863

	/* packet with broadcast indication but unicast recipient */
	if (!is_broadcast_ether_addr(ethhdr->h_dest))
864
		goto out;
865 866 867

	/* packet with broadcast sender address */
	if (is_broadcast_ether_addr(ethhdr->h_source))
868
		goto out;
869 870

	/* ignore broadcasts sent by myself */
871
	if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
872
		goto out;
873

874
	bcast_packet = (struct batadv_bcast_packet *)skb->data;
875 876

	/* ignore broadcasts originated by myself */
877
	if (batadv_is_my_mac(bat_priv, bcast_packet->orig))
878
		goto out;
879

880
	if (bcast_packet->ttl < 2)
881
		goto out;
882

883
	orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig);
884 885

	if (!orig_node)
886
		goto out;
887

888
	spin_lock_bh(&orig_node->bcast_seqno_lock);
889

890
	seqno = ntohl(bcast_packet->seqno);
891
	/* check whether the packet is a duplicate */
892
	if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno,
893
			    seqno))
894
		goto spin_unlock;
895

896
	seq_diff = seqno - orig_node->last_bcast_seqno;
897 898

	/* check whether the packet is old and the host just restarted. */
899 900
	if (batadv_window_protected(bat_priv, seq_diff,
				    &orig_node->bcast_seqno_reset))
901
		goto spin_unlock;
902 903

	/* mark broadcast in flood history, update window position
904 905
	 * if required.
	 */
906
	if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
907
		orig_node->last_bcast_seqno = seqno;
908

909 910
	spin_unlock_bh(&orig_node->bcast_seqno_lock);

911
	/* check whether this has been sent by another originator before */
912
	if (batadv_bla_check_bcast_duplist(bat_priv, skb))
913 914
		goto out;

915 916
	batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet));

917
	/* rebroadcast packet */
918
	batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
919

920 921 922
	/* don't hand the broadcast up if it is from an originator
	 * from the same backbone.
	 */
923
	if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size))
924 925
		goto out;

926 927 928 929 930
	if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
		goto rx_success;
	if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
		goto rx_success;

931
	/* broadcast for me */
932 933
	batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
			    orig_node);
934 935

rx_success:
936 937
	ret = NET_RX_SUCCESS;
	goto out;
938

939 940 941 942
spin_unlock:
	spin_unlock_bh(&orig_node->bcast_seqno_lock);
out:
	if (orig_node)
943
		batadv_orig_node_free_ref(orig_node);
944
	return ret;
945
}