Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / net / batman-adv / gateway_client.c
1 /*
2  * Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  *
20  */
21
22 #include "main.h"
23 #include "gateway_client.h"
24 #include "gateway_common.h"
25 #include "hard-interface.h"
26 #include <linux/ip.h>
27 #include <linux/ipv6.h>
28 #include <linux/udp.h>
29 #include <linux/if_vlan.h>
30
31 static void gw_node_free_ref(struct gw_node *gw_node)
32 {
33         if (atomic_dec_and_test(&gw_node->refcount))
34                 kfree_rcu(gw_node, rcu);
35 }
36
37 void *gw_get_selected(struct bat_priv *bat_priv)
38 {
39         struct gw_node *curr_gateway_tmp;
40         struct orig_node *orig_node = NULL;
41
42         rcu_read_lock();
43         curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
44         if (!curr_gateway_tmp)
45                 goto out;
46
47         orig_node = curr_gateway_tmp->orig_node;
48         if (!orig_node)
49                 goto out;
50
51         if (!atomic_inc_not_zero(&orig_node->refcount))
52                 orig_node = NULL;
53
54 out:
55         rcu_read_unlock();
56         return orig_node;
57 }
58
59 void gw_deselect(struct bat_priv *bat_priv)
60 {
61         struct gw_node *gw_node;
62
63         spin_lock_bh(&bat_priv->gw_list_lock);
64         gw_node = rcu_dereference(bat_priv->curr_gw);
65         rcu_assign_pointer(bat_priv->curr_gw, NULL);
66         spin_unlock_bh(&bat_priv->gw_list_lock);
67
68         if (gw_node)
69                 gw_node_free_ref(gw_node);
70 }
71
72 static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
73 {
74         struct gw_node *curr_gw_node;
75
76         if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
77                 new_gw_node = NULL;
78
79         spin_lock_bh(&bat_priv->gw_list_lock);
80         curr_gw_node = rcu_dereference(bat_priv->curr_gw);
81         rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
82         spin_unlock_bh(&bat_priv->gw_list_lock);
83
84         if (curr_gw_node)
85                 gw_node_free_ref(curr_gw_node);
86 }
87
88 void gw_election(struct bat_priv *bat_priv)
89 {
90         struct hlist_node *node;
91         struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL;
92         uint8_t max_tq = 0;
93         uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
94         int down, up;
95
96         /**
97          * The batman daemon checks here if we already passed a full originator
98          * cycle in order to make sure we don't choose the first gateway we
99          * hear about. This check is based on the daemon's uptime which we
100          * don't have.
101          **/
102         if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
103                 return;
104
105         rcu_read_lock();
106         curr_gw = rcu_dereference(bat_priv->curr_gw);
107         if (curr_gw) {
108                 rcu_read_unlock();
109                 return;
110         }
111
112         if (hlist_empty(&bat_priv->gw_list)) {
113
114                 if (curr_gw) {
115                         rcu_read_unlock();
116                         bat_dbg(DBG_BATMAN, bat_priv,
117                                 "Removing selected gateway - "
118                                 "no gateway in range\n");
119                         gw_deselect(bat_priv);
120                 } else
121                         rcu_read_unlock();
122
123                 return;
124         }
125
126         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
127                 if (!gw_node->orig_node->router)
128                         continue;
129
130                 if (gw_node->deleted)
131                         continue;
132
133                 switch (atomic_read(&bat_priv->gw_sel_class)) {
134                 case 1: /* fast connection */
135                         gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags,
136                                              &down, &up);
137
138                         tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
139                                          gw_node->orig_node->router->tq_avg *
140                                          down * 100 * 100) /
141                                          (TQ_LOCAL_WINDOW_SIZE *
142                                          TQ_LOCAL_WINDOW_SIZE * 64);
143
144                         if ((tmp_gw_factor > max_gw_factor) ||
145                             ((tmp_gw_factor == max_gw_factor) &&
146                              (gw_node->orig_node->router->tq_avg > max_tq)))
147                                 curr_gw_tmp = gw_node;
148                         break;
149
150                 default: /**
151                           * 2:  stable connection (use best statistic)
152                           * 3:  fast-switch (use best statistic but change as
153                           *     soon as a better gateway appears)
154                           * XX: late-switch (use best statistic but change as
155                           *     soon as a better gateway appears which has
156                           *     $routing_class more tq points)
157                           **/
158                         if (gw_node->orig_node->router->tq_avg > max_tq)
159                                 curr_gw_tmp = gw_node;
160                         break;
161                 }
162
163                 if (gw_node->orig_node->router->tq_avg > max_tq)
164                         max_tq = gw_node->orig_node->router->tq_avg;
165
166                 if (tmp_gw_factor > max_gw_factor)
167                         max_gw_factor = tmp_gw_factor;
168         }
169
170         if (curr_gw != curr_gw_tmp) {
171                 if ((curr_gw) && (!curr_gw_tmp))
172                         bat_dbg(DBG_BATMAN, bat_priv,
173                                 "Removing selected gateway - "
174                                 "no gateway in range\n");
175                 else if ((!curr_gw) && (curr_gw_tmp))
176                         bat_dbg(DBG_BATMAN, bat_priv,
177                                 "Adding route to gateway %pM "
178                                 "(gw_flags: %i, tq: %i)\n",
179                                 curr_gw_tmp->orig_node->orig,
180                                 curr_gw_tmp->orig_node->gw_flags,
181                                 curr_gw_tmp->orig_node->router->tq_avg);
182                 else
183                         bat_dbg(DBG_BATMAN, bat_priv,
184                                 "Changing route to gateway %pM "
185                                 "(gw_flags: %i, tq: %i)\n",
186                                 curr_gw_tmp->orig_node->orig,
187                                 curr_gw_tmp->orig_node->gw_flags,
188                                 curr_gw_tmp->orig_node->router->tq_avg);
189
190                 gw_select(bat_priv, curr_gw_tmp);
191         }
192
193         rcu_read_unlock();
194 }
195
196 void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
197 {
198         struct gw_node *curr_gateway_tmp;
199         uint8_t gw_tq_avg, orig_tq_avg;
200
201         rcu_read_lock();
202         curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
203         if (!curr_gateway_tmp)
204                 goto out_rcu;
205
206         if (!curr_gateway_tmp->orig_node)
207                 goto deselect_rcu;
208
209         if (!curr_gateway_tmp->orig_node->router)
210                 goto deselect_rcu;
211
212         /* this node already is the gateway */
213         if (curr_gateway_tmp->orig_node == orig_node)
214                 goto out_rcu;
215
216         if (!orig_node->router)
217                 goto out_rcu;
218
219         gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
220         rcu_read_unlock();
221
222         orig_tq_avg = orig_node->router->tq_avg;
223
224         /* the TQ value has to be better */
225         if (orig_tq_avg < gw_tq_avg)
226                 goto out;
227
228         /**
229          * if the routing class is greater than 3 the value tells us how much
230          * greater the TQ value of the new gateway must be
231          **/
232         if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
233             (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
234                 goto out;
235
236         bat_dbg(DBG_BATMAN, bat_priv,
237                 "Restarting gateway selection: better gateway found (tq curr: "
238                 "%i, tq new: %i)\n",
239                 gw_tq_avg, orig_tq_avg);
240         goto deselect;
241
242 out_rcu:
243         rcu_read_unlock();
244         goto out;
245 deselect_rcu:
246         rcu_read_unlock();
247 deselect:
248         gw_deselect(bat_priv);
249 out:
250         return;
251 }
252
253 static void gw_node_add(struct bat_priv *bat_priv,
254                         struct orig_node *orig_node, uint8_t new_gwflags)
255 {
256         struct gw_node *gw_node;
257         int down, up;
258
259         gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC);
260         if (!gw_node)
261                 return;
262
263         memset(gw_node, 0, sizeof(struct gw_node));
264         INIT_HLIST_NODE(&gw_node->list);
265         gw_node->orig_node = orig_node;
266         atomic_set(&gw_node->refcount, 1);
267
268         spin_lock_bh(&bat_priv->gw_list_lock);
269         hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list);
270         spin_unlock_bh(&bat_priv->gw_list_lock);
271
272         gw_bandwidth_to_kbit(new_gwflags, &down, &up);
273         bat_dbg(DBG_BATMAN, bat_priv,
274                 "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
275                 orig_node->orig, new_gwflags,
276                 (down > 2048 ? down / 1024 : down),
277                 (down > 2048 ? "MBit" : "KBit"),
278                 (up > 2048 ? up / 1024 : up),
279                 (up > 2048 ? "MBit" : "KBit"));
280 }
281
282 void gw_node_update(struct bat_priv *bat_priv,
283                     struct orig_node *orig_node, uint8_t new_gwflags)
284 {
285         struct hlist_node *node;
286         struct gw_node *gw_node;
287
288         rcu_read_lock();
289         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
290                 if (gw_node->orig_node != orig_node)
291                         continue;
292
293                 bat_dbg(DBG_BATMAN, bat_priv,
294                         "Gateway class of originator %pM changed from "
295                         "%i to %i\n",
296                         orig_node->orig, gw_node->orig_node->gw_flags,
297                         new_gwflags);
298
299                 gw_node->deleted = 0;
300
301                 if (new_gwflags == 0) {
302                         gw_node->deleted = jiffies;
303                         bat_dbg(DBG_BATMAN, bat_priv,
304                                 "Gateway %pM removed from gateway list\n",
305                                 orig_node->orig);
306
307                         if (gw_node == rcu_dereference(bat_priv->curr_gw)) {
308                                 rcu_read_unlock();
309                                 gw_deselect(bat_priv);
310                                 return;
311                         }
312                 }
313
314                 rcu_read_unlock();
315                 return;
316         }
317         rcu_read_unlock();
318
319         if (new_gwflags == 0)
320                 return;
321
322         gw_node_add(bat_priv, orig_node, new_gwflags);
323 }
324
325 void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
326 {
327         return gw_node_update(bat_priv, orig_node, 0);
328 }
329
330 void gw_node_purge(struct bat_priv *bat_priv)
331 {
332         struct gw_node *gw_node;
333         struct hlist_node *node, *node_tmp;
334         unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
335
336         spin_lock_bh(&bat_priv->gw_list_lock);
337
338         hlist_for_each_entry_safe(gw_node, node, node_tmp,
339                                   &bat_priv->gw_list, list) {
340                 if (((!gw_node->deleted) ||
341                      (time_before(jiffies, gw_node->deleted + timeout))) &&
342                     atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
343                         continue;
344
345                 if (rcu_dereference(bat_priv->curr_gw) == gw_node)
346                         gw_deselect(bat_priv);
347
348                 hlist_del_rcu(&gw_node->list);
349                 gw_node_free_ref(gw_node);
350         }
351
352
353         spin_unlock_bh(&bat_priv->gw_list_lock);
354 }
355
356 static int _write_buffer_text(struct bat_priv *bat_priv,
357                               struct seq_file *seq, struct gw_node *gw_node)
358 {
359         struct gw_node *curr_gw;
360         int down, up, ret;
361
362         gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
363
364         rcu_read_lock();
365         curr_gw = rcu_dereference(bat_priv->curr_gw);
366
367         ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
368                        (curr_gw == gw_node ? "=>" : "  "),
369                        gw_node->orig_node->orig,
370                        gw_node->orig_node->router->tq_avg,
371                        gw_node->orig_node->router->addr,
372                        gw_node->orig_node->router->if_incoming->net_dev->name,
373                        gw_node->orig_node->gw_flags,
374                        (down > 2048 ? down / 1024 : down),
375                        (down > 2048 ? "MBit" : "KBit"),
376                        (up > 2048 ? up / 1024 : up),
377                        (up > 2048 ? "MBit" : "KBit"));
378
379         rcu_read_unlock();
380         return ret;
381 }
382
383 int gw_client_seq_print_text(struct seq_file *seq, void *offset)
384 {
385         struct net_device *net_dev = (struct net_device *)seq->private;
386         struct bat_priv *bat_priv = netdev_priv(net_dev);
387         struct gw_node *gw_node;
388         struct hlist_node *node;
389         int gw_count = 0;
390
391         if (!bat_priv->primary_if) {
392
393                 return seq_printf(seq, "BATMAN mesh %s disabled - please "
394                                   "specify interfaces to enable it\n",
395                                   net_dev->name);
396         }
397
398         if (bat_priv->primary_if->if_status != IF_ACTIVE) {
399
400                 return seq_printf(seq, "BATMAN mesh %s disabled - "
401                                        "primary interface not active\n",
402                                        net_dev->name);
403         }
404
405         seq_printf(seq, "      %-12s (%s/%i) %17s [%10s]: gw_class ... "
406                    "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
407                    "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
408                    "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
409                    bat_priv->primary_if->net_dev->name,
410                    bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
411
412         rcu_read_lock();
413         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
414                 if (gw_node->deleted)
415                         continue;
416
417                 if (!gw_node->orig_node->router)
418                         continue;
419
420                 _write_buffer_text(bat_priv, seq, gw_node);
421                 gw_count++;
422         }
423         rcu_read_unlock();
424
425         if (gw_count == 0)
426                 seq_printf(seq, "No gateways in range ...\n");
427
428         return 0;
429 }
430
431 int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
432 {
433         struct ethhdr *ethhdr;
434         struct iphdr *iphdr;
435         struct ipv6hdr *ipv6hdr;
436         struct udphdr *udphdr;
437         unsigned int header_len = 0;
438
439         if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
440                 return 0;
441
442         /* check for ethernet header */
443         if (!pskb_may_pull(skb, header_len + ETH_HLEN))
444                 return 0;
445         ethhdr = (struct ethhdr *)skb->data;
446         header_len += ETH_HLEN;
447
448         /* check for initial vlan header */
449         if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
450                 if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
451                         return 0;
452                 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
453                 header_len += VLAN_HLEN;
454         }
455
456         /* check for ip header */
457         switch (ntohs(ethhdr->h_proto)) {
458         case ETH_P_IP:
459                 if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
460                         return 0;
461                 iphdr = (struct iphdr *)(skb->data + header_len);
462                 header_len += iphdr->ihl * 4;
463
464                 /* check for udp header */
465                 if (iphdr->protocol != IPPROTO_UDP)
466                         return 0;
467
468                 break;
469         case ETH_P_IPV6:
470                 if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
471                         return 0;
472                 ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
473                 header_len += sizeof(struct ipv6hdr);
474
475                 /* check for udp header */
476                 if (ipv6hdr->nexthdr != IPPROTO_UDP)
477                         return 0;
478
479                 break;
480         default:
481                 return 0;
482         }
483
484         if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
485                 return 0;
486         udphdr = (struct udphdr *)(skb->data + header_len);
487         header_len += sizeof(struct udphdr);
488
489         /* check for bootp port */
490         if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
491              (ntohs(udphdr->dest) != 67))
492                 return 0;
493
494         if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
495             (ntohs(udphdr->dest) != 547))
496                 return 0;
497
498         if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
499                 return -1;
500
501         rcu_read_lock();
502         if (!rcu_dereference(bat_priv->curr_gw)) {
503                 rcu_read_unlock();
504                 return 0;
505         }
506         rcu_read_unlock();
507
508         return 1;
509 }