Skip to content

Commit

Permalink
Merge branch 'for_david' of git://git.open-mesh.org/linux-merge
Browse files Browse the repository at this point in the history
  • Loading branch information
David S. Miller committed Nov 26, 2011
2 parents 6f39da2 + 76e8d7b commit d6f03f2
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 182 deletions.
4 changes: 2 additions & 2 deletions net/batman-adv/bat_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static int store_uint_attr(const char *buff, size_t count,
unsigned long uint_val;
int ret;

ret = strict_strtoul(buff, 10, &uint_val);
ret = kstrtoul(buff, 10, &uint_val);
if (ret) {
bat_info(net_dev,
"%s: Invalid parameter received: %s\n",
Expand Down Expand Up @@ -239,7 +239,7 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
unsigned long val;
int ret, vis_mode_tmp = -1;

ret = strict_strtoul(buff, 10, &val);
ret = kstrtoul(buff, 10, &val);

if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
(strncmp(buff, "client", 6) == 0) ||
Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/bitarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ int bit_get_packet(void *priv, unsigned long *seq_bits,
/* sequence number is much newer, probably missed a lot of packets */

if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
&& (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
bat_dbg(DBG_BATMAN, bat_priv,
"We missed a lot of packets (%i) !\n",
seq_num_diff - 1);
Expand Down
153 changes: 94 additions & 59 deletions net/batman-adv/gateway_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "gateway_common.h"
#include "hard-interface.h"
#include "originator.h"
#include "translation-table.h"
#include "routing.h"
#include <linux/ip.h>
#include <linux/ipv6.h>
Expand Down Expand Up @@ -572,108 +573,142 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len)
return ret;
}

int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb,
struct orig_node *old_gw)
bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
{
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
struct gw_node *curr_gw;
struct neigh_node *neigh_curr = NULL, *neigh_old = NULL;
unsigned int header_len = 0;
int ret = 1;

if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
return 0;

/* check for ethernet header */
if (!pskb_may_pull(skb, header_len + ETH_HLEN))
return 0;
if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
return false;
ethhdr = (struct ethhdr *)skb->data;
header_len += ETH_HLEN;
*header_len += ETH_HLEN;

/* check for initial vlan header */
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
return 0;
if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
return false;
ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
header_len += VLAN_HLEN;
*header_len += VLAN_HLEN;
}

/* check for ip header */
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_IP:
if (!pskb_may_pull(skb, header_len + sizeof(*iphdr)))
return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;
if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
return false;
iphdr = (struct iphdr *)(skb->data + *header_len);
*header_len += iphdr->ihl * 4;

/* check for udp header */
if (iphdr->protocol != IPPROTO_UDP)
return 0;
return false;

break;
case ETH_P_IPV6:
if (!pskb_may_pull(skb, header_len + sizeof(*ipv6hdr)))
return 0;
ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
header_len += sizeof(*ipv6hdr);
if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
return false;
ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
*header_len += sizeof(*ipv6hdr);

/* check for udp header */
if (ipv6hdr->nexthdr != IPPROTO_UDP)
return 0;
return false;

break;
default:
return 0;
return false;
}

if (!pskb_may_pull(skb, header_len + sizeof(*udphdr)))
return 0;
udphdr = (struct udphdr *)(skb->data + header_len);
header_len += sizeof(*udphdr);
if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
return false;
udphdr = (struct udphdr *)(skb->data + *header_len);
*header_len += sizeof(*udphdr);

/* check for bootp port */
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
(ntohs(udphdr->dest) != 67))
return 0;
return false;

if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
(ntohs(udphdr->dest) != 547))
return 0;
return false;

if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
return -1;
return true;
}

curr_gw = gw_get_selected_gw_node(bat_priv);
if (!curr_gw)
return 0;

