Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck...
[pandora-kernel.git] / net / batman-adv / gateway_client.c
1 /* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
2  *
3  * Marek Lindner
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA
18  */
19
20 #include "main.h"
21 #include "sysfs.h"
22 #include "gateway_client.h"
23 #include "gateway_common.h"
24 #include "hard-interface.h"
25 #include "originator.h"
26 #include "translation-table.h"
27 #include "routing.h"
28 #include <linux/ip.h>
29 #include <linux/ipv6.h>
30 #include <linux/udp.h>
31 #include <linux/if_vlan.h>
32
33 /* This is the offset of the options field in a dhcp packet starting at
34  * the beginning of the dhcp header
35  */
36 #define BATADV_DHCP_OPTIONS_OFFSET 240
37 #define BATADV_DHCP_REQUEST 3
38
39 static void batadv_gw_node_free_ref(struct batadv_gw_node *gw_node)
40 {
41         if (atomic_dec_and_test(&gw_node->refcount))
42                 kfree_rcu(gw_node, rcu);
43 }
44
45 static struct batadv_gw_node *
46 batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
47 {
48         struct batadv_gw_node *gw_node;
49
50         rcu_read_lock();
51         gw_node = rcu_dereference(bat_priv->curr_gw);
52         if (!gw_node)
53                 goto out;
54
55         if (!atomic_inc_not_zero(&gw_node->refcount))
56                 gw_node = NULL;
57
58 out:
59         rcu_read_unlock();
60         return gw_node;
61 }
62
63 struct batadv_orig_node *
64 batadv_gw_get_selected_orig(struct batadv_priv *bat_priv)
65 {
66         struct batadv_gw_node *gw_node;
67         struct batadv_orig_node *orig_node = NULL;
68
69         gw_node = batadv_gw_get_selected_gw_node(bat_priv);
70         if (!gw_node)
71                 goto out;
72
73         rcu_read_lock();
74         orig_node = gw_node->orig_node;
75         if (!orig_node)
76                 goto unlock;
77
78         if (!atomic_inc_not_zero(&orig_node->refcount))
79                 orig_node = NULL;
80
81 unlock:
82         rcu_read_unlock();
83 out:
84         if (gw_node)
85                 batadv_gw_node_free_ref(gw_node);
86         return orig_node;
87 }
88
89 static void batadv_gw_select(struct batadv_priv *bat_priv,
90                              struct batadv_gw_node *new_gw_node)
91 {
92         struct batadv_gw_node *curr_gw_node;
93
94         spin_lock_bh(&bat_priv->gw_list_lock);
95
96         if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
97                 new_gw_node = NULL;
98
99         curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1);
100         rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
101
102         if (curr_gw_node)
103                 batadv_gw_node_free_ref(curr_gw_node);
104
105         spin_unlock_bh(&bat_priv->gw_list_lock);
106 }
107
108 void batadv_gw_deselect(struct batadv_priv *bat_priv)
109 {
110         atomic_set(&bat_priv->gw_reselect, 1);
111 }
112
113 static struct batadv_gw_node *
114 batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
115 {
116         struct batadv_neigh_node *router;
117         struct hlist_node *node;
118         struct batadv_gw_node *gw_node, *curr_gw = NULL;
119         uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
120         uint8_t max_tq = 0;
121         int down, up;
122         struct batadv_orig_node *orig_node;
123
124         rcu_read_lock();
125         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
126                 if (gw_node->deleted)
127                         continue;
128
129                 orig_node = gw_node->orig_node;
130                 router = batadv_orig_node_get_router(orig_node);
131                 if (!router)
132                         continue;
133
134                 if (!atomic_inc_not_zero(&gw_node->refcount))
135                         goto next;
136
137                 switch (atomic_read(&bat_priv->gw_sel_class)) {
138                 case 1: /* fast connection */
139                         batadv_gw_bandwidth_to_kbit(orig_node->gw_flags,
140                                                     &down, &up);
141
142                         tmp_gw_factor = (router->tq_avg * router->tq_avg *
143                                          down * 100 * 100) /
144                                          (BATADV_TQ_LOCAL_WINDOW_SIZE *
145                                           BATADV_TQ_LOCAL_WINDOW_SIZE * 64);
146
147                         if ((tmp_gw_factor > max_gw_factor) ||
148                             ((tmp_gw_factor == max_gw_factor) &&
149                              (router->tq_avg > max_tq))) {
150                                 if (curr_gw)
151                                         batadv_gw_node_free_ref(curr_gw);
152                                 curr_gw = gw_node;
153                                 atomic_inc(&curr_gw->refcount);
154                         }
155                         break;
156
157                 default: /* 2:  stable connection (use best statistic)
158                           * 3:  fast-switch (use best statistic but change as
159                           *     soon as a better gateway appears)
160                           * XX: late-switch (use best statistic but change as
161                           *     soon as a better gateway appears which has
162                           *     $routing_class more tq points)
163                           */
164                         if (router->tq_avg > max_tq) {
165                                 if (curr_gw)
166                                         batadv_gw_node_free_ref(curr_gw);
167                                 curr_gw = gw_node;
168                                 atomic_inc(&curr_gw->refcount);
169                         }
170                         break;
171                 }
172
173                 if (router->tq_avg > max_tq)
174                         max_tq = router->tq_avg;
175
176                 if (tmp_gw_factor > max_gw_factor)
177                         max_gw_factor = tmp_gw_factor;
178
179                 batadv_gw_node_free_ref(gw_node);
180
181 next:
182                 batadv_neigh_node_free_ref(router);
183         }
184         rcu_read_unlock();
185
186         return curr_gw;
187 }
188
189 void batadv_gw_election(struct batadv_priv *bat_priv)
190 {
191         struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL;
192         struct batadv_neigh_node *router = NULL;
193         char gw_addr[18] = { '\0' };
194
195         /* The batman daemon checks here if we already passed a full originator
196          * cycle in order to make sure we don't choose the first gateway we
197          * hear about. This check is based on the daemon's uptime which we
198          * don't have.
199          */
200         if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
201                 goto out;
202
203         if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect))
204                 goto out;
205
206         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
207
208         next_gw = batadv_gw_get_best_gw_node(bat_priv);
209
210         if (curr_gw == next_gw)
211                 goto out;
212
213         if (next_gw) {
214                 sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
215
216                 router = batadv_orig_node_get_router(next_gw->orig_node);
217                 if (!router) {
218                         batadv_gw_deselect(bat_priv);
219                         goto out;
220                 }
221         }
222
223         if ((curr_gw) && (!next_gw)) {
224                 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
225                            "Removing selected gateway - no gateway in range\n");
226                 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL,
227                                     NULL);
228         } else if ((!curr_gw) && (next_gw)) {
229                 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
230                            "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n",
231                            next_gw->orig_node->orig,
232                            next_gw->orig_node->gw_flags, router->tq_avg);
233                 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
234                                     gw_addr);
235         } else {
236                 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
237                            "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n",
238                            next_gw->orig_node->orig,
239                            next_gw->orig_node->gw_flags, router->tq_avg);
240                 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
241                                     gw_addr);
242         }
243
244         batadv_gw_select(bat_priv, next_gw);
245
246 out:
247         if (curr_gw)
248                 batadv_gw_node_free_ref(curr_gw);
249         if (next_gw)
250                 batadv_gw_node_free_ref(next_gw);
251         if (router)
252                 batadv_neigh_node_free_ref(router);
253 }
254
255 void batadv_gw_check_election(struct batadv_priv *bat_priv,
256                               struct batadv_orig_node *orig_node)
257 {
258         struct batadv_orig_node *curr_gw_orig;
259         struct batadv_neigh_node *router_gw = NULL, *router_orig = NULL;
260         uint8_t gw_tq_avg, orig_tq_avg;
261
262         curr_gw_orig = batadv_gw_get_selected_orig(bat_priv);
263         if (!curr_gw_orig)
264                 goto deselect;
265
266         router_gw = batadv_orig_node_get_router(curr_gw_orig);
267         if (!router_gw)
268                 goto deselect;
269
270         /* this node already is the gateway */
271         if (curr_gw_orig == orig_node)
272                 goto out;
273
274         router_orig = batadv_orig_node_get_router(orig_node);
275         if (!router_orig)
276                 goto out;
277
278         gw_tq_avg = router_gw->tq_avg;
279         orig_tq_avg = router_orig->tq_avg;
280
281         /* the TQ value has to be better */
282         if (orig_tq_avg < gw_tq_avg)
283                 goto out;
284
285         /* if the routing class is greater than 3 the value tells us how much
286          * greater the TQ value of the new gateway must be
287          */
288         if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
289             (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
290                 goto out;
291
292         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
293                    "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
294                    gw_tq_avg, orig_tq_avg);
295
296 deselect:
297         batadv_gw_deselect(bat_priv);
298 out:
299         if (curr_gw_orig)
300                 batadv_orig_node_free_ref(curr_gw_orig);
301         if (router_gw)
302                 batadv_neigh_node_free_ref(router_gw);
303         if (router_orig)
304                 batadv_neigh_node_free_ref(router_orig);
305
306         return;
307 }
308
309 static void batadv_gw_node_add(struct batadv_priv *bat_priv,
310                                struct batadv_orig_node *orig_node,
311                                uint8_t new_gwflags)
312 {
313         struct batadv_gw_node *gw_node;
314         int down, up;
315
316         gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
317         if (!gw_node)
318                 return;
319
320         INIT_HLIST_NODE(&gw_node->list);
321         gw_node->orig_node = orig_node;
322         atomic_set(&gw_node->refcount, 1);
323
324         spin_lock_bh(&bat_priv->gw_list_lock);
325         hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list);
326         spin_unlock_bh(&bat_priv->gw_list_lock);
327
328         batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
329         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
330                    "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
331                    orig_node->orig, new_gwflags,
332                    (down > 2048 ? down / 1024 : down),
333                    (down > 2048 ? "MBit" : "KBit"),
334                    (up > 2048 ? up / 1024 : up),
335                    (up > 2048 ? "MBit" : "KBit"));
336 }
337
338 void batadv_gw_node_update(struct batadv_priv *bat_priv,
339                            struct batadv_orig_node *orig_node,
340                            uint8_t new_gwflags)
341 {
342         struct hlist_node *node;
343         struct batadv_gw_node *gw_node, *curr_gw;
344
345         /* Note: We don't need a NULL check here, since curr_gw never gets
346          * dereferenced. If curr_gw is NULL we also should not exit as we may
347          * have this gateway in our list (duplication check!) even though we
348          * have no currently selected gateway.
349          */
350         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
351
352         rcu_read_lock();
353         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
354                 if (gw_node->orig_node != orig_node)
355                         continue;
356
357                 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
358                            "Gateway class of originator %pM changed from %i to %i\n",
359                            orig_node->orig, gw_node->orig_node->gw_flags,
360                            new_gwflags);
361
362                 gw_node->deleted = 0;
363
364                 if (new_gwflags == BATADV_NO_FLAGS) {
365                         gw_node->deleted = jiffies;
366                         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
367                                    "Gateway %pM removed from gateway list\n",
368                                    orig_node->orig);
369
370                         if (gw_node == curr_gw)
371                                 goto deselect;
372                 }
373
374                 goto unlock;
375         }
376
377         if (new_gwflags == BATADV_NO_FLAGS)
378                 goto unlock;
379
380         batadv_gw_node_add(bat_priv, orig_node, new_gwflags);
381         goto unlock;
382
383 deselect:
384         batadv_gw_deselect(bat_priv);
385 unlock:
386         rcu_read_unlock();
387
388         if (curr_gw)
389                 batadv_gw_node_free_ref(curr_gw);
390 }
391
392 void batadv_gw_node_delete(struct batadv_priv *bat_priv,
393                            struct batadv_orig_node *orig_node)
394 {
395         batadv_gw_node_update(bat_priv, orig_node, 0);
396 }
397
398 void batadv_gw_node_purge(struct batadv_priv *bat_priv)
399 {
400         struct batadv_gw_node *gw_node, *curr_gw;
401         struct hlist_node *node, *node_tmp;
402         unsigned long timeout = msecs_to_jiffies(2 * BATADV_PURGE_TIMEOUT);
403         int do_deselect = 0;
404
405         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
406
407         spin_lock_bh(&bat_priv->gw_list_lock);
408
409         hlist_for_each_entry_safe(gw_node, node, node_tmp,
410                                   &bat_priv->gw_list, list) {
411                 if (((!gw_node->deleted) ||
412                      (time_before(jiffies, gw_node->deleted + timeout))) &&
413                     atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE)
414                         continue;
415
416                 if (curr_gw == gw_node)
417                         do_deselect = 1;
418
419                 hlist_del_rcu(&gw_node->list);
420                 batadv_gw_node_free_ref(gw_node);
421         }
422
423         spin_unlock_bh(&bat_priv->gw_list_lock);
424
425         /* gw_deselect() needs to acquire the gw_list_lock */
426         if (do_deselect)
427                 batadv_gw_deselect(bat_priv);
428
429         if (curr_gw)
430                 batadv_gw_node_free_ref(curr_gw);
431 }
432
433 /* fails if orig_node has no router */
434 static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
435                                     struct seq_file *seq,
436                                     const struct batadv_gw_node *gw_node)
437 {
438         struct batadv_gw_node *curr_gw;
439         struct batadv_neigh_node *router;
440         int down, up, ret = -1;
441
442         batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
443
444         router = batadv_orig_node_get_router(gw_node->orig_node);
445         if (!router)
446                 goto out;
447
448         curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
449
450         ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
451                          (curr_gw == gw_node ? "=>" : "  "),
452                          gw_node->orig_node->orig,
453                          router->tq_avg, router->addr,
454                          router->if_incoming->net_dev->name,
455                          gw_node->orig_node->gw_flags,
456                          (down > 2048 ? down / 1024 : down),
457                          (down > 2048 ? "MBit" : "KBit"),
458                          (up > 2048 ? up / 1024 : up),
459                          (up > 2048 ? "MBit" : "KBit"));
460
461         batadv_neigh_node_free_ref(router);
462         if (curr_gw)
463                 batadv_gw_node_free_ref(curr_gw);
464 out:
465         return ret;
466 }
467
468 int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
469 {
470         struct net_device *net_dev = (struct net_device *)seq->private;
471         struct batadv_priv *bat_priv = netdev_priv(net_dev);
472         struct batadv_hard_iface *primary_if;
473         struct batadv_gw_node *gw_node;
474         struct hlist_node *node;
475         int gw_count = 0, ret = 0;
476
477         primary_if = batadv_primary_if_get_selected(bat_priv);
478         if (!primary_if) {
479                 ret = seq_printf(seq,
480                                  "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
481                                  net_dev->name);
482                 goto out;
483         }
484
485         if (primary_if->if_status != BATADV_IF_ACTIVE) {
486                 ret = seq_printf(seq,
487                                  "BATMAN mesh %s disabled - primary interface not active\n",
488                                  net_dev->name);
489                 goto out;
490         }
491
492         seq_printf(seq,
493                    "      %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
494                    "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
495                    BATADV_SOURCE_VERSION, primary_if->net_dev->name,
496                    primary_if->net_dev->dev_addr, net_dev->name);
497
498         rcu_read_lock();
499         hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
500                 if (gw_node->deleted)
501                         continue;
502
503                 /* fails if orig_node has no router */
504                 if (batadv_write_buffer_text(bat_priv, seq, gw_node) < 0)
505                         continue;
506
507                 gw_count++;
508         }
509         rcu_read_unlock();
510
511         if (gw_count == 0)
512                 seq_printf(seq, "No gateways in range ...\n");
513
514 out:
515         if (primary_if)
516                 batadv_hardif_free_ref(primary_if);
517         return ret;
518 }
519
520 static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
521 {
522         int ret = false;
523         unsigned char *p;
524         int pkt_len;
525
526         if (skb_linearize(skb) < 0)
527                 goto out;
528
529         pkt_len = skb_headlen(skb);
530
531         if (pkt_len < header_len + BATADV_DHCP_OPTIONS_OFFSET + 1)
532                 goto out;
533
534         p = skb->data + header_len + BATADV_DHCP_OPTIONS_OFFSET;
535         pkt_len -= header_len + BATADV_DHCP_OPTIONS_OFFSET + 1;
536
537         /* Access the dhcp option lists. Each entry is made up by:
538          * - octet 1: option type
539          * - octet 2: option data len (only if type != 255 and 0)
540          * - octet 3: option data
541          */
542         while (*p != 255 && !ret) {
543                 /* p now points to the first octet: option type */
544                 if (*p == 53) {
545                         /* type 53 is the message type option.
546                          * Jump the len octet and go to the data octet
547                          */
548                         if (pkt_len < 2)
549                                 goto out;
550                         p += 2;
551
552                         /* check if the message type is what we need */
553                         if (*p == BATADV_DHCP_REQUEST)
554                                 ret = true;
555                         break;
556                 } else if (*p == 0) {
557                         /* option type 0 (padding), just go forward */
558                         if (pkt_len < 1)
559                                 goto out;
560                         pkt_len--;
561                         p++;
562                 } else {
563                         /* This is any other option. So we get the length... */
564                         if (pkt_len < 1)
565                                 goto out;
566                         pkt_len--;
567                         p++;
568
569                         /* ...and then we jump over the data */
570                         if (pkt_len < 1 + (*p))
571                                 goto out;
572                         pkt_len -= 1 + (*p);
573                         p += 1 + (*p);
574                 }
575         }
576 out:
577         return ret;
578 }
579
580 bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
581 {
582         struct ethhdr *ethhdr;
583         struct iphdr *iphdr;
584         struct ipv6hdr *ipv6hdr;
585         struct udphdr *udphdr;
586
587         /* check for ethernet header */
588         if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
589                 return false;
590         ethhdr = (struct ethhdr *)skb->data;
591         *header_len += ETH_HLEN;
592
593         /* check for initial vlan header */
594         if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
595                 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
596                         return false;
597                 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
598                 *header_len += VLAN_HLEN;
599         }
600
601         /* check for ip header */
602         switch (ntohs(ethhdr->h_proto)) {
603         case ETH_P_IP:
604                 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
605                         return false;
606                 iphdr = (struct iphdr *)(skb->data + *header_len);
607                 *header_len += iphdr->ihl * 4;
608
609                 /* check for udp header */
610                 if (iphdr->protocol != IPPROTO_UDP)
611                         return false;
612
613                 break;
614         case ETH_P_IPV6:
615                 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
616                         return false;
617                 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
618                 *header_len += sizeof(*ipv6hdr);
619
620                 /* check for udp header */
621                 if (ipv6hdr->nexthdr != IPPROTO_UDP)
622                         return false;
623
624                 break;
625         default:
626                 return false;
627         }
628
629         if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
630                 return false;
631         udphdr = (struct udphdr *)(skb->data + *header_len);
632         *header_len += sizeof(*udphdr);
633
634         /* check for bootp port */
635         if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
636             (ntohs(udphdr->dest) != 67))
637                 return false;
638
639         if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
640             (ntohs(udphdr->dest) != 547))
641                 return false;
642
643         return true;
644 }
645
646 bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
647                             struct sk_buff *skb, struct ethhdr *ethhdr)
648 {
649         struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
650         struct batadv_orig_node *orig_dst_node = NULL;
651         struct batadv_gw_node *curr_gw = NULL;
652         bool ret, out_of_range = false;
653         unsigned int header_len = 0;
654         uint8_t curr_tq_avg;
655
656         ret = batadv_gw_is_dhcp_target(skb, &header_len);
657         if (!ret)
658                 goto out;
659
660         orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
661                                                  ethhdr->h_dest);
662         if (!orig_dst_node)
663                 goto out;
664
665         if (!orig_dst_node->gw_flags)
666                 goto out;
667
668         ret = batadv_is_type_dhcprequest(skb, header_len);
669         if (!ret)
670                 goto out;
671
672         switch (atomic_read(&bat_priv->gw_mode)) {
673         case BATADV_GW_MODE_SERVER:
674                 /* If we are a GW then we are our best GW. We can artificially
675                  * set the tq towards ourself as the maximum value
676                  */
677                 curr_tq_avg = BATADV_TQ_MAX_VALUE;
678                 break;
679         case BATADV_GW_MODE_CLIENT:
680                 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
681                 if (!curr_gw)
682                         goto out;
683
684                 /* packet is going to our gateway */
685                 if (curr_gw->orig_node == orig_dst_node)
686                         goto out;
687
688                 /* If the dhcp packet has been sent to a different gw,
689                  * we have to evaluate whether the old gw is still
690                  * reliable enough
691                  */
692                 neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node,
693                                                 NULL);
694                 if (!neigh_curr)
695                         goto out;
696
697                 curr_tq_avg = neigh_curr->tq_avg;
698                 break;
699         case BATADV_GW_MODE_OFF:
700         default:
701                 goto out;
702         }
703
704         neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL);
705         if (!neigh_old)
706                 goto out;
707
708         if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD)
709                 out_of_range = true;
710
711 out:
712         if (orig_dst_node)
713                 batadv_orig_node_free_ref(orig_dst_node);
714         if (curr_gw)
715                 batadv_gw_node_free_ref(curr_gw);
716         if (neigh_old)
717                 batadv_neigh_node_free_ref(neigh_old);
718         if (neigh_curr)
719                 batadv_neigh_node_free_ref(neigh_curr);
720         return out_of_range;
721 }