diff options
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r-- | net/batman-adv/vis.c | 104 |
1 files changed, 43 insertions, 61 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index c39f20cc1ba6..8a1b98589d76 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,7 +127,7 @@ 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; } @@ -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; @@ -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: @@ -908,17 +892,15 @@ int vis_init(struct bat_priv *bat_priv) 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 - |