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 static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) 512 { 513 int ret = false; 514 unsigned char *p; 515 int pkt_len; 516 517 if (skb_linearize(skb) < 0) 518 goto out; 519 520 pkt_len = skb_headlen(skb); 521 522 if (pkt_len < header_len + BATADV_DHCP_OPTIONS_OFFSET + 1) 523 goto out; 524 525 p = skb->data + header_len + BATADV_DHCP_OPTIONS_OFFSET; 526 pkt_len -= header_len + BATADV_DHCP_OPTIONS_OFFSET + 1; 527 528 /* Access the dhcp option lists. Each entry is made up by: 529 * - octet 1: option type 530 * - octet 2: option data len (only if type != 255 and 0) 531 * - octet 3: option data 532 */ 533 while (*p != 255 && !ret) { 534 /* p now points to the first octet: option type */ 535 if (*p == 53) { 536 /* type 53 is the message type option. 537 * Jump the len octet and go to the data octet 538 */ 539 if (pkt_len < 2) 540 goto out; 541 p += 2; 542 543 /* check if the message type is what we need */ 544 if (*p == BATADV_DHCP_REQUEST) 545 ret = true; 546 break; 547 } else if (*p == 0) { 548 /* option type 0 (padding), just go forward */ 549 if (pkt_len < 1) 550 goto out; 551 pkt_len--; 552 p++; 553 } else { 554 /* This is any other option. So we get the length... */ 555 if (pkt_len < 1) 556 goto out; 557 pkt_len--; 558 p++; 559 560 /* ...and then we jump over the data */ 561 if (pkt_len < 1 + (*p)) 562 goto out; 563 pkt_len -= 1 + (*p); 564 p += 1 + (*p); 565 } 566 } 567 out: 568 return ret; 569 } 570 571 bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) 572 { 573 struct ethhdr *ethhdr; 574 struct iphdr *iphdr; 575 struct ipv6hdr *ipv6hdr; 576 struct udphdr *udphdr; 577 578 /* check for ethernet header */ 579 if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) 580 return false; 581 ethhdr = (struct ethhdr *)skb->data; 582 *header_len += ETH_HLEN; 583 584 /* check for initial vlan header */ 585 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 586 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) 587 return false; 588 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); 589 *header_len += VLAN_HLEN; 590 } 591 592 /* check for ip header */ 593 switch (ntohs(ethhdr->h_proto)) { 594 case ETH_P_IP: 595 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) 596 return false; 597 iphdr = (struct iphdr *)(skb->data + *header_len); 598 *header_len += iphdr->ihl * 4; 599 600 /* check for udp header */ 601 if (iphdr->protocol != IPPROTO_UDP) 602 return false; 603 604 break; 605 case ETH_P_IPV6: 606 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) 607 return false; 608 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); 609 *header_len += sizeof(*ipv6hdr); 610 611 /* check for udp header */ 612 if (ipv6hdr->nexthdr != IPPROTO_UDP) 613 return false; 614 615 break; 616 default: 617 return false; 618 } 619 620 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr))) 621 return false; 622 udphdr = (struct udphdr *)(skb->data + *header_len); 623 *header_len += sizeof(*udphdr); 624 625 /* check for bootp port */ 626 if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && 627 (ntohs(udphdr->dest) != 67)) 628 return false; 629 630 if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && 631 (ntohs(udphdr->dest) != 547)) 632 return false; 633 634 return true; 635 } 636 637 bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, 638 struct sk_buff *skb, struct ethhdr *ethhdr) 639 { 640 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL; 641 struct batadv_orig_node *orig_dst_node = NULL; 642 struct batadv_gw_node *curr_gw = NULL; 643 bool ret, out_of_range = false; 644 unsigned int header_len = 0; 645 uint8_t curr_tq_avg; 646 647 ret = batadv_gw_is_dhcp_target(skb, &header_len); 648 if (!ret) 649 goto out; 650 651 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 652 ethhdr->h_dest); 653 if (!orig_dst_node) 654 goto out; 655 656 if (!orig_dst_node->gw_flags) 657 goto out; 658 659 ret = batadv_is_type_dhcprequest(skb, header_len); 660 if (!ret) 661 goto out; 662 663 switch (atomic_read(&bat_priv->gw_mode)) { 664 case BATADV_GW_MODE_SERVER: 665 /* If we are a GW then we are our best GW. We can artificially 666 * set the tq towards ourself as the maximum value 667 */ 668 curr_tq_avg = BATADV_TQ_MAX_VALUE; 669 break; 670 case BATADV_GW_MODE_CLIENT: 671 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 672 if (!curr_gw) 673 goto out; 674 675 /* packet is going to our gateway */ 676 if (curr_gw->orig_node == orig_dst_node) 677 goto out; 678 679 /* If the dhcp packet has been sent to a different gw, 680 * we have to evaluate whether the old gw is still 681 * reliable enough 682 */ 683 neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node, 684 NULL); 685 if (!neigh_curr) 686 goto out; 687 688 curr_tq_avg = neigh_curr->tq_avg; 689 break; 690 case BATADV_GW_MODE_OFF: 691 default: 692 goto out; 693 } 694 695 neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL); 696 if (!neigh_old) 697 goto out; 698 699 if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD) 700 out_of_range = true; 701 702 out: 703 if (orig_dst_node) 704 batadv_orig_node_free_ref(orig_dst_node); 705 if (curr_gw) 706 batadv_gw_node_free_ref(curr_gw); 707 if (neigh_old) 708 batadv_neigh_node_free_ref(neigh_old); 709 if (neigh_curr) 710 batadv_neigh_node_free_ref(neigh_curr); 711 return out_of_range; 712 } 713