aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/batman-adv/vis.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/batman-adv/vis.c')
-rw-r--r--drivers/staging/batman-adv/vis.c124
1 files changed, 106 insertions, 18 deletions
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
index 0bfc083a423..5edeb3261ac 100644
--- a/drivers/staging/batman-adv/vis.c
+++ b/drivers/staging/batman-adv/vis.c
@@ -102,7 +102,7 @@ static int vis_info_choose(void *data, int size)
102 102
103/* insert interface to the list of interfaces of one originator, if it 103/* insert interface to the list of interfaces of one originator, if it
104 * does not already exist in the list */ 104 * does not already exist in the list */
105void proc_vis_insert_interface(const uint8_t *interface, 105static void vis_data_insert_interface(const uint8_t *interface,
106 struct hlist_head *if_list, 106 struct hlist_head *if_list,
107 bool primary) 107 bool primary)
108{ 108{
@@ -123,36 +123,119 @@ void proc_vis_insert_interface(const uint8_t *interface,
123 hlist_add_head(&entry->list, if_list); 123 hlist_add_head(&entry->list, if_list);
124} 124}
125 125
126void proc_vis_read_prim_sec(struct seq_file *seq, 126static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
127 struct hlist_head *if_list)
128{ 127{
129 struct if_list_entry *entry; 128 struct if_list_entry *entry;
130 struct hlist_node *pos; 129 struct hlist_node *pos;
131 char tmp_addr_str[ETH_STR_LEN]; 130 char tmp_addr_str[ETH_STR_LEN];
131 size_t len = 0;
132 132
133 hlist_for_each_entry(entry, pos, if_list, list) { 133 hlist_for_each_entry(entry, pos, if_list, list) {
134 if (entry->primary) 134 if (entry->primary)
135 seq_printf(seq, "PRIMARY, "); 135 len += sprintf(buff + len, "PRIMARY, ");
136 else { 136 else {
137 addr_to_string(tmp_addr_str, entry->addr); 137 addr_to_string(tmp_addr_str, entry->addr);
138 seq_printf(seq, "SEC %s, ", tmp_addr_str); 138 len += sprintf(buff + len, "SEC %s, ", tmp_addr_str);
139 } 139 }
140 } 140 }
141
142 return len;
141} 143}
142 144
143/* read an entry */ 145/* read an entry */
144void proc_vis_read_entry(struct seq_file *seq, 146static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
145 struct vis_info_entry *entry, 147 uint8_t *src, bool primary)
146 uint8_t *src,
147 bool primary)
148{ 148{
149 char to[40]; 149 char to[40];
150 150
151 addr_to_string(to, entry->dest); 151 addr_to_string(to, entry->dest);
152 if (primary && entry->quality == 0) 152 if (primary && entry->quality == 0)
153 seq_printf(seq, "HNA %s, ", to); 153 return sprintf(buff, "HNA %s, ", to);
154 else if (compare_orig(entry->src, src)) 154 else if (compare_orig(entry->src, src))
155 seq_printf(seq, "TQ %s %d, ", to, entry->quality); 155 return sprintf(buff, "TQ %s %d, ", to, entry->quality);
156
157 return 0;
158}
159
160ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
161 size_t count, loff_t off)
162{
163 HASHIT(hashit);
164 struct vis_info *info;
165 struct vis_info_entry *entries;
166 struct bat_priv *bat_priv = netdev_priv(net_dev);
167 HLIST_HEAD(vis_if_list);
168 struct if_list_entry *entry;
169 struct hlist_node *pos, *n;
170 size_t hdr_len, tmp_len;
171 int i, bytes_written = 0;
172 char tmp_addr_str[ETH_STR_LEN];
173 unsigned long flags;
174 int vis_server = atomic_read(&bat_priv->vis_mode);
175
176 rcu_read_lock();
177 if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
178 rcu_read_unlock();
179 return 0;
180 }
181
182 rcu_read_unlock();
183 hdr_len = 0;
184
185 spin_lock_irqsave(&vis_hash_lock, flags);
186 while (hash_iterate(vis_hash, &hashit)) {
187 info = hashit.bucket->data;
188 entries = (struct vis_info_entry *)
189 ((char *)info + sizeof(struct vis_info));
190
191 /* estimated line length */
192 if (count < bytes_written + 200)
193 break;
194
195 for (i = 0; i < info->packet.entries; i++) {
196 if (entries[i].quality == 0)
197 continue;
198 vis_data_insert_interface(entries[i].src, &vis_if_list,
199 compare_orig(entries[i].src,
200 info->packet.vis_orig));
201 }
202
203 hlist_for_each_entry(entry, pos, &vis_if_list, list) {
204 addr_to_string(tmp_addr_str, entry->addr);
205 tmp_len = sprintf(buff + bytes_written,
206 "%s,", tmp_addr_str);
207
208 for (i = 0; i < info->packet.entries; i++)
209 tmp_len += vis_data_read_entry(
210 buff + bytes_written + tmp_len,
211 &entries[i], entry->addr,
212 entry->primary);
213
214 /* add primary/secondary records */
215 if (compare_orig(entry->addr, info->packet.vis_orig))
216 tmp_len += vis_data_read_prim_sec(
217 buff + bytes_written + tmp_len,
218 &vis_if_list);
219
220 tmp_len += sprintf(buff + bytes_written + tmp_len,
221 "\n");
222
223 hdr_len += tmp_len;
224
225 if (off >= hdr_len)
226 continue;
227
228 bytes_written += tmp_len;
229 }
230
231 hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
232 hlist_del(&entry->list);
233 kfree(entry);
234 }
235 }
236 spin_unlock_irqrestore(&vis_hash_lock, flags);
237
238 return bytes_written;
156} 239}
157 240
158/* add the info packet to the send list, if it was not 241/* add the info packet to the send list, if it was not
@@ -280,12 +363,14 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
280} 363}
281 364
282/* handle the server sync packet, forward if needed. */ 365/* handle the server sync packet, forward if needed. */
283void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) 366void receive_server_sync_packet(struct bat_priv *bat_priv,
367 struct vis_packet *vis_packet,
368 int vis_info_len)
284{ 369{
285 struct vis_info *info; 370 struct vis_info *info;
286 int is_new, make_broadcast; 371 int is_new, make_broadcast;
287 unsigned long flags; 372 unsigned long flags;
288 int vis_server = atomic_read(&vis_mode); 373 int vis_server = atomic_read(&bat_priv->vis_mode);
289 374
290 make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); 375 make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
291 376
@@ -303,13 +388,14 @@ end:
303} 388}
304 389
305/* handle an incoming client update packet and schedule forward if needed. */ 390/* handle an incoming client update packet and schedule forward if needed. */
306void receive_client_update_packet(struct vis_packet *vis_packet, 391void receive_client_update_packet(struct bat_priv *bat_priv,
392 struct vis_packet *vis_packet,
307 int vis_info_len) 393 int vis_info_len)
308{ 394{
309 struct vis_info *info; 395 struct vis_info *info;
310 int is_new; 396 int is_new;
311 unsigned long flags; 397 unsigned long flags;
312 int vis_server = atomic_read(&vis_mode); 398 int vis_server = atomic_read(&bat_priv->vis_mode);
313 int are_target = 0; 399 int are_target = 0;
314 400
315 /* clients shall not broadcast. */ 401 /* clients shall not broadcast. */
@@ -376,7 +462,7 @@ static bool vis_packet_full(struct vis_info *info)
376 462
377/* generates a packet of own vis data, 463/* generates a packet of own vis data,
378 * returns 0 on success, -1 if no packet could be generated */ 464 * returns 0 on success, -1 if no packet could be generated */
379static int generate_vis_packet(void) 465static int generate_vis_packet(struct bat_priv *bat_priv)
380{ 466{
381 HASHIT(hashit_local); 467 HASHIT(hashit_local);
382 HASHIT(hashit_global); 468 HASHIT(hashit_global);
@@ -388,7 +474,7 @@ static int generate_vis_packet(void)
388 unsigned long flags; 474 unsigned long flags;
389 475
390 info->first_seen = jiffies; 476 info->first_seen = jiffies;
391 info->packet.vis_type = atomic_read(&vis_mode); 477 info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
392 478
393 spin_lock_irqsave(&orig_hash_lock, flags); 479 spin_lock_irqsave(&orig_hash_lock, flags);
394 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); 480 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
@@ -568,12 +654,14 @@ static void send_vis_packets(struct work_struct *work)
568{ 654{
569 struct vis_info *info, *temp; 655 struct vis_info *info, *temp;
570 unsigned long flags; 656 unsigned long flags;
657 /* FIXME: each batman_if will be attached to a softif */
658 struct bat_priv *bat_priv = netdev_priv(soft_device);
571 659
572 spin_lock_irqsave(&vis_hash_lock, flags); 660 spin_lock_irqsave(&vis_hash_lock, flags);
573 661
574 purge_vis_packets(); 662 purge_vis_packets();
575 663
576 if (generate_vis_packet() == 0) { 664 if (generate_vis_packet(bat_priv) == 0) {
577 /* schedule if generation was successful */ 665 /* schedule if generation was successful */
578 send_list_add(my_vis_info); 666 send_list_add(my_vis_info);
579 } 667 }