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