/* If old_gw != NULL then this packet is unicast.
* So, at this point we have to check the message type: if it is a
* DHCPREQUEST we have to decide whether to drop it or not */
if (old_gw && curr_gw->orig_node != old_gw) {
if (is_type_dhcprequest(skb, header_len)) {
/* If the dhcp packet has been sent to a different gw,
* we have to evaluate whether the old gw is still
* reliable enough */
neigh_curr = find_router(bat_priv, curr_gw->orig_node,
NULL);
neigh_old = find_router(bat_priv, old_gw, NULL);
if (!neigh_curr || !neigh_old)
goto free_neigh;
if (neigh_curr->tq_avg - neigh_old->tq_avg <
GW_THRESHOLD)
ret = -1;
}
bool gw_out_of_range(struct bat_priv *bat_priv,
struct sk_buff *skb, struct ethhdr *ethhdr)
{
struct neigh_node *neigh_curr = NULL, *neigh_old = NULL;
struct orig_node *orig_dst_node = NULL;
struct gw_node *curr_gw = NULL;
bool ret, out_of_range = false;
unsigned int header_len = 0;
uint8_t curr_tq_avg;

ret = gw_is_dhcp_target(skb, &header_len);
if (!ret)
goto out;

orig_dst_node = transtable_search(bat_priv, ethhdr->h_source,
ethhdr->h_dest);
if (!orig_dst_node)
goto out;

if (!orig_dst_node->gw_flags)
goto out;

ret = is_type_dhcprequest(skb, header_len);
if (!ret)
goto out;

switch (atomic_read(&bat_priv->gw_mode)) {
case GW_MODE_SERVER:
/* If we are a GW then we are our best GW. We can artificially
* set the tq towards ourself as the maximum value */
curr_tq_avg = TQ_MAX_VALUE;
break;
case GW_MODE_CLIENT:
curr_gw = gw_get_selected_gw_node(bat_priv);
if (!curr_gw)
goto out;

/* packet is going to our gateway */
if (curr_gw->orig_node == orig_dst_node)
goto out;

/* If the dhcp packet has been sent to a different gw,
* we have to evaluate whether the old gw is still
* reliable enough */
neigh_curr = find_router(bat_priv, curr_gw->orig_node, NULL);
if (!neigh_curr)
goto out;

curr_tq_avg = neigh_curr->tq_avg;
break;
case GW_MODE_OFF:
default:
goto out;
}
free_neigh:

neigh_old = find_router(bat_priv, orig_dst_node, NULL);
if (!!neigh_old)
goto out;

if (curr_tq_avg - neigh_old->tq_avg > GW_THRESHOLD)
out_of_range = true;

out:
if (orig_dst_node)
orig_node_free_ref(orig_dst_node);
if (curr_gw)
gw_node_free_ref(curr_gw);
if (neigh_old)
neigh_node_free_ref(neigh_old);
if (neigh_curr)
neigh_node_free_ref(neigh_curr);
if (curr_gw)
gw_node_free_ref(curr_gw);
return ret;
return out_of_range;
}
5 changes: 3 additions & 2 deletions net/batman-adv/gateway_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ void gw_node_update(struct bat_priv *bat_priv,
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node);
void gw_node_purge(struct bat_priv *bat_priv);
int gw_client_seq_print_text(struct seq_file *seq, void *offset);
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb,
struct orig_node *old_gw);
bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len);
bool gw_out_of_range(struct bat_priv *bat_priv,
struct sk_buff *skb, struct ethhdr *ethhdr);

#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
4 changes: 2 additions & 2 deletions net/batman-adv/gateway_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
*tmp_ptr = '\0';
}

