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