1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) B.A.T.M.A.N. contributors: 3 * 4 * Marek Lindner 5 */ 6 7 #include "gateway_client.h" 8 #include "main.h" 9 10 #include <linux/atomic.h> 11 #include <linux/byteorder/generic.h> 12 #include <linux/errno.h> 13 #include <linux/etherdevice.h> 14 #include <linux/gfp.h> 15 #include <linux/if_ether.h> 16 #include <linux/if_vlan.h> 17 #include <linux/in.h> 18 #include <linux/ip.h> 19 #include <linux/ipv6.h> 20 #include <linux/kernel.h> 21 #include <linux/kref.h> 22 #include <linux/list.h> 23 #include <linux/lockdep.h> 24 #include <linux/netdevice.h> 25 #include <linux/netlink.h> 26 #include <linux/rculist.h> 27 #include <linux/rcupdate.h> 28 #include <linux/skbuff.h> 29 #include <linux/slab.h> 30 #include <linux/spinlock.h> 31 #include <linux/stddef.h> 32 #include <linux/udp.h> 33 #include <net/sock.h> 34 #include <uapi/linux/batadv_packet.h> 35 #include <uapi/linux/batman_adv.h> 36 37 #include "hard-interface.h" 38 #include "log.h" 39 #include "netlink.h" 40 #include "originator.h" 41 #include "routing.h" 42 #include "soft-interface.h" 43 #include "translation-table.h" 44 45 /* These are the offsets of the "hw type" and "hw address length" in the dhcp 46 * packet starting at the beginning of the dhcp header 47 */ 48 #define BATADV_DHCP_HTYPE_OFFSET 1 49 #define BATADV_DHCP_HLEN_OFFSET 2 50 /* Value of htype representing Ethernet */ 51 #define BATADV_DHCP_HTYPE_ETHERNET 0x01 52 /* This is the offset of the "chaddr" field in the dhcp packet starting at the 53 * beginning of the dhcp header 54 */ 55 #define BATADV_DHCP_CHADDR_OFFSET 28 56 57 /** 58 * batadv_gw_node_release() - release gw_node from lists and queue for free 59 * after rcu grace period 60 * @ref: kref pointer of the gw_node 61 */ 62 void batadv_gw_node_release(struct kref *ref) 63 { 64 struct batadv_gw_node *gw_node; 65 66 gw_node = container_of(ref, struct batadv_gw_node, refcount); 67 68 batadv_orig_node_put(gw_node->orig_node); 69 kfree_rcu(gw_node, rcu); 70 } 71 72 /** 73 * batadv_gw_get_selected_gw_node() - Get currently selected gateway 74 * @bat_priv: the bat priv with all the soft interface information 75 * 76 * Return: selected gateway (with increased refcnt), NULL on errors 77 */ 78 struct batadv_gw_node * 79 batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv) 80 { 81 struct batadv_gw_node *gw_node; 82 83 rcu_read_lock(); 84 gw_node = rcu_dereference(bat_priv->gw.curr_gw); 85 if (!gw_node) 86 goto out; 87 88 if (!kref_get_unless_zero(&gw_node->refcount)) 89 gw_node = NULL; 90 91 out: 92 rcu_read_unlock(); 93 return gw_node; 94 } 95 96 /** 97 * batadv_gw_get_selected_orig() - Get originator of currently selected gateway 98 * @bat_priv: the bat priv with all the soft interface information 99 * 100 * Return: orig_node of selected gateway (with increased refcnt), NULL on errors 101 */ 102 struct batadv_orig_node * 103 batadv_gw_get_selected_orig(struct batadv_priv *bat_priv) 104 { 105 struct batadv_gw_node *gw_node; 106 struct batadv_orig_node *orig_node = NULL; 107 108 gw_node = batadv_gw_get_selected_gw_node(bat_priv); 109 if (!gw_node) 110 goto out; 111 112 rcu_read_lock(); 113 orig_node = gw_node->orig_node; 114 if (!orig_node) 115 goto unlock; 116 117 if (!kref_get_unless_zero(&orig_node->refcount)) 118 orig_node = NULL; 119 120 unlock: 121 rcu_read_unlock(); 122 out: 123 if (gw_node) 124 batadv_gw_node_put(gw_node); 125 return orig_node; 126 } 127 128 static void batadv_gw_select(struct batadv_priv *bat_priv, 129 struct batadv_gw_node *new_gw_node) 130 { 131 struct batadv_gw_node *curr_gw_node; 132 133 spin_lock_bh(&bat_priv->gw.list_lock); 134 135 if (new_gw_node) 136 kref_get(&new_gw_node->refcount); 137 138 curr_gw_node = rcu_replace_pointer(bat_priv->gw.curr_gw, new_gw_node, 139 true); 140 141 if (curr_gw_node) 142 batadv_gw_node_put(curr_gw_node); 143 144 spin_unlock_bh(&bat_priv->gw.list_lock); 145 } 146 147 /** 148 * batadv_gw_reselect() - force a gateway reselection 149 * @bat_priv: the bat priv with all the soft interface information 150 * 151 * Set a flag to remind the GW component to perform a new gateway reselection. 152 * However this function does not ensure that the current gateway is going to be 153 * deselected. The reselection mechanism may elect the same gateway once again. 154 * 155 * This means that invoking batadv_gw_reselect() does not guarantee a gateway 156 * change and therefore a uevent is not necessarily expected. 157 */ 158 void batadv_gw_reselect(struct batadv_priv *bat_priv) 159 { 160 atomic_set(&bat_priv->gw.reselect, 1); 161 } 162 163 /** 164 * batadv_gw_check_client_stop() - check if client mode has been switched off 165 * @bat_priv: the bat priv with all the soft interface information 166 * 167 * This function assumes the caller has checked that the gw state *is actually 168 * changing*. This function is not supposed to be called when there is no state 169 * change. 170 */ 171 void batadv_gw_check_client_stop(struct batadv_priv *bat_priv) 172 { 173 struct batadv_gw_node *curr_gw; 174 175 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT) 176 return; 177 178 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 179 if (!curr_gw) 180 return; 181 182 /* deselect the current gateway so that next time that client mode is 183 * enabled a proper GW_ADD event can be sent 184 */ 185 batadv_gw_select(bat_priv, NULL); 186 187 /* if batman-adv is switching the gw client mode off and a gateway was 188 * already selected, send a DEL uevent 189 */ 190 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL); 191 192 batadv_gw_node_put(curr_gw); 193 } 194 195 /** 196 * batadv_gw_election() - Elect the best gateway 197 * @bat_priv: the bat priv with all the soft interface information 198 */ 199 void batadv_gw_election(struct batadv_priv *bat_priv) 200 { 201 struct batadv_gw_node *curr_gw = NULL; 202 struct batadv_gw_node *next_gw = NULL; 203 struct batadv_neigh_node *router = NULL; 204 struct batadv_neigh_ifinfo *router_ifinfo = NULL; 205 char gw_addr[18] = { '\0' }; 206 207 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT) 208 goto out; 209 210 if (!bat_priv->algo_ops->gw.get_best_gw_node) 211 goto out; 212 213 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 214 215 if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw) 216 goto out; 217 218 /* if gw.reselect is set to 1 it means that a previous call to 219 * gw.is_eligible() said that we have a new best GW, therefore it can 220 * now be picked from the list and selected 221 */ 222 next_gw = bat_priv->algo_ops->gw.get_best_gw_node(bat_priv); 223 224 if (curr_gw == next_gw) 225 goto out; 226 227 if (next_gw) { 228 sprintf(gw_addr, "%pM", next_gw->orig_node->orig); 229 230 router = batadv_orig_router_get(next_gw->orig_node, 231 BATADV_IF_DEFAULT); 232 if (!router) { 233 batadv_gw_reselect(bat_priv); 234 goto out; 235 } 236 237 router_ifinfo = batadv_neigh_ifinfo_get(router, 238 BATADV_IF_DEFAULT); 239 if (!router_ifinfo) { 240 batadv_gw_reselect(bat_priv); 241 goto out; 242 } 243 } 244 245 if (curr_gw && !next_gw) { 246 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 247 "Removing selected gateway - no gateway in range\n"); 248 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, 249 NULL); 250 } else if (!curr_gw && next_gw) { 251 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 252 "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n", 253 next_gw->orig_node->orig, 254 next_gw->bandwidth_down / 10, 255 next_gw->bandwidth_down % 10, 256 next_gw->bandwidth_up / 10, 257 next_gw->bandwidth_up % 10, 258 router_ifinfo->bat_iv.tq_avg); 259 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, 260 gw_addr); 261 } else { 262 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 263 "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n", 264 next_gw->orig_node->orig, 265 next_gw->bandwidth_down / 10, 266 next_gw->bandwidth_down % 10, 267 next_gw->bandwidth_up / 10, 268 next_gw->bandwidth_up % 10, 269 router_ifinfo->bat_iv.tq_avg); 270 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, 271 gw_addr); 272 } 273 274 batadv_gw_select(bat_priv, next_gw); 275 276 out: 277 if (curr_gw) 278 batadv_gw_node_put(curr_gw); 279 if (next_gw) 280 batadv_gw_node_put(next_gw); 281 if (router) 282 batadv_neigh_node_put(router); 283 if (router_ifinfo) 284 batadv_neigh_ifinfo_put(router_ifinfo); 285 } 286 287 /** 288 * batadv_gw_check_election() - Elect orig node as best gateway when eligible 289 * @bat_priv: the bat priv with all the soft interface information 290 * @orig_node: orig node which is to be checked 291 */ 292 void batadv_gw_check_election(struct batadv_priv *bat_priv, 293 struct batadv_orig_node *orig_node) 294 { 295 struct batadv_orig_node *curr_gw_orig; 296 297 /* abort immediately if the routing algorithm does not support gateway 298 * election 299 */ 300 if (!bat_priv->algo_ops->gw.is_eligible) 301 return; 302 303 curr_gw_orig = batadv_gw_get_selected_orig(bat_priv); 304 if (!curr_gw_orig) 305 goto reselect; 306 307 /* this node already is the gateway */ 308 if (curr_gw_orig == orig_node) 309 goto out; 310 311 if (!bat_priv->algo_ops->gw.is_eligible(bat_priv, curr_gw_orig, 312 orig_node)) 313 goto out; 314 315 reselect: 316 batadv_gw_reselect(bat_priv); 317 out: 318 if (curr_gw_orig) 319 batadv_orig_node_put(curr_gw_orig); 320 } 321 322 /** 323 * batadv_gw_node_add() - add gateway node to list of available gateways 324 * @bat_priv: the bat priv with all the soft interface information 325 * @orig_node: originator announcing gateway capabilities 326 * @gateway: announced bandwidth information 327 * 328 * Has to be called with the appropriate locks being acquired 329 * (gw.list_lock). 330 */ 331 static void batadv_gw_node_add(struct batadv_priv *bat_priv, 332 struct batadv_orig_node *orig_node, 333 struct batadv_tvlv_gateway_data *gateway) 334 { 335 struct batadv_gw_node *gw_node; 336 337 lockdep_assert_held(&bat_priv->gw.list_lock); 338 339 if (gateway->bandwidth_down == 0) 340 return; 341 342 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); 343 if (!gw_node) 344 return; 345 346 kref_init(&gw_node->refcount); 347 INIT_HLIST_NODE(&gw_node->list); 348 kref_get(&orig_node->refcount); 349 gw_node->orig_node = orig_node; 350 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); 351 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up); 352 353 kref_get(&gw_node->refcount); 354 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list); 355 bat_priv->gw.generation++; 356 357 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 358 "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n", 359 orig_node->orig, 360 ntohl(gateway->bandwidth_down) / 10, 361 ntohl(gateway->bandwidth_down) % 10, 362 ntohl(gateway->bandwidth_up) / 10, 363 ntohl(gateway->bandwidth_up) % 10); 364 365 /* don't return reference to new gw_node */ 366 batadv_gw_node_put(gw_node); 367 } 368 369 /** 370 * batadv_gw_node_get() - retrieve gateway node from list of available gateways 371 * @bat_priv: the bat priv with all the soft interface information 372 * @orig_node: originator announcing gateway capabilities 373 * 374 * Return: gateway node if found or NULL otherwise. 375 */ 376 struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv, 377 struct batadv_orig_node *orig_node) 378 { 379 struct batadv_gw_node *gw_node_tmp, *gw_node = NULL; 380 381 rcu_read_lock(); 382 hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.gateway_list, 383 list) { 384 if (gw_node_tmp->orig_node != orig_node) 385 continue; 386 387 if (!kref_get_unless_zero(&gw_node_tmp->refcount)) 388 continue; 389 390 gw_node = gw_node_tmp; 391 break; 392 } 393 rcu_read_unlock(); 394 395 return gw_node; 396 } 397 398 /** 399 * batadv_gw_node_update() - update list of available gateways with changed 400 * bandwidth information 401 * @bat_priv: the bat priv with all the soft interface information 402 * @orig_node: originator announcing gateway capabilities 403 * @gateway: announced bandwidth information 404 */ 405 void batadv_gw_node_update(struct batadv_priv *bat_priv, 406 struct batadv_orig_node *orig_node, 407 struct batadv_tvlv_gateway_data *gateway) 408 { 409 struct batadv_gw_node *gw_node, *curr_gw = NULL; 410 411 spin_lock_bh(&bat_priv->gw.list_lock); 412 gw_node = batadv_gw_node_get(bat_priv, orig_node); 413 if (!gw_node) { 414 batadv_gw_node_add(bat_priv, orig_node, gateway); 415 spin_unlock_bh(&bat_priv->gw.list_lock); 416 goto out; 417 } 418 spin_unlock_bh(&bat_priv->gw.list_lock); 419 420 if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) && 421 gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)) 422 goto out; 423 424 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 425 "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n", 426 orig_node->orig, 427 gw_node->bandwidth_down / 10, 428 gw_node->bandwidth_down % 10, 429 gw_node->bandwidth_up / 10, 430 gw_node->bandwidth_up % 10, 431 ntohl(gateway->bandwidth_down) / 10, 432 ntohl(gateway->bandwidth_down) % 10, 433 ntohl(gateway->bandwidth_up) / 10, 434 ntohl(gateway->bandwidth_up) % 10); 435 436 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); 437 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up); 438 439 if (ntohl(gateway->bandwidth_down) == 0) { 440 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 441 "Gateway %pM removed from gateway list\n", 442 orig_node->orig); 443 444 /* Note: We don't need a NULL check here, since curr_gw never 445 * gets dereferenced. 446 */ 447 spin_lock_bh(&bat_priv->gw.list_lock); 448 if (!hlist_unhashed(&gw_node->list)) { 449 hlist_del_init_rcu(&gw_node->list); 450 batadv_gw_node_put(gw_node); 451 bat_priv->gw.generation++; 452 } 453 spin_unlock_bh(&bat_priv->gw.list_lock); 454 455 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 456 if (gw_node == curr_gw) 457 batadv_gw_reselect(bat_priv); 458 459 if (curr_gw) 460 batadv_gw_node_put(curr_gw); 461 } 462 463 out: 464 if (gw_node) 465 batadv_gw_node_put(gw_node); 466 } 467 468 /** 469 * batadv_gw_node_delete() - Remove orig_node from gateway list 470 * @bat_priv: the bat priv with all the soft interface information 471 * @orig_node: orig node which is currently in process of being removed 472 */ 473 void batadv_gw_node_delete(struct batadv_priv *bat_priv, 474 struct batadv_orig_node *orig_node) 475 { 476 struct batadv_tvlv_gateway_data gateway; 477 478 gateway.bandwidth_down = 0; 479 gateway.bandwidth_up = 0; 480 481 batadv_gw_node_update(bat_priv, orig_node, &gateway); 482 } 483 484 /** 485 * batadv_gw_node_free() - Free gateway information from soft interface 486 * @bat_priv: the bat priv with all the soft interface information 487 */ 488 void batadv_gw_node_free(struct batadv_priv *bat_priv) 489 { 490 struct batadv_gw_node *gw_node; 491 struct hlist_node *node_tmp; 492 493 spin_lock_bh(&bat_priv->gw.list_lock); 494 hlist_for_each_entry_safe(gw_node, node_tmp, 495 &bat_priv->gw.gateway_list, list) { 496 hlist_del_init_rcu(&gw_node->list); 497 batadv_gw_node_put(gw_node); 498 bat_priv->gw.generation++; 499 } 500 spin_unlock_bh(&bat_priv->gw.list_lock); 501 } 502 503 /** 504 * batadv_gw_dump() - Dump gateways into a message 505 * @msg: Netlink message to dump into 506 * @cb: Control block containing additional options 507 * 508 * Return: Error code, or length of message 509 */ 510 int batadv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb) 511 { 512 struct batadv_hard_iface *primary_if = NULL; 513 struct net *net = sock_net(cb->skb->sk); 514 struct net_device *soft_iface; 515 struct batadv_priv *bat_priv; 516 int ifindex; 517 int ret; 518 519 ifindex = batadv_netlink_get_ifindex(cb->nlh, 520 BATADV_ATTR_MESH_IFINDEX); 521 if (!ifindex) 522 return -EINVAL; 523 524 soft_iface = dev_get_by_index(net, ifindex); 525 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 526 ret = -ENODEV; 527 goto out; 528 } 529 530 bat_priv = netdev_priv(soft_iface); 531 532 primary_if = batadv_primary_if_get_selected(bat_priv); 533 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { 534 ret = -ENOENT; 535 goto out; 536 } 537 538 if (!bat_priv->algo_ops->gw.dump) { 539 ret = -EOPNOTSUPP; 540 goto out; 541 } 542 543 bat_priv->algo_ops->gw.dump(msg, cb, bat_priv); 544 545 ret = msg->len; 546 547 out: 548 if (primary_if) 549 batadv_hardif_put(primary_if); 550 dev_put(soft_iface); 551 552 return ret; 553 } 554 555 /** 556 * batadv_gw_dhcp_recipient_get() - check if a packet is a DHCP message 557 * @skb: the packet to check 558 * @header_len: a pointer to the batman-adv header size 559 * @chaddr: buffer where the client address will be stored. Valid 560 * only if the function returns BATADV_DHCP_TO_CLIENT 561 * 562 * This function may re-allocate the data buffer of the skb passed as argument. 563 * 564 * Return: 565 * - BATADV_DHCP_NO if the packet is not a dhcp message or if there was an error 566 * while parsing it 567 * - BATADV_DHCP_TO_SERVER if this is a message going to the DHCP server 568 * - BATADV_DHCP_TO_CLIENT if this is a message going to a DHCP client 569 */ 570 enum batadv_dhcp_recipient 571 batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, 572 u8 *chaddr) 573 { 574 enum batadv_dhcp_recipient ret = BATADV_DHCP_NO; 575 struct ethhdr *ethhdr; 576 struct iphdr *iphdr; 577 struct ipv6hdr *ipv6hdr; 578 struct udphdr *udphdr; 579 struct vlan_ethhdr *vhdr; 580 int chaddr_offset; 581 __be16 proto; 582 u8 *p; 583 584 /* check for ethernet header */ 585 if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) 586 return BATADV_DHCP_NO; 587 588 ethhdr = eth_hdr(skb); 589 proto = ethhdr->h_proto; 590 *header_len += ETH_HLEN; 591 592 /* check for initial vlan header */ 593 if (proto == htons(ETH_P_8021Q)) { 594 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) 595 return BATADV_DHCP_NO; 596 597 vhdr = vlan_eth_hdr(skb); 598 proto = vhdr->h_vlan_encapsulated_proto; 599 *header_len += VLAN_HLEN; 600 } 601 602 /* check for ip header */ 603 switch (proto) { 604 case htons(ETH_P_IP): 605 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) 606 return BATADV_DHCP_NO; 607 608 iphdr = (struct iphdr *)(skb->data + *header_len); 609 *header_len += iphdr->ihl * 4; 610 611 /* check for udp header */ 612 if (iphdr->protocol != IPPROTO_UDP) 613 return BATADV_DHCP_NO; 614 615 break; 616 case htons(ETH_P_IPV6): 617 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) 618 return BATADV_DHCP_NO; 619 620 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); 621 *header_len += sizeof(*ipv6hdr); 622 623 /* check for udp header */ 624 if (ipv6hdr->nexthdr != IPPROTO_UDP) 625 return BATADV_DHCP_NO; 626 627 break; 628 default: 629 return BATADV_DHCP_NO; 630 } 631 632 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr))) 633 return BATADV_DHCP_NO; 634 635 udphdr = (struct udphdr *)(skb->data + *header_len); 636 *header_len += sizeof(*udphdr); 637 638 /* check for bootp port */ 639 switch (proto) { 640 case htons(ETH_P_IP): 641 if (udphdr->dest == htons(67)) 642 ret = BATADV_DHCP_TO_SERVER; 643 else if (udphdr->source == htons(67)) 644 ret = BATADV_DHCP_TO_CLIENT; 645 break; 646 case htons(ETH_P_IPV6): 647 if (udphdr->dest == htons(547)) 648 ret = BATADV_DHCP_TO_SERVER; 649 else if (udphdr->source == htons(547)) 650 ret = BATADV_DHCP_TO_CLIENT; 651 break; 652 } 653 654 chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET; 655 /* store the client address if the message is going to a client */ 656 if (ret == BATADV_DHCP_TO_CLIENT) { 657 if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) 658 return BATADV_DHCP_NO; 659 660 /* check if the DHCP packet carries an Ethernet DHCP */ 661 p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET; 662 if (*p != BATADV_DHCP_HTYPE_ETHERNET) 663 return BATADV_DHCP_NO; 664 665 /* check if the DHCP packet carries a valid Ethernet address */ 666 p = skb->data + *header_len + BATADV_DHCP_HLEN_OFFSET; 667 if (*p != ETH_ALEN) 668 return BATADV_DHCP_NO; 669 670 ether_addr_copy(chaddr, skb->data + chaddr_offset); 671 } 672 673 return ret; 674 } 675 676 /** 677 * batadv_gw_out_of_range() - check if the dhcp request destination is the best 678 * gateway 679 * @bat_priv: the bat priv with all the soft interface information 680 * @skb: the outgoing packet 681 * 682 * Check if the skb is a DHCP request and if it is sent to the current best GW 683 * server. Due to topology changes it may be the case that the GW server 684 * previously selected is not the best one anymore. 685 * 686 * This call might reallocate skb data. 687 * Must be invoked only when the DHCP packet is going TO a DHCP SERVER. 688 * 689 * Return: true if the packet destination is unicast and it is not the best gw, 690 * false otherwise. 691 */ 692 bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, 693 struct sk_buff *skb) 694 { 695 struct batadv_neigh_node *neigh_curr = NULL; 696 struct batadv_neigh_node *neigh_old = NULL; 697 struct batadv_orig_node *orig_dst_node = NULL; 698 struct batadv_gw_node *gw_node = NULL; 699 struct batadv_gw_node *curr_gw = NULL; 700 struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo; 701 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 702 bool out_of_range = false; 703 u8 curr_tq_avg; 704 unsigned short vid; 705 706 vid = batadv_get_vid(skb, 0); 707 708 if (is_multicast_ether_addr(ethhdr->h_dest)) 709 goto out; 710 711 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 712 ethhdr->h_dest, vid); 713 if (!orig_dst_node) 714 goto out; 715 716 gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); 717 if (!gw_node) 718 goto out; 719 720 switch (atomic_read(&bat_priv->gw.mode)) { 721 case BATADV_GW_MODE_SERVER: 722 /* If we are a GW then we are our best GW. We can artificially 723 * set the tq towards ourself as the maximum value 724 */ 725 curr_tq_avg = BATADV_TQ_MAX_VALUE; 726 break; 727 case BATADV_GW_MODE_CLIENT: 728 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 729 if (!curr_gw) 730 goto out; 731 732 /* packet is going to our gateway */ 733 if (curr_gw->orig_node == orig_dst_node) 734 goto out; 735 736 /* If the dhcp packet has been sent to a different gw, 737 * we have to evaluate whether the old gw is still 738 * reliable enough 739 */ 740 neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node, 741 NULL); 742 if (!neigh_curr) 743 goto out; 744 745 curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr, 746 BATADV_IF_DEFAULT); 747 if (!curr_ifinfo) 748 goto out; 749 750 curr_tq_avg = curr_ifinfo->bat_iv.tq_avg; 751 batadv_neigh_ifinfo_put(curr_ifinfo); 752 753 break; 754 case BATADV_GW_MODE_OFF: 755 default: 756 goto out; 757 } 758 759 neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL); 760 if (!neigh_old) 761 goto out; 762 763 old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT); 764 if (!old_ifinfo) 765 goto out; 766 767 if ((curr_tq_avg - old_ifinfo->bat_iv.tq_avg) > BATADV_GW_THRESHOLD) 768 out_of_range = true; 769 batadv_neigh_ifinfo_put(old_ifinfo); 770 771 out: 772 if (orig_dst_node) 773 batadv_orig_node_put(orig_dst_node); 774 if (curr_gw) 775 batadv_gw_node_put(curr_gw); 776 if (gw_node) 777 batadv_gw_node_put(gw_node); 778 if (neigh_old) 779 batadv_neigh_node_put(neigh_old); 780 if (neigh_curr) 781 batadv_neigh_node_put(neigh_curr); 782 return out_of_range; 783 } 784