ret = strict_strtol(buff, 10, &ldown);
ret = kstrtol(buff, 10, &ldown);
if (ret) {
bat_err(net_dev,
"Download speed of gateway mode invalid: %s\n",
Expand All @@ -122,7 +122,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
*tmp_ptr = '\0';
}

ret = strict_strtol(slash_ptr + 1, 10, &lup);
ret = kstrtol(slash_ptr + 1, 10, &lup);
if (ret) {
bat_err(net_dev,
"Upload speed of gateway mode invalid: "
Expand Down
4 changes: 2 additions & 2 deletions net/batman-adv/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/* clears the hash */
static void hash_init(struct hashtable_t *hash)
{
int i;
uint32_t i;

for (i = 0 ; i < hash->size; i++) {
INIT_HLIST_HEAD(&hash->table[i]);
Expand All @@ -42,7 +42,7 @@ void hash_destroy(struct hashtable_t *hash)
}

/* allocates and clears the hash */
struct hashtable_t *hash_new(int size)
struct hashtable_t *hash_new(uint32_t size)
{
struct hashtable_t *hash;

Expand Down
13 changes: 7 additions & 6 deletions net/batman-adv/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ typedef int (*hashdata_compare_cb)(const struct hlist_node *, const void *);
/* the hashfunction, should return an index
* based on the key in the data of the first
* argument and the size the second */
typedef int (*hashdata_choose_cb)(const void *, int);
typedef uint32_t (*hashdata_choose_cb)(const void *, uint32_t);
typedef void (*hashdata_free_cb)(struct hlist_node *, void *);

struct hashtable_t {
struct hlist_head *table; /* the hashtable itself with the buckets */
spinlock_t *list_locks; /* spinlock for each hash list entry */
int size; /* size of hashtable */
uint32_t size; /* size of hashtable */
};

/* allocates and clears the hash */
struct hashtable_t *hash_new(int size);
struct hashtable_t *hash_new(uint32_t size);

/* free only the hashtable and the hash itself. */
void hash_destroy(struct hashtable_t *hash);
Expand All @@ -57,7 +57,7 @@ static inline void hash_delete(struct hashtable_t *hash,
struct hlist_head *head;
struct hlist_node *node, *node_tmp;
spinlock_t *list_lock; /* spinlock to protect write access */
int i;
uint32_t i;

for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
Expand Down Expand Up @@ -93,7 +93,8 @@ static inline int hash_add(struct hashtable_t *hash,
hashdata_choose_cb choose,
const void *data, struct hlist_node *data_node)
{
int index, ret = -1;
uint32_t index;
int ret = -1;
struct hlist_head *head;
struct hlist_node *node;
spinlock_t *list_lock; /* spinlock to protect write access */
Expand Down Expand Up @@ -137,7 +138,7 @@ static inline void *hash_remove(struct hashtable_t *hash,
hashdata_compare_cb compare,
hashdata_choose_cb choose, void *data)
{
size_t index;
uint32_t index;
struct hlist_node *node;
struct hlist_head *head;
void *data_save = NULL;
Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define DRIVER_DEVICE "batman-adv"

#ifndef SOURCE_VERSION
#define SOURCE_VERSION "2011.4.0"
#define SOURCE_VERSION "2012.0.0"
#endif

/* B.A.T.M.A.N. parameters */
Expand Down
13 changes: 8 additions & 5 deletions net/batman-adv/originator.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ void originator_free(struct bat_priv *bat_priv)
struct hlist_head *head;
spinlock_t *list_lock; /* spinlock to protect write access */
struct orig_node *orig_node;
int i;
uint32_t i;

if (!hash)
return;
Expand Down Expand Up @@ -350,7 +350,7 @@ static void _purge_orig(struct bat_priv *bat_priv)
struct hlist_head *head;
spinlock_t *list_lock; /* spinlock to protect write access */
struct orig_node *orig_node;
int i;
uint32_t i;

if (!hash)
return;
Expand Down Expand Up @@ -413,7 +413,8 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
int batman_count = 0;
int last_seen_secs;
int last_seen_msecs;
int i, ret = 0;
uint32_t i;
int ret = 0;

primary_if = primary_if_get_selected(bat_priv);

Expand Down Expand Up @@ -519,7 +520,8 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num)
struct hlist_node *node;
struct hlist_head *head;
struct orig_node *orig_node;
int i, ret;
uint32_t i;
int ret;

/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
Expand Down Expand Up @@ -601,7 +603,8 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num)
struct hlist_head *head;
struct hard_iface *hard_iface_tmp;
struct orig_node *orig_node;
int i, ret;
uint32_t i;
int ret;

/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/originator.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num);

/* hashfunction to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
static inline int choose_orig(const void *data, int32_t size)
static inline uint32_t choose_orig(const void *data, uint32_t size)
{
const unsigned char *key = data;
uint32_t hash = 0;
Expand Down
Loading

0 comments on commit d6f03f2

Please sign in to comment.