bridge_loop_avoidance.c (70998B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (C) B.A.T.M.A.N. contributors: 3 * 4 * Simon Wunderlich 5 */ 6 7#include "bridge_loop_avoidance.h" 8#include "main.h" 9 10#include <linux/atomic.h> 11#include <linux/byteorder/generic.h> 12#include <linux/compiler.h> 13#include <linux/container_of.h> 14#include <linux/crc16.h> 15#include <linux/errno.h> 16#include <linux/etherdevice.h> 17#include <linux/gfp.h> 18#include <linux/if_arp.h> 19#include <linux/if_ether.h> 20#include <linux/if_vlan.h> 21#include <linux/jhash.h> 22#include <linux/jiffies.h> 23#include <linux/kernel.h> 24#include <linux/kref.h> 25#include <linux/list.h> 26#include <linux/lockdep.h> 27#include <linux/netdevice.h> 28#include <linux/netlink.h> 29#include <linux/rculist.h> 30#include <linux/rcupdate.h> 31#include <linux/skbuff.h> 32#include <linux/slab.h> 33#include <linux/spinlock.h> 34#include <linux/stddef.h> 35#include <linux/string.h> 36#include <linux/workqueue.h> 37#include <net/arp.h> 38#include <net/genetlink.h> 39#include <net/netlink.h> 40#include <net/sock.h> 41#include <uapi/linux/batadv_packet.h> 42#include <uapi/linux/batman_adv.h> 43 44#include "hard-interface.h" 45#include "hash.h" 46#include "log.h" 47#include "netlink.h" 48#include "originator.h" 49#include "soft-interface.h" 50#include "translation-table.h" 51 52static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; 53 54static void batadv_bla_periodic_work(struct work_struct *work); 55static void 56batadv_bla_send_announce(struct batadv_priv *bat_priv, 57 struct batadv_bla_backbone_gw *backbone_gw); 58 59/** 60 * batadv_choose_claim() - choose the right bucket for a claim. 61 * @data: data to hash 62 * @size: size of the hash table 63 * 64 * Return: the hash index of the claim 65 */ 66static inline u32 batadv_choose_claim(const void *data, u32 size) 67{ 68 const struct batadv_bla_claim *claim = data; 69 u32 hash = 0; 70 71 hash = jhash(&claim->addr, sizeof(claim->addr), hash); 72 hash = jhash(&claim->vid, sizeof(claim->vid), hash); 73 74 return hash % size; 75} 76 77/** 78 * batadv_choose_backbone_gw() - choose the right bucket for a backbone gateway. 79 * @data: data to hash 80 * @size: size of the hash table 81 * 82 * Return: the hash index of the backbone gateway 83 */ 84static inline u32 batadv_choose_backbone_gw(const void *data, u32 size) 85{ 86 const struct batadv_bla_backbone_gw *gw; 87 u32 hash = 0; 88 89 gw = data; 90 hash = jhash(&gw->orig, sizeof(gw->orig), hash); 91 hash = jhash(&gw->vid, sizeof(gw->vid), hash); 92 93 return hash % size; 94} 95 96/** 97 * batadv_compare_backbone_gw() - compare address and vid of two backbone gws 98 * @node: list node of the first entry to compare 99 * @data2: pointer to the second backbone gateway 100 * 101 * Return: true if the backbones have the same data, false otherwise 102 */ 103static bool batadv_compare_backbone_gw(const struct hlist_node *node, 104 const void *data2) 105{ 106 const void *data1 = container_of(node, struct batadv_bla_backbone_gw, 107 hash_entry); 108 const struct batadv_bla_backbone_gw *gw1 = data1; 109 const struct batadv_bla_backbone_gw *gw2 = data2; 110 111 if (!batadv_compare_eth(gw1->orig, gw2->orig)) 112 return false; 113 114 if (gw1->vid != gw2->vid) 115 return false; 116 117 return true; 118} 119 120/** 121 * batadv_compare_claim() - compare address and vid of two claims 122 * @node: list node of the first entry to compare 123 * @data2: pointer to the second claims 124 * 125 * Return: true if the claim have the same data, 0 otherwise 126 */ 127static bool batadv_compare_claim(const struct hlist_node *node, 128 const void *data2) 129{ 130 const void *data1 = container_of(node, struct batadv_bla_claim, 131 hash_entry); 132 const struct batadv_bla_claim *cl1 = data1; 133 const struct batadv_bla_claim *cl2 = data2; 134 135 if (!batadv_compare_eth(cl1->addr, cl2->addr)) 136 return false; 137 138 if (cl1->vid != cl2->vid) 139 return false; 140 141 return true; 142} 143 144/** 145 * batadv_backbone_gw_release() - release backbone gw from lists and queue for 146 * free after rcu grace period 147 * @ref: kref pointer of the backbone gw 148 */ 149static void batadv_backbone_gw_release(struct kref *ref) 150{ 151 struct batadv_bla_backbone_gw *backbone_gw; 152 153 backbone_gw = container_of(ref, struct batadv_bla_backbone_gw, 154 refcount); 155 156 kfree_rcu(backbone_gw, rcu); 157} 158 159/** 160 * batadv_backbone_gw_put() - decrement the backbone gw refcounter and possibly 161 * release it 162 * @backbone_gw: backbone gateway to be free'd 163 */ 164static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw) 165{ 166 if (!backbone_gw) 167 return; 168 169 kref_put(&backbone_gw->refcount, batadv_backbone_gw_release); 170} 171 172/** 173 * batadv_claim_release() - release claim from lists and queue for free after 174 * rcu grace period 175 * @ref: kref pointer of the claim 176 */ 177static void batadv_claim_release(struct kref *ref) 178{ 179 struct batadv_bla_claim *claim; 180 struct batadv_bla_backbone_gw *old_backbone_gw; 181 182 claim = container_of(ref, struct batadv_bla_claim, refcount); 183 184 spin_lock_bh(&claim->backbone_lock); 185 old_backbone_gw = claim->backbone_gw; 186 claim->backbone_gw = NULL; 187 spin_unlock_bh(&claim->backbone_lock); 188 189 spin_lock_bh(&old_backbone_gw->crc_lock); 190 old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); 191 spin_unlock_bh(&old_backbone_gw->crc_lock); 192 193 batadv_backbone_gw_put(old_backbone_gw); 194 195 kfree_rcu(claim, rcu); 196} 197 198/** 199 * batadv_claim_put() - decrement the claim refcounter and possibly release it 200 * @claim: claim to be free'd 201 */ 202static void batadv_claim_put(struct batadv_bla_claim *claim) 203{ 204 if (!claim) 205 return; 206 207 kref_put(&claim->refcount, batadv_claim_release); 208} 209 210/** 211 * batadv_claim_hash_find() - looks for a claim in the claim hash 212 * @bat_priv: the bat priv with all the soft interface information 213 * @data: search data (may be local/static data) 214 * 215 * Return: claim if found or NULL otherwise. 216 */ 217static struct batadv_bla_claim * 218batadv_claim_hash_find(struct batadv_priv *bat_priv, 219 struct batadv_bla_claim *data) 220{ 221 struct batadv_hashtable *hash = bat_priv->bla.claim_hash; 222 struct hlist_head *head; 223 struct batadv_bla_claim *claim; 224 struct batadv_bla_claim *claim_tmp = NULL; 225 int index; 226 227 if (!hash) 228 return NULL; 229 230 index = batadv_choose_claim(data, hash->size); 231 head = &hash->table[index]; 232 233 rcu_read_lock(); 234 hlist_for_each_entry_rcu(claim, head, hash_entry) { 235 if (!batadv_compare_claim(&claim->hash_entry, data)) 236 continue; 237 238 if (!kref_get_unless_zero(&claim->refcount)) 239 continue; 240 241 claim_tmp = claim; 242 break; 243 } 244 rcu_read_unlock(); 245 246 return claim_tmp; 247} 248 249/** 250 * batadv_backbone_hash_find() - looks for a backbone gateway in the hash 251 * @bat_priv: the bat priv with all the soft interface information 252 * @addr: the address of the originator 253 * @vid: the VLAN ID 254 * 255 * Return: backbone gateway if found or NULL otherwise 256 */ 257static struct batadv_bla_backbone_gw * 258batadv_backbone_hash_find(struct batadv_priv *bat_priv, const u8 *addr, 259 unsigned short vid) 260{ 261 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; 262 struct hlist_head *head; 263 struct batadv_bla_backbone_gw search_entry, *backbone_gw; 264 struct batadv_bla_backbone_gw *backbone_gw_tmp = NULL; 265 int index; 266 267 if (!hash) 268 return NULL; 269 270 ether_addr_copy(search_entry.orig, addr); 271 search_entry.vid = vid; 272 273 index = batadv_choose_backbone_gw(&search_entry, hash->size); 274 head = &hash->table[index]; 275 276 rcu_read_lock(); 277 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 278 if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry, 279 &search_entry)) 280 continue; 281 282 if (!kref_get_unless_zero(&backbone_gw->refcount)) 283 continue; 284 285 backbone_gw_tmp = backbone_gw; 286 break; 287 } 288 rcu_read_unlock(); 289 290 return backbone_gw_tmp; 291} 292 293/** 294 * batadv_bla_del_backbone_claims() - delete all claims for a backbone 295 * @backbone_gw: backbone gateway where the claims should be removed 296 */ 297static void 298batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw) 299{ 300 struct batadv_hashtable *hash; 301 struct hlist_node *node_tmp; 302 struct hlist_head *head; 303 struct batadv_bla_claim *claim; 304 int i; 305 spinlock_t *list_lock; /* protects write access to the hash lists */ 306 307 hash = backbone_gw->bat_priv->bla.claim_hash; 308 if (!hash) 309 return; 310 311 for (i = 0; i < hash->size; i++) { 312 head = &hash->table[i]; 313 list_lock = &hash->list_locks[i]; 314 315 spin_lock_bh(list_lock); 316 hlist_for_each_entry_safe(claim, node_tmp, 317 head, hash_entry) { 318 if (claim->backbone_gw != backbone_gw) 319 continue; 320 321 batadv_claim_put(claim); 322 hlist_del_rcu(&claim->hash_entry); 323 } 324 spin_unlock_bh(list_lock); 325 } 326 327 /* all claims gone, initialize CRC */ 328 spin_lock_bh(&backbone_gw->crc_lock); 329 backbone_gw->crc = BATADV_BLA_CRC_INIT; 330 spin_unlock_bh(&backbone_gw->crc_lock); 331} 332 333/** 334 * batadv_bla_send_claim() - sends a claim frame according to the provided info 335 * @bat_priv: the bat priv with all the soft interface information 336 * @mac: the mac address to be announced within the claim 337 * @vid: the VLAN ID 338 * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...) 339 */ 340static void batadv_bla_send_claim(struct batadv_priv *bat_priv, const u8 *mac, 341 unsigned short vid, int claimtype) 342{ 343 struct sk_buff *skb; 344 struct ethhdr *ethhdr; 345 struct batadv_hard_iface *primary_if; 346 struct net_device *soft_iface; 347 u8 *hw_src; 348 struct batadv_bla_claim_dst local_claim_dest; 349 __be32 zeroip = 0; 350 351 primary_if = batadv_primary_if_get_selected(bat_priv); 352 if (!primary_if) 353 return; 354 355 memcpy(&local_claim_dest, &bat_priv->bla.claim_dest, 356 sizeof(local_claim_dest)); 357 local_claim_dest.type = claimtype; 358 359 soft_iface = primary_if->soft_iface; 360 361 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, 362 /* IP DST: 0.0.0.0 */ 363 zeroip, 364 primary_if->soft_iface, 365 /* IP SRC: 0.0.0.0 */ 366 zeroip, 367 /* Ethernet DST: Broadcast */ 368 NULL, 369 /* Ethernet SRC/HW SRC: originator mac */ 370 primary_if->net_dev->dev_addr, 371 /* HW DST: FF:43:05:XX:YY:YY 372 * with XX = claim type 373 * and YY:YY = group id 374 */ 375 (u8 *)&local_claim_dest); 376 377 if (!skb) 378 goto out; 379 380 ethhdr = (struct ethhdr *)skb->data; 381 hw_src = (u8 *)ethhdr + ETH_HLEN + sizeof(struct arphdr); 382 383 /* now we pretend that the client would have sent this ... */ 384 switch (claimtype) { 385 case BATADV_CLAIM_TYPE_CLAIM: 386 /* normal claim frame 387 * set Ethernet SRC to the clients mac 388 */ 389 ether_addr_copy(ethhdr->h_source, mac); 390 batadv_dbg(BATADV_DBG_BLA, bat_priv, 391 "%s(): CLAIM %pM on vid %d\n", __func__, mac, 392 batadv_print_vid(vid)); 393 break; 394 case BATADV_CLAIM_TYPE_UNCLAIM: 395 /* unclaim frame 396 * set HW SRC to the clients mac 397 */ 398 ether_addr_copy(hw_src, mac); 399 batadv_dbg(BATADV_DBG_BLA, bat_priv, 400 "%s(): UNCLAIM %pM on vid %d\n", __func__, mac, 401 batadv_print_vid(vid)); 402 break; 403 case BATADV_CLAIM_TYPE_ANNOUNCE: 404 /* announcement frame 405 * set HW SRC to the special mac containing the crc 406 */ 407 ether_addr_copy(hw_src, mac); 408 batadv_dbg(BATADV_DBG_BLA, bat_priv, 409 "%s(): ANNOUNCE of %pM on vid %d\n", __func__, 410 ethhdr->h_source, batadv_print_vid(vid)); 411 break; 412 case BATADV_CLAIM_TYPE_REQUEST: 413 /* request frame 414 * set HW SRC and header destination to the receiving backbone 415 * gws mac 416 */ 417 ether_addr_copy(hw_src, mac); 418 ether_addr_copy(ethhdr->h_dest, mac); 419 batadv_dbg(BATADV_DBG_BLA, bat_priv, 420 "%s(): REQUEST of %pM to %pM on vid %d\n", __func__, 421 ethhdr->h_source, ethhdr->h_dest, 422 batadv_print_vid(vid)); 423 break; 424 case BATADV_CLAIM_TYPE_LOOPDETECT: 425 ether_addr_copy(ethhdr->h_source, mac); 426 batadv_dbg(BATADV_DBG_BLA, bat_priv, 427 "%s(): LOOPDETECT of %pM to %pM on vid %d\n", 428 __func__, ethhdr->h_source, ethhdr->h_dest, 429 batadv_print_vid(vid)); 430 431 break; 432 } 433 434 if (vid & BATADV_VLAN_HAS_TAG) { 435 skb = vlan_insert_tag(skb, htons(ETH_P_8021Q), 436 vid & VLAN_VID_MASK); 437 if (!skb) 438 goto out; 439 } 440 441 skb_reset_mac_header(skb); 442 skb->protocol = eth_type_trans(skb, soft_iface); 443 batadv_inc_counter(bat_priv, BATADV_CNT_RX); 444 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, 445 skb->len + ETH_HLEN); 446 447 netif_rx(skb); 448out: 449 batadv_hardif_put(primary_if); 450} 451 452/** 453 * batadv_bla_loopdetect_report() - worker for reporting the loop 454 * @work: work queue item 455 * 456 * Throws an uevent, as the loopdetect check function can't do that itself 457 * since the kernel may sleep while throwing uevents. 458 */ 459static void batadv_bla_loopdetect_report(struct work_struct *work) 460{ 461 struct batadv_bla_backbone_gw *backbone_gw; 462 struct batadv_priv *bat_priv; 463 char vid_str[6] = { '\0' }; 464 465 backbone_gw = container_of(work, struct batadv_bla_backbone_gw, 466 report_work); 467 bat_priv = backbone_gw->bat_priv; 468 469 batadv_info(bat_priv->soft_iface, 470 "Possible loop on VLAN %d detected which can't be handled by BLA - please check your network setup!\n", 471 batadv_print_vid(backbone_gw->vid)); 472 snprintf(vid_str, sizeof(vid_str), "%d", 473 batadv_print_vid(backbone_gw->vid)); 474 vid_str[sizeof(vid_str) - 1] = 0; 475 476 batadv_throw_uevent(bat_priv, BATADV_UEV_BLA, BATADV_UEV_LOOPDETECT, 477 vid_str); 478 479 batadv_backbone_gw_put(backbone_gw); 480} 481 482/** 483 * batadv_bla_get_backbone_gw() - finds or creates a backbone gateway 484 * @bat_priv: the bat priv with all the soft interface information 485 * @orig: the mac address of the originator 486 * @vid: the VLAN ID 487 * @own_backbone: set if the requested backbone is local 488 * 489 * Return: the (possibly created) backbone gateway or NULL on error 490 */ 491static struct batadv_bla_backbone_gw * 492batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig, 493 unsigned short vid, bool own_backbone) 494{ 495 struct batadv_bla_backbone_gw *entry; 496 struct batadv_orig_node *orig_node; 497 int hash_added; 498 499 entry = batadv_backbone_hash_find(bat_priv, orig, vid); 500 501 if (entry) 502 return entry; 503 504 batadv_dbg(BATADV_DBG_BLA, bat_priv, 505 "%s(): not found (%pM, %d), creating new entry\n", __func__, 506 orig, batadv_print_vid(vid)); 507 508 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 509 if (!entry) 510 return NULL; 511 512 entry->vid = vid; 513 entry->lasttime = jiffies; 514 entry->crc = BATADV_BLA_CRC_INIT; 515 entry->bat_priv = bat_priv; 516 spin_lock_init(&entry->crc_lock); 517 atomic_set(&entry->request_sent, 0); 518 atomic_set(&entry->wait_periods, 0); 519 ether_addr_copy(entry->orig, orig); 520 INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report); 521 kref_init(&entry->refcount); 522 523 kref_get(&entry->refcount); 524 hash_added = batadv_hash_add(bat_priv->bla.backbone_hash, 525 batadv_compare_backbone_gw, 526 batadv_choose_backbone_gw, entry, 527 &entry->hash_entry); 528 529 if (unlikely(hash_added != 0)) { 530 /* hash failed, free the structure */ 531 kfree(entry); 532 return NULL; 533 } 534 535 /* this is a gateway now, remove any TT entry on this VLAN */ 536 orig_node = batadv_orig_hash_find(bat_priv, orig); 537 if (orig_node) { 538 batadv_tt_global_del_orig(bat_priv, orig_node, vid, 539 "became a backbone gateway"); 540 batadv_orig_node_put(orig_node); 541 } 542 543 if (own_backbone) { 544 batadv_bla_send_announce(bat_priv, entry); 545 546 /* this will be decreased in the worker thread */ 547 atomic_inc(&entry->request_sent); 548 atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS); 549 atomic_inc(&bat_priv->bla.num_requests); 550 } 551 552 return entry; 553} 554 555/** 556 * batadv_bla_update_own_backbone_gw() - updates the own backbone gw for a VLAN 557 * @bat_priv: the bat priv with all the soft interface information 558 * @primary_if: the selected primary interface 559 * @vid: VLAN identifier 560 * 561 * update or add the own backbone gw to make sure we announce 562 * where we receive other backbone gws 563 */ 564static void 565batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv, 566 struct batadv_hard_iface *primary_if, 567 unsigned short vid) 568{ 569 struct batadv_bla_backbone_gw *backbone_gw; 570 571 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, 572 primary_if->net_dev->dev_addr, 573 vid, true); 574 if (unlikely(!backbone_gw)) 575 return; 576 577 backbone_gw->lasttime = jiffies; 578 batadv_backbone_gw_put(backbone_gw); 579} 580 581/** 582 * batadv_bla_answer_request() - answer a bla request by sending own claims 583 * @bat_priv: the bat priv with all the soft interface information 584 * @primary_if: interface where the request came on 585 * @vid: the vid where the request came on 586 * 587 * Repeat all of our own claims, and finally send an ANNOUNCE frame 588 * to allow the requester another check if the CRC is correct now. 589 */ 590static void batadv_bla_answer_request(struct batadv_priv *bat_priv, 591 struct batadv_hard_iface *primary_if, 592 unsigned short vid) 593{ 594 struct hlist_head *head; 595 struct batadv_hashtable *hash; 596 struct batadv_bla_claim *claim; 597 struct batadv_bla_backbone_gw *backbone_gw; 598 int i; 599 600 batadv_dbg(BATADV_DBG_BLA, bat_priv, 601 "%s(): received a claim request, send all of our own claims again\n", 602 __func__); 603 604 backbone_gw = batadv_backbone_hash_find(bat_priv, 605 primary_if->net_dev->dev_addr, 606 vid); 607 if (!backbone_gw) 608 return; 609 610 hash = bat_priv->bla.claim_hash; 611 for (i = 0; i < hash->size; i++) { 612 head = &hash->table[i]; 613 614 rcu_read_lock(); 615 hlist_for_each_entry_rcu(claim, head, hash_entry) { 616 /* only own claims are interesting */ 617 if (claim->backbone_gw != backbone_gw) 618 continue; 619 620 batadv_bla_send_claim(bat_priv, claim->addr, claim->vid, 621 BATADV_CLAIM_TYPE_CLAIM); 622 } 623 rcu_read_unlock(); 624 } 625 626 /* finally, send an announcement frame */ 627 batadv_bla_send_announce(bat_priv, backbone_gw); 628 batadv_backbone_gw_put(backbone_gw); 629} 630 631/** 632 * batadv_bla_send_request() - send a request to repeat claims 633 * @backbone_gw: the backbone gateway from whom we are out of sync 634 * 635 * When the crc is wrong, ask the backbone gateway for a full table update. 636 * After the request, it will repeat all of his own claims and finally 637 * send an announcement claim with which we can check again. 638 */ 639static void batadv_bla_send_request(struct batadv_bla_backbone_gw *backbone_gw) 640{ 641 /* first, remove all old entries */ 642 batadv_bla_del_backbone_claims(backbone_gw); 643 644 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, 645 "Sending REQUEST to %pM\n", backbone_gw->orig); 646 647 /* send request */ 648 batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig, 649 backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST); 650 651 /* no local broadcasts should be sent or received, for now. */ 652 if (!atomic_read(&backbone_gw->request_sent)) { 653 atomic_inc(&backbone_gw->bat_priv->bla.num_requests); 654 atomic_set(&backbone_gw->request_sent, 1); 655 } 656} 657 658/** 659 * batadv_bla_send_announce() - Send an announcement frame 660 * @bat_priv: the bat priv with all the soft interface information 661 * @backbone_gw: our backbone gateway which should be announced 662 */ 663static void batadv_bla_send_announce(struct batadv_priv *bat_priv, 664 struct batadv_bla_backbone_gw *backbone_gw) 665{ 666 u8 mac[ETH_ALEN]; 667 __be16 crc; 668 669 memcpy(mac, batadv_announce_mac, 4); 670 spin_lock_bh(&backbone_gw->crc_lock); 671 crc = htons(backbone_gw->crc); 672 spin_unlock_bh(&backbone_gw->crc_lock); 673 memcpy(&mac[4], &crc, 2); 674 675 batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid, 676 BATADV_CLAIM_TYPE_ANNOUNCE); 677} 678 679/** 680 * batadv_bla_add_claim() - Adds a claim in the claim hash 681 * @bat_priv: the bat priv with all the soft interface information 682 * @mac: the mac address of the claim 683 * @vid: the VLAN ID of the frame 684 * @backbone_gw: the backbone gateway which claims it 685 */ 686static void batadv_bla_add_claim(struct batadv_priv *bat_priv, 687 const u8 *mac, const unsigned short vid, 688 struct batadv_bla_backbone_gw *backbone_gw) 689{ 690 struct batadv_bla_backbone_gw *old_backbone_gw; 691 struct batadv_bla_claim *claim; 692 struct batadv_bla_claim search_claim; 693 bool remove_crc = false; 694 int hash_added; 695 696 ether_addr_copy(search_claim.addr, mac); 697 search_claim.vid = vid; 698 claim = batadv_claim_hash_find(bat_priv, &search_claim); 699 700 /* create a new claim entry if it does not exist yet. */ 701 if (!claim) { 702 claim = kzalloc(sizeof(*claim), GFP_ATOMIC); 703 if (!claim) 704 return; 705 706 ether_addr_copy(claim->addr, mac); 707 spin_lock_init(&claim->backbone_lock); 708 claim->vid = vid; 709 claim->lasttime = jiffies; 710 kref_get(&backbone_gw->refcount); 711 claim->backbone_gw = backbone_gw; 712 kref_init(&claim->refcount); 713 714 batadv_dbg(BATADV_DBG_BLA, bat_priv, 715 "%s(): adding new entry %pM, vid %d to hash ...\n", 716 __func__, mac, batadv_print_vid(vid)); 717 718 kref_get(&claim->refcount); 719 hash_added = batadv_hash_add(bat_priv->bla.claim_hash, 720 batadv_compare_claim, 721 batadv_choose_claim, claim, 722 &claim->hash_entry); 723 724 if (unlikely(hash_added != 0)) { 725 /* only local changes happened. */ 726 kfree(claim); 727 return; 728 } 729 } else { 730 claim->lasttime = jiffies; 731 if (claim->backbone_gw == backbone_gw) 732 /* no need to register a new backbone */ 733 goto claim_free_ref; 734 735 batadv_dbg(BATADV_DBG_BLA, bat_priv, 736 "%s(): changing ownership for %pM, vid %d to gw %pM\n", 737 __func__, mac, batadv_print_vid(vid), 738 backbone_gw->orig); 739 740 remove_crc = true; 741 } 742 743 /* replace backbone_gw atomically and adjust reference counters */ 744 spin_lock_bh(&claim->backbone_lock); 745 old_backbone_gw = claim->backbone_gw; 746 kref_get(&backbone_gw->refcount); 747 claim->backbone_gw = backbone_gw; 748 spin_unlock_bh(&claim->backbone_lock); 749 750 if (remove_crc) { 751 /* remove claim address from old backbone_gw */ 752 spin_lock_bh(&old_backbone_gw->crc_lock); 753 old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); 754 spin_unlock_bh(&old_backbone_gw->crc_lock); 755 } 756 757 batadv_backbone_gw_put(old_backbone_gw); 758 759 /* add claim address to new backbone_gw */ 760 spin_lock_bh(&backbone_gw->crc_lock); 761 backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); 762 spin_unlock_bh(&backbone_gw->crc_lock); 763 backbone_gw->lasttime = jiffies; 764 765claim_free_ref: 766 batadv_claim_put(claim); 767} 768 769/** 770 * batadv_bla_claim_get_backbone_gw() - Get valid reference for backbone_gw of 771 * claim 772 * @claim: claim whose backbone_gw should be returned 773 * 774 * Return: valid reference to claim::backbone_gw 775 */ 776static struct batadv_bla_backbone_gw * 777batadv_bla_claim_get_backbone_gw(struct batadv_bla_claim *claim) 778{ 779 struct batadv_bla_backbone_gw *backbone_gw; 780 781 spin_lock_bh(&claim->backbone_lock); 782 backbone_gw = claim->backbone_gw; 783 kref_get(&backbone_gw->refcount); 784 spin_unlock_bh(&claim->backbone_lock); 785 786 return backbone_gw; 787} 788 789/** 790 * batadv_bla_del_claim() - delete a claim from the claim hash 791 * @bat_priv: the bat priv with all the soft interface information 792 * @mac: mac address of the claim to be removed 793 * @vid: VLAN id for the claim to be removed 794 */ 795static void batadv_bla_del_claim(struct batadv_priv *bat_priv, 796 const u8 *mac, const unsigned short vid) 797{ 798 struct batadv_bla_claim search_claim, *claim; 799 struct batadv_bla_claim *claim_removed_entry; 800 struct hlist_node *claim_removed_node; 801 802 ether_addr_copy(search_claim.addr, mac); 803 search_claim.vid = vid; 804 claim = batadv_claim_hash_find(bat_priv, &search_claim); 805 if (!claim) 806 return; 807 808 batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): %pM, vid %d\n", __func__, 809 mac, batadv_print_vid(vid)); 810 811 claim_removed_node = batadv_hash_remove(bat_priv->bla.claim_hash, 812 batadv_compare_claim, 813 batadv_choose_claim, claim); 814 if (!claim_removed_node) 815 goto free_claim; 816 817 /* reference from the hash is gone */ 818 claim_removed_entry = hlist_entry(claim_removed_node, 819 struct batadv_bla_claim, hash_entry); 820 batadv_claim_put(claim_removed_entry); 821 822free_claim: 823 /* don't need the reference from hash_find() anymore */ 824 batadv_claim_put(claim); 825} 826 827/** 828 * batadv_handle_announce() - check for ANNOUNCE frame 829 * @bat_priv: the bat priv with all the soft interface information 830 * @an_addr: announcement mac address (ARP Sender HW address) 831 * @backbone_addr: originator address of the sender (Ethernet source MAC) 832 * @vid: the VLAN ID of the frame 833 * 834 * Return: true if handled 835 */ 836static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, 837 u8 *backbone_addr, unsigned short vid) 838{ 839 struct batadv_bla_backbone_gw *backbone_gw; 840 u16 backbone_crc, crc; 841 842 if (memcmp(an_addr, batadv_announce_mac, 4) != 0) 843 return false; 844 845 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid, 846 false); 847 848 if (unlikely(!backbone_gw)) 849 return true; 850 851 /* handle as ANNOUNCE frame */ 852 backbone_gw->lasttime = jiffies; 853 crc = ntohs(*((__force __be16 *)(&an_addr[4]))); 854 855 batadv_dbg(BATADV_DBG_BLA, bat_priv, 856 "%s(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n", 857 __func__, batadv_print_vid(vid), backbone_gw->orig, crc); 858 859 spin_lock_bh(&backbone_gw->crc_lock); 860 backbone_crc = backbone_gw->crc; 861 spin_unlock_bh(&backbone_gw->crc_lock); 862 863 if (backbone_crc != crc) { 864 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, 865 "%s(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n", 866 __func__, backbone_gw->orig, 867 batadv_print_vid(backbone_gw->vid), 868 backbone_crc, crc); 869 870 batadv_bla_send_request(backbone_gw); 871 } else { 872 /* if we have sent a request and the crc was OK, 873 * we can allow traffic again. 874 */ 875 if (atomic_read(&backbone_gw->request_sent)) { 876 atomic_dec(&backbone_gw->bat_priv->bla.num_requests); 877 atomic_set(&backbone_gw->request_sent, 0); 878 } 879 } 880 881 batadv_backbone_gw_put(backbone_gw); 882 return true; 883} 884 885/** 886 * batadv_handle_request() - check for REQUEST frame 887 * @bat_priv: the bat priv with all the soft interface information 888 * @primary_if: the primary hard interface of this batman soft interface 889 * @backbone_addr: backbone address to be requested (ARP sender HW MAC) 890 * @ethhdr: ethernet header of a packet 891 * @vid: the VLAN ID of the frame 892 * 893 * Return: true if handled 894 */ 895static bool batadv_handle_request(struct batadv_priv *bat_priv, 896 struct batadv_hard_iface *primary_if, 897 u8 *backbone_addr, struct ethhdr *ethhdr, 898 unsigned short vid) 899{ 900 /* check for REQUEST frame */ 901 if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest)) 902 return false; 903 904 /* sanity check, this should not happen on a normal switch, 905 * we ignore it in this case. 906 */ 907 if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) 908 return true; 909 910 batadv_dbg(BATADV_DBG_BLA, bat_priv, 911 "%s(): REQUEST vid %d (sent by %pM)...\n", 912 __func__, batadv_print_vid(vid), ethhdr->h_source); 913 914 batadv_bla_answer_request(bat_priv, primary_if, vid); 915 return true; 916} 917 918/** 919 * batadv_handle_unclaim() - check for UNCLAIM frame 920 * @bat_priv: the bat priv with all the soft interface information 921 * @primary_if: the primary hard interface of this batman soft interface 922 * @backbone_addr: originator address of the backbone (Ethernet source) 923 * @claim_addr: Client to be unclaimed (ARP sender HW MAC) 924 * @vid: the VLAN ID of the frame 925 * 926 * Return: true if handled 927 */ 928static bool batadv_handle_unclaim(struct batadv_priv *bat_priv, 929 struct batadv_hard_iface *primary_if, 930 const u8 *backbone_addr, const u8 *claim_addr, 931 unsigned short vid) 932{ 933 struct batadv_bla_backbone_gw *backbone_gw; 934 935 /* unclaim in any case if it is our own */ 936 if (primary_if && batadv_compare_eth(backbone_addr, 937 primary_if->net_dev->dev_addr)) 938 batadv_bla_send_claim(bat_priv, claim_addr, vid, 939 BATADV_CLAIM_TYPE_UNCLAIM); 940 941 backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); 942 943 if (!backbone_gw) 944 return true; 945 946 /* this must be an UNCLAIM frame */ 947 batadv_dbg(BATADV_DBG_BLA, bat_priv, 948 "%s(): UNCLAIM %pM on vid %d (sent by %pM)...\n", __func__, 949 claim_addr, batadv_print_vid(vid), backbone_gw->orig); 950 951 batadv_bla_del_claim(bat_priv, claim_addr, vid); 952 batadv_backbone_gw_put(backbone_gw); 953 return true; 954} 955 956/** 957 * batadv_handle_claim() - check for CLAIM frame 958 * @bat_priv: the bat priv with all the soft interface information 959 * @primary_if: the primary hard interface of this batman soft interface 960 * @backbone_addr: originator address of the backbone (Ethernet Source) 961 * @claim_addr: client mac address to be claimed (ARP sender HW MAC) 962 * @vid: the VLAN ID of the frame 963 * 964 * Return: true if handled 965 */ 966static bool batadv_handle_claim(struct batadv_priv *bat_priv, 967 struct batadv_hard_iface *primary_if, 968 const u8 *backbone_addr, const u8 *claim_addr, 969 unsigned short vid) 970{ 971 struct batadv_bla_backbone_gw *backbone_gw; 972 973 /* register the gateway if not yet available, and add the claim. */ 974 975 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid, 976 false); 977 978 if (unlikely(!backbone_gw)) 979 return true; 980 981 /* this must be a CLAIM frame */ 982 batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); 983 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) 984 batadv_bla_send_claim(bat_priv, claim_addr, vid, 985 BATADV_CLAIM_TYPE_CLAIM); 986 987 /* TODO: we could call something like tt_local_del() here. */ 988 989 batadv_backbone_gw_put(backbone_gw); 990 return true; 991} 992 993/** 994 * batadv_check_claim_group() - check for claim group membership 995 * @bat_priv: the bat priv with all the soft interface information 996 * @primary_if: the primary interface of this batman interface 997 * @hw_src: the Hardware source in the ARP Header 998 * @hw_dst: the Hardware destination in the ARP Header 999 * @ethhdr: pointer to the Ethernet header of the claim frame 1000 * 1001 * checks if it is a claim packet and if it's on the same group. 1002 * This function also applies the group ID of the sender 1003 * if it is in the same mesh. 1004 * 1005 * Return: 1006 * 2 - if it is a claim packet and on the same group 1007 * 1 - if is a claim packet from another group 1008 * 0 - if it is not a claim packet 1009 */ 1010static int batadv_check_claim_group(struct batadv_priv *bat_priv, 1011 struct batadv_hard_iface *primary_if, 1012 u8 *hw_src, u8 *hw_dst, 1013 struct ethhdr *ethhdr) 1014{ 1015 u8 *backbone_addr; 1016 struct batadv_orig_node *orig_node; 1017 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; 1018 1019 bla_dst = (struct batadv_bla_claim_dst *)hw_dst; 1020 bla_dst_own = &bat_priv->bla.claim_dest; 1021 1022 /* if announcement packet, use the source, 1023 * otherwise assume it is in the hw_src 1024 */ 1025 switch (bla_dst->type) { 1026 case BATADV_CLAIM_TYPE_CLAIM: 1027 backbone_addr = hw_src; 1028 break; 1029 case BATADV_CLAIM_TYPE_REQUEST: 1030 case BATADV_CLAIM_TYPE_ANNOUNCE: 1031 case BATADV_CLAIM_TYPE_UNCLAIM: 1032 backbone_addr = ethhdr->h_source; 1033 break; 1034 default: 1035 return 0; 1036 } 1037 1038 /* don't accept claim frames from ourselves */ 1039 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) 1040 return 0; 1041 1042 /* if its already the same group, it is fine. */ 1043 if (bla_dst->group == bla_dst_own->group) 1044 return 2; 1045 1046 /* lets see if this originator is in our mesh */ 1047 orig_node = batadv_orig_hash_find(bat_priv, backbone_addr); 1048 1049 /* don't accept claims from gateways which are not in 1050 * the same mesh or group. 1051 */ 1052 if (!orig_node) 1053 return 1; 1054 1055 /* if our mesh friends mac is bigger, use it for ourselves. */ 1056 if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) { 1057 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1058 "taking other backbones claim group: %#.4x\n", 1059 ntohs(bla_dst->group)); 1060 bla_dst_own->group = bla_dst->group; 1061 } 1062 1063 batadv_orig_node_put(orig_node); 1064 1065 return 2; 1066} 1067 1068/** 1069 * batadv_bla_process_claim() - Check if this is a claim frame, and process it 1070 * @bat_priv: the bat priv with all the soft interface information 1071 * @primary_if: the primary hard interface of this batman soft interface 1072 * @skb: the frame to be checked 1073 * 1074 * Return: true if it was a claim frame, otherwise return false to 1075 * tell the callee that it can use the frame on its own. 1076 */ 1077static bool batadv_bla_process_claim(struct batadv_priv *bat_priv, 1078 struct batadv_hard_iface *primary_if, 1079 struct sk_buff *skb) 1080{ 1081 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; 1082 u8 *hw_src, *hw_dst; 1083 struct vlan_hdr *vhdr, vhdr_buf; 1084 struct ethhdr *ethhdr; 1085 struct arphdr *arphdr; 1086 unsigned short vid; 1087 int vlan_depth = 0; 1088 __be16 proto; 1089 int headlen; 1090 int ret; 1091 1092 vid = batadv_get_vid(skb, 0); 1093 ethhdr = eth_hdr(skb); 1094 1095 proto = ethhdr->h_proto; 1096 headlen = ETH_HLEN; 1097 if (vid & BATADV_VLAN_HAS_TAG) { 1098 /* Traverse the VLAN/Ethertypes. 1099 * 1100 * At this point it is known that the first protocol is a VLAN 1101 * header, so start checking at the encapsulated protocol. 1102 * 1103 * The depth of the VLAN headers is recorded to drop BLA claim 1104 * frames encapsulated into multiple VLAN headers (QinQ). 1105 */ 1106 do { 1107 vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN, 1108 &vhdr_buf); 1109 if (!vhdr) 1110 return false; 1111 1112 proto = vhdr->h_vlan_encapsulated_proto; 1113 headlen += VLAN_HLEN; 1114 vlan_depth++; 1115 } while (proto == htons(ETH_P_8021Q)); 1116 } 1117 1118 if (proto != htons(ETH_P_ARP)) 1119 return false; /* not a claim frame */ 1120 1121 /* this must be a ARP frame. check if it is a claim. */ 1122 1123 if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev)))) 1124 return false; 1125 1126 /* pskb_may_pull() may have modified the pointers, get ethhdr again */ 1127 ethhdr = eth_hdr(skb); 1128 arphdr = (struct arphdr *)((u8 *)ethhdr + headlen); 1129 1130 /* Check whether the ARP frame carries a valid 1131 * IP information 1132 */ 1133 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) 1134 return false; 1135 if (arphdr->ar_pro != htons(ETH_P_IP)) 1136 return false; 1137 if (arphdr->ar_hln != ETH_ALEN) 1138 return false; 1139 if (arphdr->ar_pln != 4) 1140 return false; 1141 1142 hw_src = (u8 *)arphdr + sizeof(struct arphdr); 1143 hw_dst = hw_src + ETH_ALEN + 4; 1144 bla_dst = (struct batadv_bla_claim_dst *)hw_dst; 1145 bla_dst_own = &bat_priv->bla.claim_dest; 1146 1147 /* check if it is a claim frame in general */ 1148 if (memcmp(bla_dst->magic, bla_dst_own->magic, 1149 sizeof(bla_dst->magic)) != 0) 1150 return false; 1151 1152 /* check if there is a claim frame encapsulated deeper in (QinQ) and 1153 * drop that, as this is not supported by BLA but should also not be 1154 * sent via the mesh. 1155 */ 1156 if (vlan_depth > 1) 1157 return true; 1158 1159 /* Let the loopdetect frames on the mesh in any case. */ 1160 if (bla_dst->type == BATADV_CLAIM_TYPE_LOOPDETECT) 1161 return false; 1162 1163 /* check if it is a claim frame. */ 1164 ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, 1165 ethhdr); 1166 if (ret == 1) 1167 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1168 "%s(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", 1169 __func__, ethhdr->h_source, batadv_print_vid(vid), 1170 hw_src, hw_dst); 1171 1172 if (ret < 2) 1173 return !!ret; 1174 1175 /* become a backbone gw ourselves on this vlan if not happened yet */ 1176 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); 1177 1178 /* check for the different types of claim frames ... */ 1179 switch (bla_dst->type) { 1180 case BATADV_CLAIM_TYPE_CLAIM: 1181 if (batadv_handle_claim(bat_priv, primary_if, hw_src, 1182 ethhdr->h_source, vid)) 1183 return true; 1184 break; 1185 case BATADV_CLAIM_TYPE_UNCLAIM: 1186 if (batadv_handle_unclaim(bat_priv, primary_if, 1187 ethhdr->h_source, hw_src, vid)) 1188 return true; 1189 break; 1190 1191 case BATADV_CLAIM_TYPE_ANNOUNCE: 1192 if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source, 1193 vid)) 1194 return true; 1195 break; 1196 case BATADV_CLAIM_TYPE_REQUEST: 1197 if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr, 1198 vid)) 1199 return true; 1200 break; 1201 } 1202 1203 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1204 "%s(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", 1205 __func__, ethhdr->h_source, batadv_print_vid(vid), hw_src, 1206 hw_dst); 1207 return true; 1208} 1209 1210/** 1211 * batadv_bla_purge_backbone_gw() - Remove backbone gateways after a timeout or 1212 * immediately 1213 * @bat_priv: the bat priv with all the soft interface information 1214 * @now: whether the whole hash shall be wiped now 1215 * 1216 * Check when we last heard from other nodes, and remove them in case of 1217 * a time out, or clean all backbone gws if now is set. 1218 */ 1219static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) 1220{ 1221 struct batadv_bla_backbone_gw *backbone_gw; 1222 struct hlist_node *node_tmp; 1223 struct hlist_head *head; 1224 struct batadv_hashtable *hash; 1225 spinlock_t *list_lock; /* protects write access to the hash lists */ 1226 int i; 1227 1228 hash = bat_priv->bla.backbone_hash; 1229 if (!hash) 1230 return; 1231 1232 for (i = 0; i < hash->size; i++) { 1233 head = &hash->table[i]; 1234 list_lock = &hash->list_locks[i]; 1235 1236 spin_lock_bh(list_lock); 1237 hlist_for_each_entry_safe(backbone_gw, node_tmp, 1238 head, hash_entry) { 1239 if (now) 1240 goto purge_now; 1241 if (!batadv_has_timed_out(backbone_gw->lasttime, 1242 BATADV_BLA_BACKBONE_TIMEOUT)) 1243 continue; 1244 1245 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, 1246 "%s(): backbone gw %pM timed out\n", 1247 __func__, backbone_gw->orig); 1248 1249purge_now: 1250 /* don't wait for the pending request anymore */ 1251 if (atomic_read(&backbone_gw->request_sent)) 1252 atomic_dec(&bat_priv->bla.num_requests); 1253 1254 batadv_bla_del_backbone_claims(backbone_gw); 1255 1256 hlist_del_rcu(&backbone_gw->hash_entry); 1257 batadv_backbone_gw_put(backbone_gw); 1258 } 1259 spin_unlock_bh(list_lock); 1260 } 1261} 1262 1263/** 1264 * batadv_bla_purge_claims() - Remove claims after a timeout or immediately 1265 * @bat_priv: the bat priv with all the soft interface information 1266 * @primary_if: the selected primary interface, may be NULL if now is set 1267 * @now: whether the whole hash shall be wiped now 1268 * 1269 * Check when we heard last time from our own claims, and remove them in case of 1270 * a time out, or clean all claims if now is set 1271 */ 1272static void batadv_bla_purge_claims(struct batadv_priv *bat_priv, 1273 struct batadv_hard_iface *primary_if, 1274 int now) 1275{ 1276 struct batadv_bla_backbone_gw *backbone_gw; 1277 struct batadv_bla_claim *claim; 1278 struct hlist_head *head; 1279 struct batadv_hashtable *hash; 1280 int i; 1281 1282 hash = bat_priv->bla.claim_hash; 1283 if (!hash) 1284 return; 1285 1286 for (i = 0; i < hash->size; i++) { 1287 head = &hash->table[i]; 1288 1289 rcu_read_lock(); 1290 hlist_for_each_entry_rcu(claim, head, hash_entry) { 1291 backbone_gw = batadv_bla_claim_get_backbone_gw(claim); 1292 if (now) 1293 goto purge_now; 1294 1295 if (!batadv_compare_eth(backbone_gw->orig, 1296 primary_if->net_dev->dev_addr)) 1297 goto skip; 1298 1299 if (!batadv_has_timed_out(claim->lasttime, 1300 BATADV_BLA_CLAIM_TIMEOUT)) 1301 goto skip; 1302 1303 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1304 "%s(): timed out.\n", __func__); 1305 1306purge_now: 1307 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1308 "%s(): %pM, vid %d\n", __func__, 1309 claim->addr, claim->vid); 1310 1311 batadv_handle_unclaim(bat_priv, primary_if, 1312 backbone_gw->orig, 1313 claim->addr, claim->vid); 1314skip: 1315 batadv_backbone_gw_put(backbone_gw); 1316 } 1317 rcu_read_unlock(); 1318 } 1319} 1320 1321/** 1322 * batadv_bla_update_orig_address() - Update the backbone gateways when the own 1323 * originator address changes 1324 * @bat_priv: the bat priv with all the soft interface information 1325 * @primary_if: the new selected primary_if 1326 * @oldif: the old primary interface, may be NULL 1327 */ 1328void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, 1329 struct batadv_hard_iface *primary_if, 1330 struct batadv_hard_iface *oldif) 1331{ 1332 struct batadv_bla_backbone_gw *backbone_gw; 1333 struct hlist_head *head; 1334 struct batadv_hashtable *hash; 1335 __be16 group; 1336 int i; 1337 1338 /* reset bridge loop avoidance group id */ 1339 group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); 1340 bat_priv->bla.claim_dest.group = group; 1341 1342 /* purge everything when bridge loop avoidance is turned off */ 1343 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1344 oldif = NULL; 1345 1346 if (!oldif) { 1347 batadv_bla_purge_claims(bat_priv, NULL, 1); 1348 batadv_bla_purge_backbone_gw(bat_priv, 1); 1349 return; 1350 } 1351 1352 hash = bat_priv->bla.backbone_hash; 1353 if (!hash) 1354 return; 1355 1356 for (i = 0; i < hash->size; i++) { 1357 head = &hash->table[i]; 1358 1359 rcu_read_lock(); 1360 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 1361 /* own orig still holds the old value. */ 1362 if (!batadv_compare_eth(backbone_gw->orig, 1363 oldif->net_dev->dev_addr)) 1364 continue; 1365 1366 ether_addr_copy(backbone_gw->orig, 1367 primary_if->net_dev->dev_addr); 1368 /* send an announce frame so others will ask for our 1369 * claims and update their tables. 1370 */ 1371 batadv_bla_send_announce(bat_priv, backbone_gw); 1372 } 1373 rcu_read_unlock(); 1374 } 1375} 1376 1377/** 1378 * batadv_bla_send_loopdetect() - send a loopdetect frame 1379 * @bat_priv: the bat priv with all the soft interface information 1380 * @backbone_gw: the backbone gateway for which a loop should be detected 1381 * 1382 * To detect loops that the bridge loop avoidance can't handle, send a loop 1383 * detection packet on the backbone. Unlike other BLA frames, this frame will 1384 * be allowed on the mesh by other nodes. If it is received on the mesh, this 1385 * indicates that there is a loop. 1386 */ 1387static void 1388batadv_bla_send_loopdetect(struct batadv_priv *bat_priv, 1389 struct batadv_bla_backbone_gw *backbone_gw) 1390{ 1391 batadv_dbg(BATADV_DBG_BLA, bat_priv, "Send loopdetect frame for vid %d\n", 1392 backbone_gw->vid); 1393 batadv_bla_send_claim(bat_priv, bat_priv->bla.loopdetect_addr, 1394 backbone_gw->vid, BATADV_CLAIM_TYPE_LOOPDETECT); 1395} 1396 1397/** 1398 * batadv_bla_status_update() - purge bla interfaces if necessary 1399 * @net_dev: the soft interface net device 1400 */ 1401void batadv_bla_status_update(struct net_device *net_dev) 1402{ 1403 struct batadv_priv *bat_priv = netdev_priv(net_dev); 1404 struct batadv_hard_iface *primary_if; 1405 1406 primary_if = batadv_primary_if_get_selected(bat_priv); 1407 if (!primary_if) 1408 return; 1409 1410 /* this function already purges everything when bla is disabled, 1411 * so just call that one. 1412 */ 1413 batadv_bla_update_orig_address(bat_priv, primary_if, primary_if); 1414 batadv_hardif_put(primary_if); 1415} 1416 1417/** 1418 * batadv_bla_periodic_work() - performs periodic bla work 1419 * @work: kernel work struct 1420 * 1421 * periodic work to do: 1422 * * purge structures when they are too old 1423 * * send announcements 1424 */ 1425static void batadv_bla_periodic_work(struct work_struct *work) 1426{ 1427 struct delayed_work *delayed_work; 1428 struct batadv_priv *bat_priv; 1429 struct batadv_priv_bla *priv_bla; 1430 struct hlist_head *head; 1431 struct batadv_bla_backbone_gw *backbone_gw; 1432 struct batadv_hashtable *hash; 1433 struct batadv_hard_iface *primary_if; 1434 bool send_loopdetect = false; 1435 int i; 1436 1437 delayed_work = to_delayed_work(work); 1438 priv_bla = container_of(delayed_work, struct batadv_priv_bla, work); 1439 bat_priv = container_of(priv_bla, struct batadv_priv, bla); 1440 primary_if = batadv_primary_if_get_selected(bat_priv); 1441 if (!primary_if) 1442 goto out; 1443 1444 batadv_bla_purge_claims(bat_priv, primary_if, 0); 1445 batadv_bla_purge_backbone_gw(bat_priv, 0); 1446 1447 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1448 goto out; 1449 1450 if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) { 1451 /* set a new random mac address for the next bridge loop 1452 * detection frames. Set the locally administered bit to avoid 1453 * collisions with users mac addresses. 1454 */ 1455 eth_random_addr(bat_priv->bla.loopdetect_addr); 1456 bat_priv->bla.loopdetect_addr[0] = 0xba; 1457 bat_priv->bla.loopdetect_addr[1] = 0xbe; 1458 bat_priv->bla.loopdetect_lasttime = jiffies; 1459 atomic_set(&bat_priv->bla.loopdetect_next, 1460 BATADV_BLA_LOOPDETECT_PERIODS); 1461 1462 /* mark for sending loop detect on all VLANs */ 1463 send_loopdetect = true; 1464 } 1465 1466 hash = bat_priv->bla.backbone_hash; 1467 if (!hash) 1468 goto out; 1469 1470 for (i = 0; i < hash->size; i++) { 1471 head = &hash->table[i]; 1472 1473 rcu_read_lock(); 1474 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 1475 if (!batadv_compare_eth(backbone_gw->orig, 1476 primary_if->net_dev->dev_addr)) 1477 continue; 1478 1479 backbone_gw->lasttime = jiffies; 1480 1481 batadv_bla_send_announce(bat_priv, backbone_gw); 1482 if (send_loopdetect) 1483 batadv_bla_send_loopdetect(bat_priv, 1484 backbone_gw); 1485 1486 /* request_sent is only set after creation to avoid 1487 * problems when we are not yet known as backbone gw 1488 * in the backbone. 1489 * 1490 * We can reset this now after we waited some periods 1491 * to give bridge forward delays and bla group forming 1492 * some grace time. 1493 */ 1494 1495 if (atomic_read(&backbone_gw->request_sent) == 0) 1496 continue; 1497 1498 if (!atomic_dec_and_test(&backbone_gw->wait_periods)) 1499 continue; 1500 1501 atomic_dec(&backbone_gw->bat_priv->bla.num_requests); 1502 atomic_set(&backbone_gw->request_sent, 0); 1503 } 1504 rcu_read_unlock(); 1505 } 1506out: 1507 batadv_hardif_put(primary_if); 1508 1509 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work, 1510 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); 1511} 1512 1513/* The hash for claim and backbone hash receive the same key because they 1514 * are getting initialized by hash_new with the same key. Reinitializing 1515 * them with to different keys to allow nested locking without generating 1516 * lockdep warnings 1517 */ 1518static struct lock_class_key batadv_claim_hash_lock_class_key; 1519static struct lock_class_key batadv_backbone_hash_lock_class_key; 1520 1521/** 1522 * batadv_bla_init() - initialize all bla structures 1523 * @bat_priv: the bat priv with all the soft interface information 1524 * 1525 * Return: 0 on success, < 0 on error. 1526 */ 1527int batadv_bla_init(struct batadv_priv *bat_priv) 1528{ 1529 int i; 1530 u8 claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; 1531 struct batadv_hard_iface *primary_if; 1532 u16 crc; 1533 unsigned long entrytime; 1534 1535 spin_lock_init(&bat_priv->bla.bcast_duplist_lock); 1536 1537 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); 1538 1539 /* setting claim destination address */ 1540 memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3); 1541 bat_priv->bla.claim_dest.type = 0; 1542 primary_if = batadv_primary_if_get_selected(bat_priv); 1543 if (primary_if) { 1544 crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN); 1545 bat_priv->bla.claim_dest.group = htons(crc); 1546 batadv_hardif_put(primary_if); 1547 } else { 1548 bat_priv->bla.claim_dest.group = 0; /* will be set later */ 1549 } 1550 1551 /* initialize the duplicate list */ 1552 entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); 1553 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) 1554 bat_priv->bla.bcast_duplist[i].entrytime = entrytime; 1555 bat_priv->bla.bcast_duplist_curr = 0; 1556 1557 atomic_set(&bat_priv->bla.loopdetect_next, 1558 BATADV_BLA_LOOPDETECT_PERIODS); 1559 1560 if (bat_priv->bla.claim_hash) 1561 return 0; 1562 1563 bat_priv->bla.claim_hash = batadv_hash_new(128); 1564 if (!bat_priv->bla.claim_hash) 1565 return -ENOMEM; 1566 1567 bat_priv->bla.backbone_hash = batadv_hash_new(32); 1568 if (!bat_priv->bla.backbone_hash) { 1569 batadv_hash_destroy(bat_priv->bla.claim_hash); 1570 return -ENOMEM; 1571 } 1572 1573 batadv_hash_set_lock_class(bat_priv->bla.claim_hash, 1574 &batadv_claim_hash_lock_class_key); 1575 batadv_hash_set_lock_class(bat_priv->bla.backbone_hash, 1576 &batadv_backbone_hash_lock_class_key); 1577 1578 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n"); 1579 1580 INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work); 1581 1582 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work, 1583 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); 1584 return 0; 1585} 1586 1587/** 1588 * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup. 1589 * @bat_priv: the bat priv with all the soft interface information 1590 * @skb: contains the multicast packet to be checked 1591 * @payload_ptr: pointer to position inside the head buffer of the skb 1592 * marking the start of the data to be CRC'ed 1593 * @orig: originator mac address, NULL if unknown 1594 * 1595 * Check if it is on our broadcast list. Another gateway might have sent the 1596 * same packet because it is connected to the same backbone, so we have to 1597 * remove this duplicate. 1598 * 1599 * This is performed by checking the CRC, which will tell us 1600 * with a good chance that it is the same packet. If it is furthermore 1601 * sent by another host, drop it. We allow equal packets from 1602 * the same host however as this might be intended. 1603 * 1604 * Return: true if a packet is in the duplicate list, false otherwise. 1605 */ 1606static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv, 1607 struct sk_buff *skb, u8 *payload_ptr, 1608 const u8 *orig) 1609{ 1610 struct batadv_bcast_duplist_entry *entry; 1611 bool ret = false; 1612 int i, curr; 1613 __be32 crc; 1614 1615 /* calculate the crc ... */ 1616 crc = batadv_skb_crc32(skb, payload_ptr); 1617 1618 spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); 1619 1620 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { 1621 curr = (bat_priv->bla.bcast_duplist_curr + i); 1622 curr %= BATADV_DUPLIST_SIZE; 1623 entry = &bat_priv->bla.bcast_duplist[curr]; 1624 1625 /* we can stop searching if the entry is too old ; 1626 * later entries will be even older 1627 */ 1628 if (batadv_has_timed_out(entry->entrytime, 1629 BATADV_DUPLIST_TIMEOUT)) 1630 break; 1631 1632 if (entry->crc != crc) 1633 continue; 1634 1635 /* are the originators both known and not anonymous? */ 1636 if (orig && !is_zero_ether_addr(orig) && 1637 !is_zero_ether_addr(entry->orig)) { 1638 /* If known, check if the new frame came from 1639 * the same originator: 1640 * We are safe to take identical frames from the 1641 * same orig, if known, as multiplications in 1642 * the mesh are detected via the (orig, seqno) pair. 1643 * So we can be a bit more liberal here and allow 1644 * identical frames from the same orig which the source 1645 * host might have sent multiple times on purpose. 1646 */ 1647 if (batadv_compare_eth(entry->orig, orig)) 1648 continue; 1649 } 1650 1651 /* this entry seems to match: same crc, not too old, 1652 * and from another gw. therefore return true to forbid it. 1653 */ 1654 ret = true; 1655 goto out; 1656 } 1657 /* not found, add a new entry (overwrite the oldest entry) 1658 * and allow it, its the first occurrence. 1659 */ 1660 curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); 1661 curr %= BATADV_DUPLIST_SIZE; 1662 entry = &bat_priv->bla.bcast_duplist[curr]; 1663 entry->crc = crc; 1664 entry->entrytime = jiffies; 1665 1666 /* known originator */ 1667 if (orig) 1668 ether_addr_copy(entry->orig, orig); 1669 /* anonymous originator */ 1670 else 1671 eth_zero_addr(entry->orig); 1672 1673 bat_priv->bla.bcast_duplist_curr = curr; 1674 1675out: 1676 spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock); 1677 1678 return ret; 1679} 1680 1681/** 1682 * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup. 1683 * @bat_priv: the bat priv with all the soft interface information 1684 * @skb: contains the multicast packet to be checked, decapsulated from a 1685 * unicast_packet 1686 * 1687 * Check if it is on our broadcast list. Another gateway might have sent the 1688 * same packet because it is connected to the same backbone, so we have to 1689 * remove this duplicate. 1690 * 1691 * Return: true if a packet is in the duplicate list, false otherwise. 1692 */ 1693static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv, 1694 struct sk_buff *skb) 1695{ 1696 return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL); 1697} 1698 1699/** 1700 * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup. 1701 * @bat_priv: the bat priv with all the soft interface information 1702 * @skb: contains the bcast_packet to be checked 1703 * 1704 * Check if it is on our broadcast list. Another gateway might have sent the 1705 * same packet because it is connected to the same backbone, so we have to 1706 * remove this duplicate. 1707 * 1708 * Return: true if a packet is in the duplicate list, false otherwise. 1709 */ 1710bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, 1711 struct sk_buff *skb) 1712{ 1713 struct batadv_bcast_packet *bcast_packet; 1714 u8 *payload_ptr; 1715 1716 bcast_packet = (struct batadv_bcast_packet *)skb->data; 1717 payload_ptr = (u8 *)(bcast_packet + 1); 1718 1719 return batadv_bla_check_duplist(bat_priv, skb, payload_ptr, 1720 bcast_packet->orig); 1721} 1722 1723/** 1724 * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for 1725 * the VLAN identified by vid. 1726 * @bat_priv: the bat priv with all the soft interface information 1727 * @orig: originator mac address 1728 * @vid: VLAN identifier 1729 * 1730 * Return: true if orig is a backbone for this vid, false otherwise. 1731 */ 1732bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig, 1733 unsigned short vid) 1734{ 1735 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; 1736 struct hlist_head *head; 1737 struct batadv_bla_backbone_gw *backbone_gw; 1738 int i; 1739 1740 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1741 return false; 1742 1743 if (!hash) 1744 return false; 1745 1746 for (i = 0; i < hash->size; i++) { 1747 head = &hash->table[i]; 1748 1749 rcu_read_lock(); 1750 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 1751 if (batadv_compare_eth(backbone_gw->orig, orig) && 1752 backbone_gw->vid == vid) { 1753 rcu_read_unlock(); 1754 return true; 1755 } 1756 } 1757 rcu_read_unlock(); 1758 } 1759 1760 return false; 1761} 1762 1763/** 1764 * batadv_bla_is_backbone_gw() - check if originator is a backbone gw for a VLAN 1765 * @skb: the frame to be checked 1766 * @orig_node: the orig_node of the frame 1767 * @hdr_size: maximum length of the frame 1768 * 1769 * Return: true if the orig_node is also a gateway on the soft interface, 1770 * otherwise it returns false. 1771 */ 1772bool batadv_bla_is_backbone_gw(struct sk_buff *skb, 1773 struct batadv_orig_node *orig_node, int hdr_size) 1774{ 1775 struct batadv_bla_backbone_gw *backbone_gw; 1776 unsigned short vid; 1777 1778 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) 1779 return false; 1780 1781 /* first, find out the vid. */ 1782 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) 1783 return false; 1784 1785 vid = batadv_get_vid(skb, hdr_size); 1786 1787 /* see if this originator is a backbone gw for this VLAN */ 1788 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, 1789 orig_node->orig, vid); 1790 if (!backbone_gw) 1791 return false; 1792 1793 batadv_backbone_gw_put(backbone_gw); 1794 return true; 1795} 1796 1797/** 1798 * batadv_bla_free() - free all bla structures 1799 * @bat_priv: the bat priv with all the soft interface information 1800 * 1801 * for softinterface free or module unload 1802 */ 1803void batadv_bla_free(struct batadv_priv *bat_priv) 1804{ 1805 struct batadv_hard_iface *primary_if; 1806 1807 cancel_delayed_work_sync(&bat_priv->bla.work); 1808 primary_if = batadv_primary_if_get_selected(bat_priv); 1809 1810 if (bat_priv->bla.claim_hash) { 1811 batadv_bla_purge_claims(bat_priv, primary_if, 1); 1812 batadv_hash_destroy(bat_priv->bla.claim_hash); 1813 bat_priv->bla.claim_hash = NULL; 1814 } 1815 if (bat_priv->bla.backbone_hash) { 1816 batadv_bla_purge_backbone_gw(bat_priv, 1); 1817 batadv_hash_destroy(bat_priv->bla.backbone_hash); 1818 bat_priv->bla.backbone_hash = NULL; 1819 } 1820 batadv_hardif_put(primary_if); 1821} 1822 1823/** 1824 * batadv_bla_loopdetect_check() - check and handle a detected loop 1825 * @bat_priv: the bat priv with all the soft interface information 1826 * @skb: the packet to check 1827 * @primary_if: interface where the request came on 1828 * @vid: the VLAN ID of the frame 1829 * 1830 * Checks if this packet is a loop detect frame which has been sent by us, 1831 * throws an uevent and logs the event if that is the case. 1832 * 1833 * Return: true if it is a loop detect frame which is to be dropped, false 1834 * otherwise. 1835 */ 1836static bool 1837batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb, 1838 struct batadv_hard_iface *primary_if, 1839 unsigned short vid) 1840{ 1841 struct batadv_bla_backbone_gw *backbone_gw; 1842 struct ethhdr *ethhdr; 1843 bool ret; 1844 1845 ethhdr = eth_hdr(skb); 1846 1847 /* Only check for the MAC address and skip more checks here for 1848 * performance reasons - this function is on the hotpath, after all. 1849 */ 1850 if (!batadv_compare_eth(ethhdr->h_source, 1851 bat_priv->bla.loopdetect_addr)) 1852 return false; 1853 1854 /* If the packet came too late, don't forward it on the mesh 1855 * but don't consider that as loop. It might be a coincidence. 1856 */ 1857 if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime, 1858 BATADV_BLA_LOOPDETECT_TIMEOUT)) 1859 return true; 1860 1861 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, 1862 primary_if->net_dev->dev_addr, 1863 vid, true); 1864 if (unlikely(!backbone_gw)) 1865 return true; 1866 1867 ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work); 1868 1869 /* backbone_gw is unreferenced in the report work function 1870 * if queue_work() call was successful 1871 */ 1872 if (!ret) 1873 batadv_backbone_gw_put(backbone_gw); 1874 1875 return true; 1876} 1877 1878/** 1879 * batadv_bla_rx() - check packets coming from the mesh. 1880 * @bat_priv: the bat priv with all the soft interface information 1881 * @skb: the frame to be checked 1882 * @vid: the VLAN ID of the frame 1883 * @packet_type: the batman packet type this frame came in 1884 * 1885 * batadv_bla_rx avoidance checks if: 1886 * * we have to race for a claim 1887 * * if the frame is allowed on the LAN 1888 * 1889 * In these cases, the skb is further handled by this function 1890 * 1891 * Return: true if handled, otherwise it returns false and the caller shall 1892 * further process the skb. 1893 */ 1894bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, 1895 unsigned short vid, int packet_type) 1896{ 1897 struct batadv_bla_backbone_gw *backbone_gw; 1898 struct ethhdr *ethhdr; 1899 struct batadv_bla_claim search_claim, *claim = NULL; 1900 struct batadv_hard_iface *primary_if; 1901 bool own_claim; 1902 bool ret; 1903 1904 ethhdr = eth_hdr(skb); 1905 1906 primary_if = batadv_primary_if_get_selected(bat_priv); 1907 if (!primary_if) 1908 goto handled; 1909 1910 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1911 goto allow; 1912 1913 if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid)) 1914 goto handled; 1915 1916 if (unlikely(atomic_read(&bat_priv->bla.num_requests))) 1917 /* don't allow multicast packets while requests are in flight */ 1918 if (is_multicast_ether_addr(ethhdr->h_dest)) 1919 /* Both broadcast flooding or multicast-via-unicasts 1920 * delivery might send to multiple backbone gateways 1921 * sharing the same LAN and therefore need to coordinate 1922 * which backbone gateway forwards into the LAN, 1923 * by claiming the payload source address. 1924 * 1925 * Broadcast flooding and multicast-via-unicasts 1926 * delivery use the following two batman packet types. 1927 * Note: explicitly exclude BATADV_UNICAST_4ADDR, 1928 * as the DHCP gateway feature will send explicitly 1929 * to only one BLA gateway, so the claiming process 1930 * should be avoided there. 1931 */ 1932 if (packet_type == BATADV_BCAST || 1933 packet_type == BATADV_UNICAST) 1934 goto handled; 1935 1936 /* potential duplicates from foreign BLA backbone gateways via 1937 * multicast-in-unicast packets 1938 */ 1939 if (is_multicast_ether_addr(ethhdr->h_dest) && 1940 packet_type == BATADV_UNICAST && 1941 batadv_bla_check_ucast_duplist(bat_priv, skb)) 1942 goto handled; 1943 1944 ether_addr_copy(search_claim.addr, ethhdr->h_source); 1945 search_claim.vid = vid; 1946 claim = batadv_claim_hash_find(bat_priv, &search_claim); 1947 1948 if (!claim) { 1949 /* possible optimization: race for a claim */ 1950 /* No claim exists yet, claim it for us! 1951 */ 1952 1953 batadv_dbg(BATADV_DBG_BLA, bat_priv, 1954 "%s(): Unclaimed MAC %pM found. Claim it. Local: %s\n", 1955 __func__, ethhdr->h_source, 1956 batadv_is_my_client(bat_priv, 1957 ethhdr->h_source, vid) ? 1958 "yes" : "no"); 1959 batadv_handle_claim(bat_priv, primary_if, 1960 primary_if->net_dev->dev_addr, 1961 ethhdr->h_source, vid); 1962 goto allow; 1963 } 1964 1965 /* if it is our own claim ... */ 1966 backbone_gw = batadv_bla_claim_get_backbone_gw(claim); 1967 own_claim = batadv_compare_eth(backbone_gw->orig, 1968 primary_if->net_dev->dev_addr); 1969 batadv_backbone_gw_put(backbone_gw); 1970 1971 if (own_claim) { 1972 /* ... allow it in any case */ 1973 claim->lasttime = jiffies; 1974 goto allow; 1975 } 1976 1977 /* if it is a multicast ... */ 1978 if (is_multicast_ether_addr(ethhdr->h_dest) && 1979 (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) { 1980 /* ... drop it. the responsible gateway is in charge. 1981 * 1982 * We need to check packet type because with the gateway 1983 * feature, broadcasts (like DHCP requests) may be sent 1984 * using a unicast 4 address packet type. See comment above. 1985 */ 1986 goto handled; 1987 } else { 1988 /* seems the client considers us as its best gateway. 1989 * send a claim and update the claim table 1990 * immediately. 1991 */ 1992 batadv_handle_claim(bat_priv, primary_if, 1993 primary_if->net_dev->dev_addr, 1994 ethhdr->h_source, vid); 1995 goto allow; 1996 } 1997allow: 1998 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); 1999 ret = false; 2000 goto out; 2001 2002handled: 2003 kfree_skb(skb); 2004 ret = true; 2005 2006out: 2007 batadv_hardif_put(primary_if); 2008 batadv_claim_put(claim); 2009 return ret; 2010} 2011 2012/** 2013 * batadv_bla_tx() - check packets going into the mesh 2014 * @bat_priv: the bat priv with all the soft interface information 2015 * @skb: the frame to be checked 2016 * @vid: the VLAN ID of the frame 2017 * 2018 * batadv_bla_tx checks if: 2019 * * a claim was received which has to be processed 2020 * * the frame is allowed on the mesh 2021 * 2022 * in these cases, the skb is further handled by this function. 2023 * 2024 * This call might reallocate skb data. 2025 * 2026 * Return: true if handled, otherwise it returns false and the caller shall 2027 * further process the skb. 2028 */ 2029bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, 2030 unsigned short vid) 2031{ 2032 struct ethhdr *ethhdr; 2033 struct batadv_bla_claim search_claim, *claim = NULL; 2034 struct batadv_bla_backbone_gw *backbone_gw; 2035 struct batadv_hard_iface *primary_if; 2036 bool client_roamed; 2037 bool ret = false; 2038 2039 primary_if = batadv_primary_if_get_selected(bat_priv); 2040 if (!primary_if) 2041 goto out; 2042 2043 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 2044 goto allow; 2045 2046 if (batadv_bla_process_claim(bat_priv, primary_if, skb)) 2047 goto handled; 2048 2049 ethhdr = eth_hdr(skb); 2050 2051 if (unlikely(atomic_read(&bat_priv->bla.num_requests))) 2052 /* don't allow broadcasts while requests are in flight */ 2053 if (is_multicast_ether_addr(ethhdr->h_dest)) 2054 goto handled; 2055 2056 ether_addr_copy(search_claim.addr, ethhdr->h_source); 2057 search_claim.vid = vid; 2058 2059 claim = batadv_claim_hash_find(bat_priv, &search_claim); 2060 2061 /* if no claim exists, allow it. */ 2062 if (!claim) 2063 goto allow; 2064 2065 /* check if we are responsible. */ 2066 backbone_gw = batadv_bla_claim_get_backbone_gw(claim); 2067 client_roamed = batadv_compare_eth(backbone_gw->orig, 2068 primary_if->net_dev->dev_addr); 2069 batadv_backbone_gw_put(backbone_gw); 2070 2071 if (client_roamed) { 2072 /* if yes, the client has roamed and we have 2073 * to unclaim it. 2074 */ 2075 if (batadv_has_timed_out(claim->lasttime, 100)) { 2076 /* only unclaim if the last claim entry is 2077 * older than 100 ms to make sure we really 2078 * have a roaming client here. 2079 */ 2080 batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Roaming client %pM detected. Unclaim it.\n", 2081 __func__, ethhdr->h_source); 2082 batadv_handle_unclaim(bat_priv, primary_if, 2083 primary_if->net_dev->dev_addr, 2084 ethhdr->h_source, vid); 2085 goto allow; 2086 } else { 2087 batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Race for claim %pM detected. Drop packet.\n", 2088 __func__, ethhdr->h_source); 2089 goto handled; 2090 } 2091 } 2092 2093 /* check if it is a multicast/broadcast frame */ 2094 if (is_multicast_ether_addr(ethhdr->h_dest)) { 2095 /* drop it. the responsible gateway has forwarded it into 2096 * the backbone network. 2097 */ 2098 goto handled; 2099 } else { 2100 /* we must allow it. at least if we are 2101 * responsible for the DESTINATION. 2102 */ 2103 goto allow; 2104 } 2105allow: 2106 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); 2107 ret = false; 2108 goto out; 2109handled: 2110 ret = true; 2111out: 2112 batadv_hardif_put(primary_if); 2113 batadv_claim_put(claim); 2114 return ret; 2115} 2116 2117/** 2118 * batadv_bla_claim_dump_entry() - dump one entry of the claim table 2119 * to a netlink socket 2120 * @msg: buffer for the message 2121 * @portid: netlink port 2122 * @cb: Control block containing additional options 2123 * @primary_if: primary interface 2124 * @claim: entry to dump 2125 * 2126 * Return: 0 or error code. 2127 */ 2128static int 2129batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid, 2130 struct netlink_callback *cb, 2131 struct batadv_hard_iface *primary_if, 2132 struct batadv_bla_claim *claim) 2133{ 2134 const u8 *primary_addr = primary_if->net_dev->dev_addr; 2135 u16 backbone_crc; 2136 bool is_own; 2137 void *hdr; 2138 int ret = -EINVAL; 2139 2140 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, 2141 &batadv_netlink_family, NLM_F_MULTI, 2142 BATADV_CMD_GET_BLA_CLAIM); 2143 if (!hdr) { 2144 ret = -ENOBUFS; 2145 goto out; 2146 } 2147 2148 genl_dump_check_consistent(cb, hdr); 2149 2150 is_own = batadv_compare_eth(claim->backbone_gw->orig, 2151 primary_addr); 2152 2153 spin_lock_bh(&claim->backbone_gw->crc_lock); 2154 backbone_crc = claim->backbone_gw->crc; 2155 spin_unlock_bh(&claim->backbone_gw->crc_lock); 2156 2157 if (is_own) 2158 if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) { 2159 genlmsg_cancel(msg, hdr); 2160 goto out; 2161 } 2162 2163 if (nla_put(msg, BATADV_ATTR_BLA_ADDRESS, ETH_ALEN, claim->addr) || 2164 nla_put_u16(msg, BATADV_ATTR_BLA_VID, claim->vid) || 2165 nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN, 2166 claim->backbone_gw->orig) || 2167 nla_put_u16(msg, BATADV_ATTR_BLA_CRC, 2168 backbone_crc)) { 2169 genlmsg_cancel(msg, hdr); 2170 goto out; 2171 } 2172 2173 genlmsg_end(msg, hdr); 2174 ret = 0; 2175 2176out: 2177 return ret; 2178} 2179 2180/** 2181 * batadv_bla_claim_dump_bucket() - dump one bucket of the claim table 2182 * to a netlink socket 2183 * @msg: buffer for the message 2184 * @portid: netlink port 2185 * @cb: Control block containing additional options 2186 * @primary_if: primary interface 2187 * @hash: hash to dump 2188 * @bucket: bucket index to dump 2189 * @idx_skip: How many entries to skip 2190 * 2191 * Return: always 0. 2192 */ 2193static int 2194batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid, 2195 struct netlink_callback *cb, 2196 struct batadv_hard_iface *primary_if, 2197 struct batadv_hashtable *hash, unsigned int bucket, 2198 int *idx_skip) 2199{ 2200 struct batadv_bla_claim *claim; 2201 int idx = 0; 2202 int ret = 0; 2203 2204 spin_lock_bh(&hash->list_locks[bucket]); 2205 cb->seq = atomic_read(&hash->generation) << 1 | 1; 2206 2207 hlist_for_each_entry(claim, &hash->table[bucket], hash_entry) { 2208 if (idx++ < *idx_skip) 2209 continue; 2210 2211 ret = batadv_bla_claim_dump_entry(msg, portid, cb, 2212 primary_if, claim); 2213 if (ret) { 2214 *idx_skip = idx - 1; 2215 goto unlock; 2216 } 2217 } 2218 2219 *idx_skip = 0; 2220unlock: 2221 spin_unlock_bh(&hash->list_locks[bucket]); 2222 return ret; 2223} 2224 2225/** 2226 * batadv_bla_claim_dump() - dump claim table to a netlink socket 2227 * @msg: buffer for the message 2228 * @cb: callback structure containing arguments 2229 * 2230 * Return: message length. 2231 */ 2232int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb) 2233{ 2234 struct batadv_hard_iface *primary_if = NULL; 2235 int portid = NETLINK_CB(cb->skb).portid; 2236 struct net *net = sock_net(cb->skb->sk); 2237 struct net_device *soft_iface; 2238 struct batadv_hashtable *hash; 2239 struct batadv_priv *bat_priv; 2240 int bucket = cb->args[0]; 2241 int idx = cb->args[1]; 2242 int ifindex; 2243 int ret = 0; 2244 2245 ifindex = batadv_netlink_get_ifindex(cb->nlh, 2246 BATADV_ATTR_MESH_IFINDEX); 2247 if (!ifindex) 2248 return -EINVAL; 2249 2250 soft_iface = dev_get_by_index(net, ifindex); 2251 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 2252 ret = -ENODEV; 2253 goto out; 2254 } 2255 2256 bat_priv = netdev_priv(soft_iface); 2257 hash = bat_priv->bla.claim_hash; 2258 2259 primary_if = batadv_primary_if_get_selected(bat_priv); 2260 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { 2261 ret = -ENOENT; 2262 goto out; 2263 } 2264 2265 while (bucket < hash->size) { 2266 if (batadv_bla_claim_dump_bucket(msg, portid, cb, primary_if, 2267 hash, bucket, &idx)) 2268 break; 2269 bucket++; 2270 } 2271 2272 cb->args[0] = bucket; 2273 cb->args[1] = idx; 2274 2275 ret = msg->len; 2276 2277out: 2278 batadv_hardif_put(primary_if); 2279 2280 dev_put(soft_iface); 2281 2282 return ret; 2283} 2284 2285/** 2286 * batadv_bla_backbone_dump_entry() - dump one entry of the backbone table to a 2287 * netlink socket 2288 * @msg: buffer for the message 2289 * @portid: netlink port 2290 * @cb: Control block containing additional options 2291 * @primary_if: primary interface 2292 * @backbone_gw: entry to dump 2293 * 2294 * Return: 0 or error code. 2295 */ 2296static int 2297batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid, 2298 struct netlink_callback *cb, 2299 struct batadv_hard_iface *primary_if, 2300 struct batadv_bla_backbone_gw *backbone_gw) 2301{ 2302 const u8 *primary_addr = primary_if->net_dev->dev_addr; 2303 u16 backbone_crc; 2304 bool is_own; 2305 int msecs; 2306 void *hdr; 2307 int ret = -EINVAL; 2308 2309 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, 2310 &batadv_netlink_family, NLM_F_MULTI, 2311 BATADV_CMD_GET_BLA_BACKBONE); 2312 if (!hdr) { 2313 ret = -ENOBUFS; 2314 goto out; 2315 } 2316 2317 genl_dump_check_consistent(cb, hdr); 2318 2319 is_own = batadv_compare_eth(backbone_gw->orig, primary_addr); 2320 2321 spin_lock_bh(&backbone_gw->crc_lock); 2322 backbone_crc = backbone_gw->crc; 2323 spin_unlock_bh(&backbone_gw->crc_lock); 2324 2325 msecs = jiffies_to_msecs(jiffies - backbone_gw->lasttime); 2326 2327 if (is_own) 2328 if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) { 2329 genlmsg_cancel(msg, hdr); 2330 goto out; 2331 } 2332 2333 if (nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN, 2334 backbone_gw->orig) || 2335 nla_put_u16(msg, BATADV_ATTR_BLA_VID, backbone_gw->vid) || 2336 nla_put_u16(msg, BATADV_ATTR_BLA_CRC, 2337 backbone_crc) || 2338 nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) { 2339 genlmsg_cancel(msg, hdr); 2340 goto out; 2341 } 2342 2343 genlmsg_end(msg, hdr); 2344 ret = 0; 2345 2346out: 2347 return ret; 2348} 2349 2350/** 2351 * batadv_bla_backbone_dump_bucket() - dump one bucket of the backbone table to 2352 * a netlink socket 2353 * @msg: buffer for the message 2354 * @portid: netlink port 2355 * @cb: Control block containing additional options 2356 * @primary_if: primary interface 2357 * @hash: hash to dump 2358 * @bucket: bucket index to dump 2359 * @idx_skip: How many entries to skip 2360 * 2361 * Return: always 0. 2362 */ 2363static int 2364batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid, 2365 struct netlink_callback *cb, 2366 struct batadv_hard_iface *primary_if, 2367 struct batadv_hashtable *hash, 2368 unsigned int bucket, int *idx_skip) 2369{ 2370 struct batadv_bla_backbone_gw *backbone_gw; 2371 int idx = 0; 2372 int ret = 0; 2373 2374 spin_lock_bh(&hash->list_locks[bucket]); 2375 cb->seq = atomic_read(&hash->generation) << 1 | 1; 2376 2377 hlist_for_each_entry(backbone_gw, &hash->table[bucket], hash_entry) { 2378 if (idx++ < *idx_skip) 2379 continue; 2380 2381 ret = batadv_bla_backbone_dump_entry(msg, portid, cb, 2382 primary_if, backbone_gw); 2383 if (ret) { 2384 *idx_skip = idx - 1; 2385 goto unlock; 2386 } 2387 } 2388 2389 *idx_skip = 0; 2390unlock: 2391 spin_unlock_bh(&hash->list_locks[bucket]); 2392 return ret; 2393} 2394 2395/** 2396 * batadv_bla_backbone_dump() - dump backbone table to a netlink socket 2397 * @msg: buffer for the message 2398 * @cb: callback structure containing arguments 2399 * 2400 * Return: message length. 2401 */ 2402int batadv_bla_backbone_dump(struct sk_buff *msg, struct netlink_callback *cb) 2403{ 2404 struct batadv_hard_iface *primary_if = NULL; 2405 int portid = NETLINK_CB(cb->skb).portid; 2406 struct net *net = sock_net(cb->skb->sk); 2407 struct net_device *soft_iface; 2408 struct batadv_hashtable *hash; 2409 struct batadv_priv *bat_priv; 2410 int bucket = cb->args[0]; 2411 int idx = cb->args[1]; 2412 int ifindex; 2413 int ret = 0; 2414 2415 ifindex = batadv_netlink_get_ifindex(cb->nlh, 2416 BATADV_ATTR_MESH_IFINDEX); 2417 if (!ifindex) 2418 return -EINVAL; 2419 2420 soft_iface = dev_get_by_index(net, ifindex); 2421 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 2422 ret = -ENODEV; 2423 goto out; 2424 } 2425 2426 bat_priv = netdev_priv(soft_iface); 2427 hash = bat_priv->bla.backbone_hash; 2428 2429 primary_if = batadv_primary_if_get_selected(bat_priv); 2430 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { 2431 ret = -ENOENT; 2432 goto out; 2433 } 2434 2435 while (bucket < hash->size) { 2436 if (batadv_bla_backbone_dump_bucket(msg, portid, cb, primary_if, 2437 hash, bucket, &idx)) 2438 break; 2439 bucket++; 2440 } 2441 2442 cb->args[0] = bucket; 2443 cb->args[1] = idx; 2444 2445 ret = msg->len; 2446 2447out: 2448 batadv_hardif_put(primary_if); 2449 2450 dev_put(soft_iface); 2451 2452 return ret; 2453} 2454 2455#ifdef CONFIG_BATMAN_ADV_DAT 2456/** 2457 * batadv_bla_check_claim() - check if address is claimed 2458 * 2459 * @bat_priv: the bat priv with all the soft interface information 2460 * @addr: mac address of which the claim status is checked 2461 * @vid: the VLAN ID 2462 * 2463 * addr is checked if this address is claimed by the local device itself. 2464 * 2465 * Return: true if bla is disabled or the mac is claimed by the device, 2466 * false if the device addr is already claimed by another gateway 2467 */ 2468bool batadv_bla_check_claim(struct batadv_priv *bat_priv, 2469 u8 *addr, unsigned short vid) 2470{ 2471 struct batadv_bla_claim search_claim; 2472 struct batadv_bla_claim *claim = NULL; 2473 struct batadv_hard_iface *primary_if = NULL; 2474 bool ret = true; 2475 2476 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 2477 return ret; 2478 2479 primary_if = batadv_primary_if_get_selected(bat_priv); 2480 if (!primary_if) 2481 return ret; 2482 2483 /* First look if the mac address is claimed */ 2484 ether_addr_copy(search_claim.addr, addr); 2485 search_claim.vid = vid; 2486 2487 claim = batadv_claim_hash_find(bat_priv, &search_claim); 2488 2489 /* If there is a claim and we are not owner of the claim, 2490 * return false. 2491 */ 2492 if (claim) { 2493 if (!batadv_compare_eth(claim->backbone_gw->orig, 2494 primary_if->net_dev->dev_addr)) 2495 ret = false; 2496 batadv_claim_put(claim); 2497 } 2498 2499 batadv_hardif_put(primary_if); 2500 return ret; 2501} 2502#endif