2 * Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
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.
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.
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
23 #include "gateway_client.h"
24 #include "gateway_common.h"
25 #include "hard-interface.h"
27 #include <linux/ipv6.h>
28 #include <linux/udp.h>
29 #include <linux/if_vlan.h>
31 static void gw_node_free_ref(struct gw_node *gw_node)
33 if (atomic_dec_and_test(&gw_node->refcount))
34 kfree_rcu(gw_node, rcu);
37 void *gw_get_selected(struct bat_priv *bat_priv)
39 struct gw_node *curr_gateway_tmp;
40 struct orig_node *orig_node = NULL;
43 curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
44 if (!curr_gateway_tmp)
47 orig_node = curr_gateway_tmp->orig_node;
51 if (!atomic_inc_not_zero(&orig_node->refcount))
59 void gw_deselect(struct bat_priv *bat_priv)
61 struct gw_node *gw_node;
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);
69 gw_node_free_ref(gw_node);
72 static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
74 struct gw_node *curr_gw_node;
76 if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
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);
85 gw_node_free_ref(curr_gw_node);
88 void gw_election(struct bat_priv *bat_priv)
90 struct hlist_node *node;
91 struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL;
93 uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
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
102 if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
106 curr_gw = rcu_dereference(bat_priv->curr_gw);
112 if (hlist_empty(&bat_priv->gw_list)) {
116 bat_dbg(DBG_BATMAN, bat_priv,
117 "Removing selected gateway - "
118 "no gateway in range\n");
119 gw_deselect(bat_priv);
126 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
127 if (!gw_node->orig_node->router)
130 if (gw_node->deleted)
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,
138 tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
139 gw_node->orig_node->router->tq_avg *
141 (TQ_LOCAL_WINDOW_SIZE *
142 TQ_LOCAL_WINDOW_SIZE * 64);
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;
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)
158 if (gw_node->orig_node->router->tq_avg > max_tq)
159 curr_gw_tmp = gw_node;
163 if (gw_node->orig_node->router->tq_avg > max_tq)
164 max_tq = gw_node->orig_node->router->tq_avg;
166 if (tmp_gw_factor > max_gw_factor)
167 max_gw_factor = tmp_gw_factor;
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);
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);
190 gw_select(bat_priv, curr_gw_tmp);
196 void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
198 struct gw_node *curr_gateway_tmp;
199 uint8_t gw_tq_avg, orig_tq_avg;
202 curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
203 if (!curr_gateway_tmp)
206 if (!curr_gateway_tmp->orig_node)
209 if (!curr_gateway_tmp->orig_node->router)
212 /* this node already is the gateway */
213 if (curr_gateway_tmp->orig_node == orig_node)
216 if (!orig_node->router)
219 gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
222 orig_tq_avg = orig_node->router->tq_avg;
224 /* the TQ value has to be better */
225 if (orig_tq_avg < gw_tq_avg)
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
232 if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
233 (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
236 bat_dbg(DBG_BATMAN, bat_priv,
237 "Restarting gateway selection: better gateway found (tq curr: "
239 gw_tq_avg, orig_tq_avg);
248 gw_deselect(bat_priv);
253 static void gw_node_add(struct bat_priv *bat_priv,
254 struct orig_node *orig_node, uint8_t new_gwflags)
256 struct gw_node *gw_node;
259 gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC);
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);
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);
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"));
282 void gw_node_update(struct bat_priv *bat_priv,
283 struct orig_node *orig_node, uint8_t new_gwflags)
285 struct hlist_node *node;
286 struct gw_node *gw_node;
289 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
290 if (gw_node->orig_node != orig_node)
293 bat_dbg(DBG_BATMAN, bat_priv,
294 "Gateway class of originator %pM changed from "
296 orig_node->orig, gw_node->orig_node->gw_flags,
299 gw_node->deleted = 0;
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",
307 if (gw_node == rcu_dereference(bat_priv->curr_gw)) {
309 gw_deselect(bat_priv);
319 if (new_gwflags == 0)
322 gw_node_add(bat_priv, orig_node, new_gwflags);
325 void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
327 return gw_node_update(bat_priv, orig_node, 0);
330 void gw_node_purge(struct bat_priv *bat_priv)
332 struct gw_node *gw_node;
333 struct hlist_node *node, *node_tmp;
334 unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
336 spin_lock_bh(&bat_priv->gw_list_lock);
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)
345 if (rcu_dereference(bat_priv->curr_gw) == gw_node)
346 gw_deselect(bat_priv);
348 hlist_del_rcu(&gw_node->list);
349 gw_node_free_ref(gw_node);
353 spin_unlock_bh(&bat_priv->gw_list_lock);
356 static int _write_buffer_text(struct bat_priv *bat_priv,
357 struct seq_file *seq, struct gw_node *gw_node)
359 struct gw_node *curr_gw;
362 gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
365 curr_gw = rcu_dereference(bat_priv->curr_gw);
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"));
383 int gw_client_seq_print_text(struct seq_file *seq, void *offset)
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;
391 if (!bat_priv->primary_if) {
393 return seq_printf(seq, "BATMAN mesh %s disabled - please "
394 "specify interfaces to enable it\n",
398 if (bat_priv->primary_if->if_status != IF_ACTIVE) {
400 return seq_printf(seq, "BATMAN mesh %s disabled - "
401 "primary interface not active\n",
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);
413 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
414 if (gw_node->deleted)
417 if (!gw_node->orig_node->router)
420 _write_buffer_text(bat_priv, seq, gw_node);
426 seq_printf(seq, "No gateways in range ...\n");
431 int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
433 struct ethhdr *ethhdr;
435 struct ipv6hdr *ipv6hdr;
436 struct udphdr *udphdr;
437 unsigned int header_len = 0;
439 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
442 /* check for ethernet header */
443 if (!pskb_may_pull(skb, header_len + ETH_HLEN))
445 ethhdr = (struct ethhdr *)skb->data;
446 header_len += ETH_HLEN;
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))
452 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
453 header_len += VLAN_HLEN;
456 /* check for ip header */
457 switch (ntohs(ethhdr->h_proto)) {
459 if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
461 iphdr = (struct iphdr *)(skb->data + header_len);
462 header_len += iphdr->ihl * 4;
464 /* check for udp header */
465 if (iphdr->protocol != IPPROTO_UDP)
470 if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
472 ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
473 header_len += sizeof(struct ipv6hdr);
475 /* check for udp header */
476 if (ipv6hdr->nexthdr != IPPROTO_UDP)
484 if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
486 udphdr = (struct udphdr *)(skb->data + header_len);
487 header_len += sizeof(struct udphdr);
489 /* check for bootp port */
490 if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
491 (ntohs(udphdr->dest) != 67))
494 if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
495 (ntohs(udphdr->dest) != 547))
498 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
502 if (!rcu_dereference(bat_priv->curr_gw)) {