Project

General

Profile

Bug #153 » 0001-Revert-batman-adv-improved-gateway-tq-based-selectio.patch

Revert gw filter patch - Anonymous, 09/01/2011 10:35 PM

View differences:

gateway_client.c
25 25
#include "gateway_common.h"
26 26
#include "hard-interface.h"
27 27
#include "originator.h"
28
#include "routing.h"
29 28
#include <linux/ip.h>
30 29
#include <linux/ipv6.h>
31 30
#include <linux/udp.h>
32 31
#include <linux/if_vlan.h>
33 32

  
34
/* This is the offset of the options field in a dhcp packet starting at
35
 * the beginning of the dhcp header */
36
#define DHCP_OPTIONS_OFFSET 240
37
#define DHCP_REQUEST 3
38

  
39 33
static void gw_node_free_ref(struct gw_node *gw_node)
40 34
{
41 35
	if (atomic_dec_and_test(&gw_node->refcount))
......
514 508
	return ret;
515 509
}
516 510

  
517
static bool is_type_dhcprequest(struct sk_buff *skb, int header_len)
518
{
519
	int ret = false;
520
	unsigned char *p;
521
	int pkt_len;
522

  
523
	if (skb_linearize(skb) < 0)
524
		goto out;
525

  
526
	pkt_len = skb_headlen(skb);
527

  
528
	if (pkt_len < header_len + DHCP_OPTIONS_OFFSET + 1)
529
		goto out;
530

  
531
	p = skb->data + header_len + DHCP_OPTIONS_OFFSET;
532
	pkt_len -= header_len + DHCP_OPTIONS_OFFSET + 1;
533

  
534
	/* Access the dhcp option lists. Each entry is made up by:
535
	 * - octect 1: option type
536
	 * - octect 2: option data len (only if type != 255 and 0)
537
	 * - octect 3: option data */
538
	while (*p != 255 && !ret) {
539
		/* p now points to the first octect: option type */
540
		if (*p == 53) {
541
			/* type 53 is the message type option.
542
			 * Jump the len octect and go to the data octect */
543
			if (pkt_len < 2)
544
				goto out;
545
			p += 2;
546

  
547
			/* check if the message type is what we need */
548
			if (*p == DHCP_REQUEST)
549
				ret = true;
550
			break;
551
		} else if (*p == 0) {
552
			/* option type 0 (padding), just go forward */
553
			if (pkt_len < 1)
554
				goto out;
555
			pkt_len--;
556
			p++;
557
		} else {
558
			/* This is any other option. So we get the length... */
559
			if (pkt_len < 1)
560
				goto out;
561
			pkt_len--;
562
			p++;
563

  
564
			/* ...and then we jump over the data */
565
			if (pkt_len < *p)
566
				goto out;
567
			pkt_len -= *p;
568
			p += (*p);
569
		}
570
	}
571
out:
572
	return ret;
573
}
574

  
575
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb,
576
		 struct orig_node *old_gw)
511
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
577 512
{
578 513
	struct ethhdr *ethhdr;
579 514
	struct iphdr *iphdr;
580 515
	struct ipv6hdr *ipv6hdr;
581 516
	struct udphdr *udphdr;
582 517
	struct gw_node *curr_gw;
583
	struct neigh_node *neigh_curr = NULL, *neigh_old = NULL;
584 518
	unsigned int header_len = 0;
585
	int ret = 1;
586 519

  
587 520
	if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
588 521
		return 0;
......
650 583
	if (!curr_gw)
651 584
		return 0;
652 585

  
653
	/* If old_gw != NULL then this packet is unicast.
654
	 * So, at this point we have to check the message type: if it is a
655
	 * DHCPREQUEST we have to decide whether to drop it or not */
656
	if (old_gw && curr_gw->orig_node != old_gw) {
657
		if (is_type_dhcprequest(skb, header_len)) {
658
			/* If the dhcp packet has been sent to a different gw,
659
			 * we have to evaluate whether the old gw is still
660
			 * reliable enough */
661
			neigh_curr = find_router(bat_priv, curr_gw->orig_node,
662
						 NULL);
663
			neigh_old = find_router(bat_priv, old_gw, NULL);
664
			if (!neigh_curr || !neigh_old)
665
				goto free_neigh;
666
			if (neigh_curr->tq_avg - neigh_old->tq_avg <
667
								GW_THRESHOLD)
668
				ret = -1;
669
		}
670
	}
671
free_neigh:
672
	if (neigh_old)
673
		neigh_node_free_ref(neigh_old);
674
	if (neigh_curr)
675
		neigh_node_free_ref(neigh_curr);
676 586
	if (curr_gw)
677 587
		gw_node_free_ref(curr_gw);
678
	return ret;
588
	return 1;
679 589
}
gateway_client.h
31 31
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node);
32 32
void gw_node_purge(struct bat_priv *bat_priv);
33 33
int gw_client_seq_print_text(struct seq_file *seq, void *offset);
34
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb,
35
		 struct orig_node *old_gw);
34
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb);
36 35

  
37 36
#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
main.h
92 92
#define BCAST_QUEUE_LEN		256
93 93
#define BATMAN_QUEUE_LEN	256
94 94

  
95

  
95 96
enum uev_action {
96 97
	UEV_ADD = 0,
97 98
	UEV_DEL,
......
102 103
	UEV_GW = 0
103 104
};
104 105

  
105
#define GW_THRESHOLD	50
106

  
107 106
/*
108 107
 * Debug Messages
109 108
 */
soft-interface.c
30 30
#include "gateway_common.h"
31 31
#include "gateway_client.h"
32 32
#include "bat_sysfs.h"
33
#include "originator.h"
34 33
#include <linux/slab.h>
35 34
#include <linux/ethtool.h>
36 35
#include <linux/etherdevice.h>
......
562 561
	struct bcast_packet *bcast_packet;
563 562
	struct vlan_ethhdr *vhdr;
564 563
	struct softif_neigh *curr_softif_neigh = NULL;
565
	struct orig_node *orig_node = NULL;
566 564
	int data_len = skb->len, ret;
567 565
	short vid = -1;
568 566
	bool do_bcast = false;
......
597 595
	/* Register the client MAC in the transtable */
598 596
	tt_local_add(soft_iface, ethhdr->h_source);
599 597

  
600
	orig_node = transtable_search(bat_priv, ethhdr->h_dest);
601
	if (is_multicast_ether_addr(ethhdr->h_dest) ||
602
				(orig_node && orig_node->gw_flags)) {
603
		ret = gw_is_target(bat_priv, skb, orig_node);
598
	if (is_multicast_ether_addr(ethhdr->h_dest)) {
599
		ret = gw_is_target(bat_priv, skb);
604 600

  
605 601
		if (ret < 0)
606 602
			goto dropped;
......
660 656
		softif_neigh_free_ref(curr_softif_neigh);
661 657
	if (primary_if)
662 658
		hardif_free_ref(primary_if);
663
	if (orig_node)
664
		orig_node_free_ref(orig_node);
665 659
	return NETDEV_TX_OK;
666 660
}
667 661

  
668
- 
(1-1/3)