aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/vis.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r--net/batman-adv/vis.c114
1 files changed, 47 insertions, 67 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index c39f20c..f81a6b6 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -30,22 +30,6 @@
#define MAX_VIS_PACKET_SIZE 1000
-/* Returns the smallest signed integer in two's complement with the sizeof x */
-#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
-
-/* Checks if a sequence number x is a predecessor/successor of y.
- * they handle overflows/underflows and can correctly check for a
- * predecessor/successor unless the variable sequence number has grown by
- * more then 2**(bitwidth(x)-1)-1.
- * This means that for a uint8_t with the maximum value 255, it would think:
- * - when adding nothing - it is neither a predecessor nor a successor
- * - before adding more than 127 to the starting value - it is a predecessor,
- * - when adding 128 - it is neither a predecessor nor a successor,
- * - after adding more than 127 to the starting value - it is a successor */
-#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
- _dummy > smallest_signed_int(_dummy); })
-#define seq_after(x, y) seq_before(y, x)
-
static void start_vis_timer(struct bat_priv *bat_priv);
/* free the info */
@@ -68,10 +52,10 @@ static void free_info(struct kref *ref)
}
/* Compare two vis packets, used by the hashing algorithm */
-static int vis_info_cmp(struct hlist_node *node, void *data2)
+static int vis_info_cmp(const struct hlist_node *node, const void *data2)
{
- struct vis_info *d1, *d2;
- struct vis_packet *p1, *p2;
+ const struct vis_info *d1, *d2;
+ const struct vis_packet *p1, *p2;
d1 = container_of(node, struct vis_info, hash_entry);
d2 = data2;
@@ -82,11 +66,11 @@ static int vis_info_cmp(struct hlist_node *node, void *data2)
/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
-static int vis_info_choose(void *data, int size)
+static int vis_info_choose(const void *data, int size)
{
- struct vis_info *vis_info = data;
- struct vis_packet *packet;
- unsigned char *key;
+ const struct vis_info *vis_info = data;
+ const struct vis_packet *packet;
+ const unsigned char *key;
uint32_t hash = 0;
size_t i;
@@ -106,7 +90,7 @@ static int vis_info_choose(void *data, int size)
}
static struct vis_info *vis_hash_find(struct bat_priv *bat_priv,
- void *data)
+ const void *data)
{
struct hashtable_t *hash = bat_priv->vis_hash;
struct hlist_head *head;
@@ -143,11 +127,11 @@ static void vis_data_insert_interface(const uint8_t *interface,
struct hlist_node *pos;
hlist_for_each_entry(entry, pos, if_list, list) {
- if (compare_eth(entry->addr, (void *)interface))
+ if (compare_eth(entry->addr, interface))
return;
}
- /* its a new address, add it to the list */
+ /* it's a new address, add it to the list */
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return;
@@ -156,7 +140,8 @@ static void vis_data_insert_interface(const uint8_t *interface,
hlist_add_head(&entry->list, if_list);
}
-static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
+static ssize_t vis_data_read_prim_sec(char *buff,
+ const struct hlist_head *if_list)
{
struct if_list_entry *entry;
struct hlist_node *pos;
@@ -189,8 +174,9 @@ static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
}
/* read an entry */
-static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
- uint8_t *src, bool primary)
+static ssize_t vis_data_read_entry(char *buff,
+ const struct vis_info_entry *entry,
+ const uint8_t *src, bool primary)
{
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
if (primary && entry->quality == 0)
@@ -239,7 +225,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)packet + sizeof(struct vis_packet));
+ ((char *)packet + sizeof(*packet));
for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
@@ -287,7 +273,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)packet + sizeof(struct vis_packet));
+ ((char *)packet + sizeof(*packet));
for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
@@ -361,11 +347,11 @@ static void send_list_del(struct vis_info *info)
/* tries to add one entry to the receive list. */
static void recv_list_add(struct bat_priv *bat_priv,
- struct list_head *recv_list, char *mac)
+ struct list_head *recv_list, const char *mac)
{
struct recvlist_node *entry;
- entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return;
@@ -377,9 +363,9 @@ static void recv_list_add(struct bat_priv *bat_priv,
/* returns 1 if this mac is in the recv_list */
static int recv_list_is_in(struct bat_priv *bat_priv,
- struct list_head *recv_list, char *mac)
+ const struct list_head *recv_list, const char *mac)
{
- struct recvlist_node *entry;
+ const struct recvlist_node *entry;
spin_lock_bh(&bat_priv->vis_list_lock);
list_for_each_entry(entry, recv_list, list) {
@@ -412,11 +398,11 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
return NULL;
/* see if the packet is already in vis_hash */
- search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
+ search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
if (!search_elem.skb_packet)
return NULL;
search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
- sizeof(struct vis_packet));
+ sizeof(*search_packet));
memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
old_info = vis_hash_find(bat_priv, &search_elem);
@@ -442,27 +428,26 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
kref_put(&old_info->refcount, free_info);
}
- info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
+ info = kmalloc(sizeof(*info), GFP_ATOMIC);
if (!info)
return NULL;
- info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
- vis_info_len + sizeof(struct ethhdr));
+ info->skb_packet = dev_alloc_skb(sizeof(*packet) + vis_info_len +
+ sizeof(struct ethhdr));
if (!info->skb_packet) {
kfree(info);
return NULL;
}
skb_reserve(info->skb_packet, sizeof(struct ethhdr));
- packet = (struct vis_packet *)skb_put(info->skb_packet,
- sizeof(struct vis_packet) +
- vis_info_len);
+ packet = (struct vis_packet *)skb_put(info->skb_packet, sizeof(*packet)
+ + vis_info_len);
kref_init(&info->refcount);
INIT_LIST_HEAD(&info->send_list);
INIT_LIST_HEAD(&info->recv_list);
info->first_seen = jiffies;
info->bat_priv = bat_priv;
- memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
+ memcpy(packet, vis_packet, sizeof(*packet) + vis_info_len);
/* initialize and add new packet. */
*is_new = 1;
@@ -480,7 +465,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
/* try to add it */
hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
info, &info->hash_entry);
- if (hash_added < 0) {
+ if (hash_added != 0) {
/* did not work (for some reason) */
kref_put(&info->refcount, free_info);
info = NULL;
@@ -599,9 +584,9 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
}
/* Return true if the vis packet is full. */
-static bool vis_packet_full(struct vis_info *info)
+static bool vis_packet_full(const struct vis_info *info)
{
- struct vis_packet *packet;
+ const struct vis_packet *packet;
packet = (struct vis_packet *)info->skb_packet->data;
if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
@@ -619,7 +604,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
struct hlist_head *head;
struct orig_node *orig_node;
struct neigh_node *router;
- struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
+ struct vis_info *info = bat_priv->my_vis_info;
struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
struct vis_info_entry *entry;
struct tt_local_entry *tt_local_entry;
@@ -632,7 +617,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
packet->ttl = TTL;
packet->seqno = htonl(ntohl(packet->seqno) + 1);
packet->entries = 0;
- skb_trim(info->skb_packet, sizeof(struct vis_packet));
+ skb_trim(info->skb_packet, sizeof(*packet));
if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
best_tq = find_best_vis_server(bat_priv, info);
@@ -680,11 +665,12 @@ next:
hash = bat_priv->tt_local_hash;
- spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
- hlist_for_each_entry(tt_local_entry, node, head, hash_entry) {
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(tt_local_entry, node, head,
+ hash_entry) {
entry = (struct vis_info_entry *)
skb_put(info->skb_packet,
sizeof(*entry));
@@ -693,14 +679,12 @@ next:
entry->quality = 0; /* 0 means TT */
packet->entries++;
- if (vis_packet_full(info)) {
- spin_unlock_bh(&bat_priv->tt_lhash_lock);
- return 0;
- }
+ if (vis_packet_full(info))
+ goto unlock;
}
+ rcu_read_unlock();
}
- spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0;
unlock:
@@ -903,22 +887,18 @@ int vis_init(struct bat_priv *bat_priv)
}
bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
- if (!bat_priv->my_vis_info) {
- pr_err("Can't initialize vis packet\n");
+ if (!bat_priv->my_vis_info)
goto err;
- }
- bat_priv->my_vis_info->skb_packet = dev_alloc_skb(
- sizeof(struct vis_packet) +
- MAX_VIS_PACKET_SIZE +
- sizeof(struct ethhdr));
+ bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
+ MAX_VIS_PACKET_SIZE +
+ sizeof(struct ethhdr));
if (!bat_priv->my_vis_info->skb_packet)
goto free_info;
skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
- packet = (struct vis_packet *)skb_put(
- bat_priv->my_vis_info->skb_packet,
- sizeof(struct vis_packet));
+ packet = (struct vis_packet *)skb_put(bat_priv->my_vis_info->skb_packet,
+ sizeof(*packet));
/* prefill the vis info */
bat_priv->my_vis_info->first_seen = jiffies -
@@ -938,7 +918,7 @@ int vis_init(struct bat_priv *bat_priv)
hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
bat_priv->my_vis_info,
&bat_priv->my_vis_info->hash_entry);
- if (hash_added < 0) {
+ if (hash_added != 0) {
pr_err("Can't add own vis packet into hash\n");
/* not in hash, need to remove it manually. */
kref_put(&bat_priv->my_vis_info->refcount, free_info);