1 /* 2 * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: 3 * 4 * Simon Wunderlich 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, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA 19 * 20 */ 21 22 #include "main.h" 23 #include "hash.h" 24 #include "hard-interface.h" 25 #include "originator.h" 26 #include "bridge_loop_avoidance.h" 27 #include "translation-table.h" 28 #include "send.h" 29 30 #include <linux/etherdevice.h> 31 #include <linux/crc16.h> 32 #include <linux/if_arp.h> 33 #include <net/arp.h> 34 #include <linux/if_vlan.h> 35 36 static const uint8_t announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; 37 38 static void bla_periodic_work(struct work_struct *work); 39 static void bla_send_announce(struct bat_priv *bat_priv, 40 struct backbone_gw *backbone_gw); 41 42 /* return the index of the claim */ 43 static inline uint32_t choose_claim(const void *data, uint32_t size) 44 { 45 const unsigned char *key = data; 46 uint32_t hash = 0; 47 size_t i; 48 49 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 50 hash += key[i]; 51 hash += (hash << 10); 52 hash ^= (hash >> 6); 53 } 54 55 hash += (hash << 3); 56 hash ^= (hash >> 11); 57 hash += (hash << 15); 58 59 return hash % size; 60 } 61 62 /* return the index of the backbone gateway */ 63 static inline uint32_t choose_backbone_gw(const void *data, uint32_t size) 64 { 65 const unsigned char *key = data; 66 uint32_t hash = 0; 67 size_t i; 68 69 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 70 hash += key[i]; 71 hash += (hash << 10); 72 hash ^= (hash >> 6); 73 } 74 75 hash += (hash << 3); 76 hash ^= (hash >> 11); 77 hash += (hash << 15); 78 79 return hash % size; 80 } 81 82 83 /* compares address and vid of two backbone gws */ 84 static int compare_backbone_gw(const struct hlist_node *node, const void *data2) 85 { 86 const void *data1 = container_of(node, struct backbone_gw, 87 hash_entry); 88 89 return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0); 90 } 91 92 /* compares address and vid of two claims */ 93 static int compare_claim(const struct hlist_node *node, const void *data2) 94 { 95 const void *data1 = container_of(node, struct claim, 96 hash_entry); 97 98 return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0); 99 } 100 101 /* free a backbone gw */ 102 static void backbone_gw_free_ref(struct backbone_gw *backbone_gw) 103 { 104 if (atomic_dec_and_test(&backbone_gw->refcount)) 105 kfree_rcu(backbone_gw, rcu); 106 } 107 108 /* finally deinitialize the claim */ 109 static void claim_free_rcu(struct rcu_head *rcu) 110 { 111 struct claim *claim; 112 113 claim = container_of(rcu, struct claim, rcu); 114 115 backbone_gw_free_ref(claim->backbone_gw); 116 kfree(claim); 117 } 118 119 /* free a claim, call claim_free_rcu if its the last reference */ 120 static void claim_free_ref(struct claim *claim) 121 { 122 if (atomic_dec_and_test(&claim->refcount)) 123 call_rcu(&claim->rcu, claim_free_rcu); 124 } 125 126 /** 127 * @bat_priv: the bat priv with all the soft interface information 128 * @data: search data (may be local/static data) 129 * 130 * looks for a claim in the hash, and returns it if found 131 * or NULL otherwise. 132 */ 133 static struct claim *claim_hash_find(struct bat_priv *bat_priv, 134 struct claim *data) 135 { 136 struct hashtable_t *hash = bat_priv->claim_hash; 137 struct hlist_head *head; 138 struct hlist_node *node; 139 struct claim *claim; 140 struct claim *claim_tmp = NULL; 141 int index; 142 143 if (!hash) 144 return NULL; 145 146 index = choose_claim(data, hash->size); 147 head = &hash->table[index]; 148 149 rcu_read_lock(); 150 hlist_for_each_entry_rcu(claim, node, head, hash_entry) { 151 if (!compare_claim(&claim->hash_entry, data)) 152 continue; 153 154 if (!atomic_inc_not_zero(&claim->refcount)) 155 continue; 156 157 claim_tmp = claim; 158 break; 159 } 160 rcu_read_unlock(); 161 162 return claim_tmp; 163 } 164 165 /** 166 * @bat_priv: the bat priv with all the soft interface information 167 * @addr: the address of the originator 168 * @vid: the VLAN ID 169 * 170 * looks for a claim in the hash, and returns it if found 171 * or NULL otherwise. 172 */ 173 static struct backbone_gw *backbone_hash_find(struct bat_priv *bat_priv, 174 uint8_t *addr, short vid) 175 { 176 struct hashtable_t *hash = bat_priv->backbone_hash; 177 struct hlist_head *head; 178 struct hlist_node *node; 179 struct backbone_gw search_entry, *backbone_gw; 180 struct backbone_gw *backbone_gw_tmp = NULL; 181 int index; 182 183 if (!hash) 184 return NULL; 185 186 memcpy(search_entry.orig, addr, ETH_ALEN); 187 search_entry.vid = vid; 188 189 index = choose_backbone_gw(&search_entry, hash->size); 190 head = &hash->table[index]; 191 192 rcu_read_lock(); 193 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { 194 if (!compare_backbone_gw(&backbone_gw->hash_entry, 195 &search_entry)) 196 continue; 197 198 if (!atomic_inc_not_zero(&backbone_gw->refcount)) 199 continue; 200 201 backbone_gw_tmp = backbone_gw; 202 break; 203 } 204 rcu_read_unlock(); 205 206 return backbone_gw_tmp; 207 } 208 209 /* delete all claims for a backbone */ 210 static void bla_del_backbone_claims(struct backbone_gw *backbone_gw) 211 { 212 struct hashtable_t *hash; 213 struct hlist_node *node, *node_tmp; 214 struct hlist_head *head; 215 struct claim *claim; 216 int i; 217 spinlock_t *list_lock; /* protects write access to the hash lists */ 218 219 hash = backbone_gw->bat_priv->claim_hash; 220 if (!hash) 221 return; 222 223 for (i = 0; i < hash->size; i++) { 224 head = &hash->table[i]; 225 list_lock = &hash->list_locks[i]; 226 227 spin_lock_bh(list_lock); 228 hlist_for_each_entry_safe(claim, node, node_tmp, 229 head, hash_entry) { 230 231 if (claim->backbone_gw != backbone_gw) 232 continue; 233 234 claim_free_ref(claim); 235 hlist_del_rcu(node); 236 } 237 spin_unlock_bh(list_lock); 238 } 239 240 /* all claims gone, intialize CRC */ 241 backbone_gw->crc = BLA_CRC_INIT; 242 } 243 244 /** 245 * @bat_priv: the bat priv with all the soft interface information 246 * @orig: the mac address to be announced within the claim 247 * @vid: the VLAN ID 248 * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...) 249 * 250 * sends a claim frame according to the provided info. 251 */ 252 static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, 253 short vid, int claimtype) 254 { 255 struct sk_buff *skb; 256 struct ethhdr *ethhdr; 257 struct hard_iface *primary_if; 258 struct net_device *soft_iface; 259 uint8_t *hw_src; 260 struct bla_claim_dst local_claim_dest; 261 uint32_t zeroip = 0; 262 263 primary_if = primary_if_get_selected(bat_priv); 264 if (!primary_if) 265 return; 266 267 memcpy(&local_claim_dest, &bat_priv->claim_dest, 268 sizeof(local_claim_dest)); 269 local_claim_dest.type = claimtype; 270 271 soft_iface = primary_if->soft_iface; 272 273 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, 274 /* IP DST: 0.0.0.0 */ 275 zeroip, 276 primary_if->soft_iface, 277 /* IP SRC: 0.0.0.0 */ 278 zeroip, 279 /* Ethernet DST: Broadcast */ 280 NULL, 281 /* Ethernet SRC/HW SRC: originator mac */ 282 primary_if->net_dev->dev_addr, 283 /* HW DST: FF:43:05:XX:00:00 284 * with XX = claim type 285 * and YY:YY = group id 286 */ 287 (uint8_t *)&local_claim_dest); 288 289 if (!skb) 290 goto out; 291 292 ethhdr = (struct ethhdr *)skb->data; 293 hw_src = (uint8_t *)ethhdr + ETH_HLEN + sizeof(struct arphdr); 294 295 /* now we pretend that the client would have sent this ... */ 296 switch (claimtype) { 297 case CLAIM_TYPE_ADD: 298 /* normal claim frame 299 * set Ethernet SRC to the clients mac 300 */ 301 memcpy(ethhdr->h_source, mac, ETH_ALEN); 302 bat_dbg(DBG_BLA, bat_priv, 303 "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); 304 break; 305 case CLAIM_TYPE_DEL: 306 /* unclaim frame 307 * set HW SRC to the clients mac 308 */ 309 memcpy(hw_src, mac, ETH_ALEN); 310 bat_dbg(DBG_BLA, bat_priv, 311 "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac, vid); 312 break; 313 case CLAIM_TYPE_ANNOUNCE: 314 /* announcement frame 315 * set HW SRC to the special mac containg the crc 316 */ 317 memcpy(hw_src, mac, ETH_ALEN); 318 bat_dbg(DBG_BLA, bat_priv, 319 "bla_send_claim(): ANNOUNCE of %pM on vid %d\n", 320 ethhdr->h_source, vid); 321 break; 322 case CLAIM_TYPE_REQUEST: 323 /* request frame 324 * set HW SRC to the special mac containg the crc 325 */ 326 memcpy(hw_src, mac, ETH_ALEN); 327 memcpy(ethhdr->h_dest, mac, ETH_ALEN); 328 bat_dbg(DBG_BLA, bat_priv, 329 "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n", 330 ethhdr->h_source, ethhdr->h_dest, vid); 331 break; 332 333 } 334 335 if (vid != -1) 336 skb = vlan_insert_tag(skb, vid); 337 338 skb_reset_mac_header(skb); 339 skb->protocol = eth_type_trans(skb, soft_iface); 340 bat_priv->stats.rx_packets++; 341 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; 342 soft_iface->last_rx = jiffies; 343 344 netif_rx(skb); 345 out: 346 if (primary_if) 347 hardif_free_ref(primary_if); 348 } 349 350 /** 351 * @bat_priv: the bat priv with all the soft interface information 352 * @orig: the mac address of the originator 353 * @vid: the VLAN ID 354 * 355 * searches for the backbone gw or creates a new one if it could not 356 * be found. 357 */ 358 static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, 359 uint8_t *orig, short vid) 360 { 361 struct backbone_gw *entry; 362 struct orig_node *orig_node; 363 int hash_added; 364 365 entry = backbone_hash_find(bat_priv, orig, vid); 366 367 if (entry) 368 return entry; 369 370 bat_dbg(DBG_BLA, bat_priv, 371 "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n", 372 orig, vid); 373 374 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 375 if (!entry) 376 return NULL; 377 378 entry->vid = vid; 379 entry->lasttime = jiffies; 380 entry->crc = BLA_CRC_INIT; 381 entry->bat_priv = bat_priv; 382 atomic_set(&entry->request_sent, 0); 383 memcpy(entry->orig, orig, ETH_ALEN); 384 385 /* one for the hash, one for returning */ 386 atomic_set(&entry->refcount, 2); 387 388 hash_added = hash_add(bat_priv->backbone_hash, compare_backbone_gw, 389 choose_backbone_gw, entry, &entry->hash_entry); 390 391 if (unlikely(hash_added != 0)) { 392 /* hash failed, free the structure */ 393 kfree(entry); 394 return NULL; 395 } 396 397 /* this is a gateway now, remove any tt entries */ 398 orig_node = orig_hash_find(bat_priv, orig); 399 if (orig_node) { 400 tt_global_del_orig(bat_priv, orig_node, 401 "became a backbone gateway"); 402 orig_node_free_ref(orig_node); 403 } 404 return entry; 405 } 406 407 /* update or add the own backbone gw to make sure we announce 408 * where we receive other backbone gws 409 */ 410 static void bla_update_own_backbone_gw(struct bat_priv *bat_priv, 411 struct hard_iface *primary_if, 412 short vid) 413 { 414 struct backbone_gw *backbone_gw; 415 416 backbone_gw = bla_get_backbone_gw(bat_priv, 417 primary_if->net_dev->dev_addr, vid); 418 if (unlikely(!backbone_gw)) 419 return; 420 421 backbone_gw->lasttime = jiffies; 422 backbone_gw_free_ref(backbone_gw); 423 } 424 425 /** 426 * @bat_priv: the bat priv with all the soft interface information 427 * @vid: the vid where the request came on 428 * 429 * Repeat all of our own claims, and finally send an ANNOUNCE frame 430 * to allow the requester another check if the CRC is correct now. 431 */ 432 static void bla_answer_request(struct bat_priv *bat_priv, 433 struct hard_iface *primary_if, short vid) 434 { 435 struct hlist_node *node; 436 struct hlist_head *head; 437 struct hashtable_t *hash; 438 struct claim *claim; 439 struct backbone_gw *backbone_gw; 440 int i; 441 442 bat_dbg(DBG_BLA, bat_priv, 443 "bla_answer_request(): received a claim request, send all of our own claims again\n"); 444 445 backbone_gw = backbone_hash_find(bat_priv, 446 primary_if->net_dev->dev_addr, vid); 447 if (!backbone_gw) 448 return; 449 450 hash = bat_priv->claim_hash; 451 for (i = 0; i < hash->size; i++) { 452 head = &hash->table[i]; 453 454 rcu_read_lock(); 455 hlist_for_each_entry_rcu(claim, node, head, hash_entry) { 456 /* only own claims are interesting */ 457 if (claim->backbone_gw != backbone_gw) 458 continue; 459 460 bla_send_claim(bat_priv, claim->addr, claim->vid, 461 CLAIM_TYPE_ADD); 462 } 463 rcu_read_unlock(); 464 } 465 466 /* finally, send an announcement frame */ 467 bla_send_announce(bat_priv, backbone_gw); 468 backbone_gw_free_ref(backbone_gw); 469 } 470 471 /** 472 * @backbone_gw: the backbone gateway from whom we are out of sync 473 * 474 * When the crc is wrong, ask the backbone gateway for a full table update. 475 * After the request, it will repeat all of his own claims and finally 476 * send an announcement claim with which we can check again. 477 */ 478 static void bla_send_request(struct backbone_gw *backbone_gw) 479 { 480 /* first, remove all old entries */ 481 bla_del_backbone_claims(backbone_gw); 482 483 bat_dbg(DBG_BLA, backbone_gw->bat_priv, 484 "Sending REQUEST to %pM\n", 485 backbone_gw->orig); 486 487 /* send request */ 488 bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig, 489 backbone_gw->vid, CLAIM_TYPE_REQUEST); 490 491 /* no local broadcasts should be sent or received, for now. */ 492 if (!atomic_read(&backbone_gw->request_sent)) { 493 atomic_inc(&backbone_gw->bat_priv->bla_num_requests); 494 atomic_set(&backbone_gw->request_sent, 1); 495 } 496 } 497 498 /** 499 * @bat_priv: the bat priv with all the soft interface information 500 * @backbone_gw: our backbone gateway which should be announced 501 * 502 * This function sends an announcement. It is called from multiple 503 * places. 504 */ 505 static void bla_send_announce(struct bat_priv *bat_priv, 506 struct backbone_gw *backbone_gw) 507 { 508 uint8_t mac[ETH_ALEN]; 509 uint16_t crc; 510 511 memcpy(mac, announce_mac, 4); 512 crc = htons(backbone_gw->crc); 513 memcpy(&mac[4], (uint8_t *)&crc, 2); 514 515 bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE); 516 517 } 518 519 /** 520 * @bat_priv: the bat priv with all the soft interface information 521 * @mac: the mac address of the claim 522 * @vid: the VLAN ID of the frame 523 * @backbone_gw: the backbone gateway which claims it 524 * 525 * Adds a claim in the claim hash. 526 */ 527 static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, 528 const short vid, struct backbone_gw *backbone_gw) 529 { 530 struct claim *claim; 531 struct claim search_claim; 532 int hash_added; 533 534 memcpy(search_claim.addr, mac, ETH_ALEN); 535 search_claim.vid = vid; 536 claim = claim_hash_find(bat_priv, &search_claim); 537 538 /* create a new claim entry if it does not exist yet. */ 539 if (!claim) { 540 claim = kzalloc(sizeof(*claim), GFP_ATOMIC); 541 if (!claim) 542 return; 543 544 memcpy(claim->addr, mac, ETH_ALEN); 545 claim->vid = vid; 546 claim->lasttime = jiffies; 547 claim->backbone_gw = backbone_gw; 548 549 atomic_set(&claim->refcount, 2); 550 bat_dbg(DBG_BLA, bat_priv, 551 "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", 552 mac, vid); 553 hash_added = hash_add(bat_priv->claim_hash, compare_claim, 554 choose_claim, claim, &claim->hash_entry); 555 556 if (unlikely(hash_added != 0)) { 557 /* only local changes happened. */ 558 kfree(claim); 559 return; 560 } 561 } else { 562 claim->lasttime = jiffies; 563 if (claim->backbone_gw == backbone_gw) 564 /* no need to register a new backbone */ 565 goto claim_free_ref; 566 567 bat_dbg(DBG_BLA, bat_priv, 568 "bla_add_claim(): changing ownership for %pM, vid %d\n", 569 mac, vid); 570 571 claim->backbone_gw->crc ^= 572 crc16(0, claim->addr, ETH_ALEN); 573 backbone_gw_free_ref(claim->backbone_gw); 574 575 } 576 /* set (new) backbone gw */ 577 atomic_inc(&backbone_gw->refcount); 578 claim->backbone_gw = backbone_gw; 579 580 backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); 581 backbone_gw->lasttime = jiffies; 582 583 claim_free_ref: 584 claim_free_ref(claim); 585 } 586 587 /* Delete a claim from the claim hash which has the 588 * given mac address and vid. 589 */ 590 static void bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac, 591 const short vid) 592 { 593 struct claim search_claim, *claim; 594 595 memcpy(search_claim.addr, mac, ETH_ALEN); 596 search_claim.vid = vid; 597 claim = claim_hash_find(bat_priv, &search_claim); 598 if (!claim) 599 return; 600 601 bat_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid); 602 603 hash_remove(bat_priv->claim_hash, compare_claim, choose_claim, claim); 604 claim_free_ref(claim); /* reference from the hash is gone */ 605 606 claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); 607 608 /* don't need the reference from hash_find() anymore */ 609 claim_free_ref(claim); 610 } 611 612 /* check for ANNOUNCE frame, return 1 if handled */ 613 static int handle_announce(struct bat_priv *bat_priv, 614 uint8_t *an_addr, uint8_t *backbone_addr, short vid) 615 { 616 struct backbone_gw *backbone_gw; 617 uint16_t crc; 618 619 if (memcmp(an_addr, announce_mac, 4) != 0) 620 return 0; 621 622 backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid); 623 624 if (unlikely(!backbone_gw)) 625 return 1; 626 627 628 /* handle as ANNOUNCE frame */ 629 backbone_gw->lasttime = jiffies; 630 crc = ntohs(*((uint16_t *)(&an_addr[4]))); 631 632 bat_dbg(DBG_BLA, bat_priv, 633 "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", 634 vid, backbone_gw->orig, crc); 635 636 if (backbone_gw->crc != crc) { 637 bat_dbg(DBG_BLA, backbone_gw->bat_priv, 638 "handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n", 639 backbone_gw->orig, backbone_gw->vid, backbone_gw->crc, 640 crc); 641 642 bla_send_request(backbone_gw); 643 } else { 644 /* if we have sent a request and the crc was OK, 645 * we can allow traffic again. 646 */ 647 if (atomic_read(&backbone_gw->request_sent)) { 648 atomic_dec(&backbone_gw->bat_priv->bla_num_requests); 649 atomic_set(&backbone_gw->request_sent, 0); 650 } 651 } 652 653 backbone_gw_free_ref(backbone_gw); 654 return 1; 655 } 656 657 /* check for REQUEST frame, return 1 if handled */ 658 static int handle_request(struct bat_priv *bat_priv, 659 struct hard_iface *primary_if, 660 uint8_t *backbone_addr, 661 struct ethhdr *ethhdr, short vid) 662 { 663 /* check for REQUEST frame */ 664 if (!compare_eth(backbone_addr, ethhdr->h_dest)) 665 return 0; 666 667 /* sanity check, this should not happen on a normal switch, 668 * we ignore it in this case. 669 */ 670 if (!compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) 671 return 1; 672 673 bat_dbg(DBG_BLA, bat_priv, 674 "handle_request(): REQUEST vid %d (sent by %pM)...\n", 675 vid, ethhdr->h_source); 676 677 bla_answer_request(bat_priv, primary_if, vid); 678 return 1; 679 } 680 681 /* check for UNCLAIM frame, return 1 if handled */ 682 static int handle_unclaim(struct bat_priv *bat_priv, 683 struct hard_iface *primary_if, 684 uint8_t *backbone_addr, 685 uint8_t *claim_addr, short vid) 686 { 687 struct backbone_gw *backbone_gw; 688 689 /* unclaim in any case if it is our own */ 690 if (primary_if && compare_eth(backbone_addr, 691 primary_if->net_dev->dev_addr)) 692 bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_DEL); 693 694 backbone_gw = backbone_hash_find(bat_priv, backbone_addr, vid); 695 696 if (!backbone_gw) 697 return 1; 698 699 /* this must be an UNCLAIM frame */ 700 bat_dbg(DBG_BLA, bat_priv, 701 "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n", 702 claim_addr, vid, backbone_gw->orig); 703 704 bla_del_claim(bat_priv, claim_addr, vid); 705 backbone_gw_free_ref(backbone_gw); 706 return 1; 707 } 708 709 /* check for CLAIM frame, return 1 if handled */ 710 static int handle_claim(struct bat_priv *bat_priv, 711 struct hard_iface *primary_if, uint8_t *backbone_addr, 712 uint8_t *claim_addr, short vid) 713 { 714 struct backbone_gw *backbone_gw; 715 716 /* register the gateway if not yet available, and add the claim. */ 717 718 backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid); 719 720 if (unlikely(!backbone_gw)) 721 return 1; 722 723 /* this must be a CLAIM frame */ 724 bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); 725 if (compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) 726 bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_ADD); 727 728 /* TODO: we could call something like tt_local_del() here. */ 729 730 backbone_gw_free_ref(backbone_gw); 731 return 1; 732 } 733 734 /** 735 * @bat_priv: the bat priv with all the soft interface information 736 * @hw_src: the Hardware source in the ARP Header 737 * @hw_dst: the Hardware destination in the ARP Header 738 * @ethhdr: pointer to the Ethernet header of the claim frame 739 * 740 * checks if it is a claim packet and if its on the same group. 741 * This function also applies the group ID of the sender 742 * if it is in the same mesh. 743 * 744 * returns: 745 * 2 - if it is a claim packet and on the same group 746 * 1 - if is a claim packet from another group 747 * 0 - if it is not a claim packet 748 */ 749 static int check_claim_group(struct bat_priv *bat_priv, 750 struct hard_iface *primary_if, 751 uint8_t *hw_src, uint8_t *hw_dst, 752 struct ethhdr *ethhdr) 753 { 754 uint8_t *backbone_addr; 755 struct orig_node *orig_node; 756 struct bla_claim_dst *bla_dst, *bla_dst_own; 757 758 bla_dst = (struct bla_claim_dst *)hw_dst; 759 bla_dst_own = &bat_priv->claim_dest; 760 761 /* check if it is a claim packet in general */ 762 if (memcmp(bla_dst->magic, bla_dst_own->magic, 763 sizeof(bla_dst->magic)) != 0) 764 return 0; 765 766 /* if announcement packet, use the source, 767 * otherwise assume it is in the hw_src 768 */ 769 switch (bla_dst->type) { 770 case CLAIM_TYPE_ADD: 771 backbone_addr = hw_src; 772 break; 773 case CLAIM_TYPE_REQUEST: 774 case CLAIM_TYPE_ANNOUNCE: 775 case CLAIM_TYPE_DEL: 776 backbone_addr = ethhdr->h_source; 777 break; 778 default: 779 return 0; 780 } 781 782 /* don't accept claim frames from ourselves */ 783 if (compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) 784 return 0; 785 786 /* if its already the same group, it is fine. */ 787 if (bla_dst->group == bla_dst_own->group) 788 return 2; 789 790 /* lets see if this originator is in our mesh */ 791 orig_node = orig_hash_find(bat_priv, backbone_addr); 792 793 /* dont accept claims from gateways which are not in 794 * the same mesh or group. 795 */ 796 if (!orig_node) 797 return 1; 798 799 /* if our mesh friends mac is bigger, use it for ourselves. */ 800 if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) { 801 bat_dbg(DBG_BLA, bat_priv, 802 "taking other backbones claim group: %04x\n", 803 ntohs(bla_dst->group)); 804 bla_dst_own->group = bla_dst->group; 805 } 806 807 orig_node_free_ref(orig_node); 808 809 return 2; 810 } 811 812 813 /** 814 * @bat_priv: the bat priv with all the soft interface information 815 * @skb: the frame to be checked 816 * 817 * Check if this is a claim frame, and process it accordingly. 818 * 819 * returns 1 if it was a claim frame, otherwise return 0 to 820 * tell the callee that it can use the frame on its own. 821 */ 822 static int bla_process_claim(struct bat_priv *bat_priv, 823 struct hard_iface *primary_if, 824 struct sk_buff *skb) 825 { 826 struct ethhdr *ethhdr; 827 struct vlan_ethhdr *vhdr; 828 struct arphdr *arphdr; 829 uint8_t *hw_src, *hw_dst; 830 struct bla_claim_dst *bla_dst; 831 uint16_t proto; 832 int headlen; 833 short vid = -1; 834 int ret; 835 836 ethhdr = (struct ethhdr *)skb_mac_header(skb); 837 838 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 839 vhdr = (struct vlan_ethhdr *)ethhdr; 840 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 841 proto = ntohs(vhdr->h_vlan_encapsulated_proto); 842 headlen = sizeof(*vhdr); 843 } else { 844 proto = ntohs(ethhdr->h_proto); 845 headlen = ETH_HLEN; 846 } 847 848 if (proto != ETH_P_ARP) 849 return 0; /* not a claim frame */ 850 851 /* this must be a ARP frame. check if it is a claim. */ 852 853 if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev)))) 854 return 0; 855 856 /* pskb_may_pull() may have modified the pointers, get ethhdr again */ 857 ethhdr = (struct ethhdr *)skb_mac_header(skb); 858 arphdr = (struct arphdr *)((uint8_t *)ethhdr + headlen); 859 860 /* Check whether the ARP frame carries a valid 861 * IP information 862 */ 863 864 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) 865 return 0; 866 if (arphdr->ar_pro != htons(ETH_P_IP)) 867 return 0; 868 if (arphdr->ar_hln != ETH_ALEN) 869 return 0; 870 if (arphdr->ar_pln != 4) 871 return 0; 872 873 hw_src = (uint8_t *)arphdr + sizeof(struct arphdr); 874 hw_dst = hw_src + ETH_ALEN + 4; 875 bla_dst = (struct bla_claim_dst *)hw_dst; 876 877 /* check if it is a claim frame. */ 878 ret = check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ethhdr); 879 if (ret == 1) 880 bat_dbg(DBG_BLA, bat_priv, 881 "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", 882 ethhdr->h_source, vid, hw_src, hw_dst); 883 884 if (ret < 2) 885 return ret; 886 887 /* become a backbone gw ourselves on this vlan if not happened yet */ 888 bla_update_own_backbone_gw(bat_priv, primary_if, vid); 889 890 /* check for the different types of claim frames ... */ 891 switch (bla_dst->type) { 892 case CLAIM_TYPE_ADD: 893 if (handle_claim(bat_priv, primary_if, hw_src, 894 ethhdr->h_source, vid)) 895 return 1; 896 break; 897 case CLAIM_TYPE_DEL: 898 if (handle_unclaim(bat_priv, primary_if, 899 ethhdr->h_source, hw_src, vid)) 900 return 1; 901 break; 902 903 case CLAIM_TYPE_ANNOUNCE: 904 if (handle_announce(bat_priv, hw_src, ethhdr->h_source, vid)) 905 return 1; 906 break; 907 case CLAIM_TYPE_REQUEST: 908 if (handle_request(bat_priv, primary_if, hw_src, ethhdr, vid)) 909 return 1; 910 break; 911 } 912 913 bat_dbg(DBG_BLA, bat_priv, 914 "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", 915 ethhdr->h_source, vid, hw_src, hw_dst); 916 return 1; 917 } 918 919 /* Check when we last heard from other nodes, and remove them in case of 920 * a time out, or clean all backbone gws if now is set. 921 */ 922 static void bla_purge_backbone_gw(struct bat_priv *bat_priv, int now) 923 { 924 struct backbone_gw *backbone_gw; 925 struct hlist_node *node, *node_tmp; 926 struct hlist_head *head; 927 struct hashtable_t *hash; 928 spinlock_t *list_lock; /* protects write access to the hash lists */ 929 int i; 930 931 hash = bat_priv->backbone_hash; 932 if (!hash) 933 return; 934 935 for (i = 0; i < hash->size; i++) { 936 head = &hash->table[i]; 937 list_lock = &hash->list_locks[i]; 938 939 spin_lock_bh(list_lock); 940 hlist_for_each_entry_safe(backbone_gw, node, node_tmp, 941 head, hash_entry) { 942 if (now) 943 goto purge_now; 944 if (!has_timed_out(backbone_gw->lasttime, 945 BLA_BACKBONE_TIMEOUT)) 946 continue; 947 948 bat_dbg(DBG_BLA, backbone_gw->bat_priv, 949 "bla_purge_backbone_gw(): backbone gw %pM timed out\n", 950 backbone_gw->orig); 951 952 purge_now: 953 /* don't wait for the pending request anymore */ 954 if (atomic_read(&backbone_gw->request_sent)) 955 atomic_dec(&bat_priv->bla_num_requests); 956 957 bla_del_backbone_claims(backbone_gw); 958 959 hlist_del_rcu(node); 960 backbone_gw_free_ref(backbone_gw); 961 } 962 spin_unlock_bh(list_lock); 963 } 964 } 965 966 /** 967 * @bat_priv: the bat priv with all the soft interface information 968 * @primary_if: the selected primary interface, may be NULL if now is set 969 * @now: whether the whole hash shall be wiped now 970 * 971 * Check when we heard last time from our own claims, and remove them in case of 972 * a time out, or clean all claims if now is set 973 */ 974 static void bla_purge_claims(struct bat_priv *bat_priv, 975 struct hard_iface *primary_if, int now) 976 { 977 struct claim *claim; 978 struct hlist_node *node; 979 struct hlist_head *head; 980 struct hashtable_t *hash; 981 int i; 982 983 hash = bat_priv->claim_hash; 984 if (!hash) 985 return; 986 987 for (i = 0; i < hash->size; i++) { 988 head = &hash->table[i]; 989 990 rcu_read_lock(); 991 hlist_for_each_entry_rcu(claim, node, head, hash_entry) { 992 if (now) 993 goto purge_now; 994 if (!compare_eth(claim->backbone_gw->orig, 995 primary_if->net_dev->dev_addr)) 996 continue; 997 if (!has_timed_out(claim->lasttime, 998 BLA_CLAIM_TIMEOUT)) 999 continue; 1000 1001 bat_dbg(DBG_BLA, bat_priv, 1002 "bla_purge_claims(): %pM, vid %d, time out\n", 1003 claim->addr, claim->vid); 1004 1005 purge_now: 1006 handle_unclaim(bat_priv, primary_if, 1007 claim->backbone_gw->orig, 1008 claim->addr, claim->vid); 1009 } 1010 rcu_read_unlock(); 1011 } 1012 } 1013 1014 /** 1015 * @bat_priv: the bat priv with all the soft interface information 1016 * @primary_if: the new selected primary_if 1017 * @oldif: the old primary interface, may be NULL 1018 * 1019 * Update the backbone gateways when the own orig address changes. 1020 * 1021 */ 1022 void bla_update_orig_address(struct bat_priv *bat_priv, 1023 struct hard_iface *primary_if, 1024 struct hard_iface *oldif) 1025 { 1026 struct backbone_gw *backbone_gw; 1027 struct hlist_node *node; 1028 struct hlist_head *head; 1029 struct hashtable_t *hash; 1030 int i; 1031 1032 /* reset bridge loop avoidance group id */ 1033 bat_priv->claim_dest.group = 1034 htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); 1035 1036 if (!oldif) { 1037 bla_purge_claims(bat_priv, NULL, 1); 1038 bla_purge_backbone_gw(bat_priv, 1); 1039 return; 1040 } 1041 1042 hash = bat_priv->backbone_hash; 1043 if (!hash) 1044 return; 1045 1046 for (i = 0; i < hash->size; i++) { 1047 head = &hash->table[i]; 1048 1049 rcu_read_lock(); 1050 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { 1051 /* own orig still holds the old value. */ 1052 if (!compare_eth(backbone_gw->orig, 1053 oldif->net_dev->dev_addr)) 1054 continue; 1055 1056 memcpy(backbone_gw->orig, 1057 primary_if->net_dev->dev_addr, ETH_ALEN); 1058 /* send an announce frame so others will ask for our 1059 * claims and update their tables. 1060 */ 1061 bla_send_announce(bat_priv, backbone_gw); 1062 } 1063 rcu_read_unlock(); 1064 } 1065 } 1066 1067 1068 1069 /* (re)start the timer */ 1070 static void bla_start_timer(struct bat_priv *bat_priv) 1071 { 1072 INIT_DELAYED_WORK(&bat_priv->bla_work, bla_periodic_work); 1073 queue_delayed_work(bat_event_workqueue, &bat_priv->bla_work, 1074 msecs_to_jiffies(BLA_PERIOD_LENGTH)); 1075 } 1076 1077 /* periodic work to do: 1078 * * purge structures when they are too old 1079 * * send announcements 1080 */ 1081 static void bla_periodic_work(struct work_struct *work) 1082 { 1083 struct delayed_work *delayed_work = 1084 container_of(work, struct delayed_work, work); 1085 struct bat_priv *bat_priv = 1086 container_of(delayed_work, struct bat_priv, bla_work); 1087 struct hlist_node *node; 1088 struct hlist_head *head; 1089 struct backbone_gw *backbone_gw; 1090 struct hashtable_t *hash; 1091 struct hard_iface *primary_if; 1092 int i; 1093 1094 primary_if = primary_if_get_selected(bat_priv); 1095 if (!primary_if) 1096 goto out; 1097 1098 bla_purge_claims(bat_priv, primary_if, 0); 1099 bla_purge_backbone_gw(bat_priv, 0); 1100 1101 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1102 goto out; 1103 1104 hash = bat_priv->backbone_hash; 1105 if (!hash) 1106 goto out; 1107 1108 for (i = 0; i < hash->size; i++) { 1109 head = &hash->table[i]; 1110 1111 rcu_read_lock(); 1112 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { 1113 if (!compare_eth(backbone_gw->orig, 1114 primary_if->net_dev->dev_addr)) 1115 continue; 1116 1117 backbone_gw->lasttime = jiffies; 1118 1119 bla_send_announce(bat_priv, backbone_gw); 1120 } 1121 rcu_read_unlock(); 1122 } 1123 out: 1124 if (primary_if) 1125 hardif_free_ref(primary_if); 1126 1127 bla_start_timer(bat_priv); 1128 } 1129 1130 /* initialize all bla structures */ 1131 int bla_init(struct bat_priv *bat_priv) 1132 { 1133 int i; 1134 uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; 1135 struct hard_iface *primary_if; 1136 1137 bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n"); 1138 1139 /* setting claim destination address */ 1140 memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); 1141 bat_priv->claim_dest.type = 0; 1142 primary_if = primary_if_get_selected(bat_priv); 1143 if (primary_if) { 1144 bat_priv->claim_dest.group = 1145 htons(crc16(0, primary_if->net_dev->dev_addr, 1146 ETH_ALEN)); 1147 hardif_free_ref(primary_if); 1148 } else { 1149 bat_priv->claim_dest.group = 0; /* will be set later */ 1150 } 1151 1152 /* initialize the duplicate list */ 1153 for (i = 0; i < DUPLIST_SIZE; i++) 1154 bat_priv->bcast_duplist[i].entrytime = 1155 jiffies - msecs_to_jiffies(DUPLIST_TIMEOUT); 1156 bat_priv->bcast_duplist_curr = 0; 1157 1158 if (bat_priv->claim_hash) 1159 return 1; 1160 1161 bat_priv->claim_hash = hash_new(128); 1162 bat_priv->backbone_hash = hash_new(32); 1163 1164 if (!bat_priv->claim_hash || !bat_priv->backbone_hash) 1165 return -1; 1166 1167 bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); 1168 1169 bla_start_timer(bat_priv); 1170 return 1; 1171 } 1172 1173 /** 1174 * @bat_priv: the bat priv with all the soft interface information 1175 * @bcast_packet: originator mac address 1176 * @hdr_size: maximum length of the frame 1177 * 1178 * check if it is on our broadcast list. Another gateway might 1179 * have sent the same packet because it is connected to the same backbone, 1180 * so we have to remove this duplicate. 1181 * 1182 * This is performed by checking the CRC, which will tell us 1183 * with a good chance that it is the same packet. If it is furthermore 1184 * sent by another host, drop it. We allow equal packets from 1185 * the same host however as this might be intended. 1186 * 1187 **/ 1188 1189 int bla_check_bcast_duplist(struct bat_priv *bat_priv, 1190 struct bcast_packet *bcast_packet, 1191 int hdr_size) 1192 { 1193 int i, length, curr; 1194 uint8_t *content; 1195 uint16_t crc; 1196 struct bcast_duplist_entry *entry; 1197 1198 length = hdr_size - sizeof(*bcast_packet); 1199 content = (uint8_t *)bcast_packet; 1200 content += sizeof(*bcast_packet); 1201 1202 /* calculate the crc ... */ 1203 crc = crc16(0, content, length); 1204 1205 for (i = 0 ; i < DUPLIST_SIZE; i++) { 1206 curr = (bat_priv->bcast_duplist_curr + i) % DUPLIST_SIZE; 1207 entry = &bat_priv->bcast_duplist[curr]; 1208 1209 /* we can stop searching if the entry is too old ; 1210 * later entries will be even older 1211 */ 1212 if (has_timed_out(entry->entrytime, DUPLIST_TIMEOUT)) 1213 break; 1214 1215 if (entry->crc != crc) 1216 continue; 1217 1218 if (compare_eth(entry->orig, bcast_packet->orig)) 1219 continue; 1220 1221 /* this entry seems to match: same crc, not too old, 1222 * and from another gw. therefore return 1 to forbid it. 1223 */ 1224 return 1; 1225 } 1226 /* not found, add a new entry (overwrite the oldest entry) */ 1227 curr = (bat_priv->bcast_duplist_curr + DUPLIST_SIZE - 1) % DUPLIST_SIZE; 1228 entry = &bat_priv->bcast_duplist[curr]; 1229 entry->crc = crc; 1230 entry->entrytime = jiffies; 1231 memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); 1232 bat_priv->bcast_duplist_curr = curr; 1233 1234 /* allow it, its the first occurence. */ 1235 return 0; 1236 } 1237 1238 1239 1240 /** 1241 * @bat_priv: the bat priv with all the soft interface information 1242 * @orig: originator mac address 1243 * 1244 * check if the originator is a gateway for any VLAN ID. 1245 * 1246 * returns 1 if it is found, 0 otherwise 1247 * 1248 */ 1249 1250 int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) 1251 { 1252 struct hashtable_t *hash = bat_priv->backbone_hash; 1253 struct hlist_head *head; 1254 struct hlist_node *node; 1255 struct backbone_gw *backbone_gw; 1256 int i; 1257 1258 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1259 return 0; 1260 1261 if (!hash) 1262 return 0; 1263 1264 for (i = 0; i < hash->size; i++) { 1265 head = &hash->table[i]; 1266 1267 rcu_read_lock(); 1268 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { 1269 if (compare_eth(backbone_gw->orig, orig)) { 1270 rcu_read_unlock(); 1271 return 1; 1272 } 1273 } 1274 rcu_read_unlock(); 1275 } 1276 1277 return 0; 1278 } 1279 1280 1281 /** 1282 * @skb: the frame to be checked 1283 * @orig_node: the orig_node of the frame 1284 * @hdr_size: maximum length of the frame 1285 * 1286 * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1 1287 * if the orig_node is also a gateway on the soft interface, otherwise it 1288 * returns 0. 1289 * 1290 */ 1291 int bla_is_backbone_gw(struct sk_buff *skb, 1292 struct orig_node *orig_node, int hdr_size) 1293 { 1294 struct ethhdr *ethhdr; 1295 struct vlan_ethhdr *vhdr; 1296 struct backbone_gw *backbone_gw; 1297 short vid = -1; 1298 1299 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) 1300 return 0; 1301 1302 /* first, find out the vid. */ 1303 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) 1304 return 0; 1305 1306 ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size); 1307 1308 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 1309 if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr))) 1310 return 0; 1311 1312 vhdr = (struct vlan_ethhdr *)(((uint8_t *)skb->data) + 1313 hdr_size); 1314 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 1315 } 1316 1317 /* see if this originator is a backbone gw for this VLAN */ 1318 1319 backbone_gw = backbone_hash_find(orig_node->bat_priv, 1320 orig_node->orig, vid); 1321 if (!backbone_gw) 1322 return 0; 1323 1324 backbone_gw_free_ref(backbone_gw); 1325 return 1; 1326 } 1327 1328 /* free all bla structures (for softinterface free or module unload) */ 1329 void bla_free(struct bat_priv *bat_priv) 1330 { 1331 struct hard_iface *primary_if; 1332 1333 cancel_delayed_work_sync(&bat_priv->bla_work); 1334 primary_if = primary_if_get_selected(bat_priv); 1335 1336 if (bat_priv->claim_hash) { 1337 bla_purge_claims(bat_priv, primary_if, 1); 1338 hash_destroy(bat_priv->claim_hash); 1339 bat_priv->claim_hash = NULL; 1340 } 1341 if (bat_priv->backbone_hash) { 1342 bla_purge_backbone_gw(bat_priv, 1); 1343 hash_destroy(bat_priv->backbone_hash); 1344 bat_priv->backbone_hash = NULL; 1345 } 1346 if (primary_if) 1347 hardif_free_ref(primary_if); 1348 } 1349 1350 /** 1351 * @bat_priv: the bat priv with all the soft interface information 1352 * @skb: the frame to be checked 1353 * @vid: the VLAN ID of the frame 1354 * 1355 * bla_rx avoidance checks if: 1356 * * we have to race for a claim 1357 * * if the frame is allowed on the LAN 1358 * 1359 * in these cases, the skb is further handled by this function and 1360 * returns 1, otherwise it returns 0 and the caller shall further 1361 * process the skb. 1362 * 1363 */ 1364 int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) 1365 { 1366 struct ethhdr *ethhdr; 1367 struct claim search_claim, *claim = NULL; 1368 struct hard_iface *primary_if; 1369 int ret; 1370 1371 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1372 1373 primary_if = primary_if_get_selected(bat_priv); 1374 if (!primary_if) 1375 goto handled; 1376 1377 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1378 goto allow; 1379 1380 1381 if (unlikely(atomic_read(&bat_priv->bla_num_requests))) 1382 /* don't allow broadcasts while requests are in flight */ 1383 if (is_multicast_ether_addr(ethhdr->h_dest)) 1384 goto handled; 1385 1386 memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); 1387 search_claim.vid = vid; 1388 claim = claim_hash_find(bat_priv, &search_claim); 1389 1390 if (!claim) { 1391 /* possible optimization: race for a claim */ 1392 /* No claim exists yet, claim it for us! 1393 */ 1394 handle_claim(bat_priv, primary_if, 1395 primary_if->net_dev->dev_addr, 1396 ethhdr->h_source, vid); 1397 goto allow; 1398 } 1399 1400 /* if it is our own claim ... */ 1401 if (compare_eth(claim->backbone_gw->orig, 1402 primary_if->net_dev->dev_addr)) { 1403 /* ... allow it in any case */ 1404 claim->lasttime = jiffies; 1405 goto allow; 1406 } 1407 1408 /* if it is a broadcast ... */ 1409 if (is_multicast_ether_addr(ethhdr->h_dest)) { 1410 /* ... drop it. the responsible gateway is in charge. */ 1411 goto handled; 1412 } else { 1413 /* seems the client considers us as its best gateway. 1414 * send a claim and update the claim table 1415 * immediately. 1416 */ 1417 handle_claim(bat_priv, primary_if, 1418 primary_if->net_dev->dev_addr, 1419 ethhdr->h_source, vid); 1420 goto allow; 1421 } 1422 allow: 1423 bla_update_own_backbone_gw(bat_priv, primary_if, vid); 1424 ret = 0; 1425 goto out; 1426 1427 handled: 1428 kfree_skb(skb); 1429 ret = 1; 1430 1431 out: 1432 if (primary_if) 1433 hardif_free_ref(primary_if); 1434 if (claim) 1435 claim_free_ref(claim); 1436 return ret; 1437 } 1438 1439 /** 1440 * @bat_priv: the bat priv with all the soft interface information 1441 * @skb: the frame to be checked 1442 * @vid: the VLAN ID of the frame 1443 * 1444 * bla_tx checks if: 1445 * * a claim was received which has to be processed 1446 * * the frame is allowed on the mesh 1447 * 1448 * in these cases, the skb is further handled by this function and 1449 * returns 1, otherwise it returns 0 and the caller shall further 1450 * process the skb. 1451 * 1452 */ 1453 int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) 1454 { 1455 struct ethhdr *ethhdr; 1456 struct claim search_claim, *claim = NULL; 1457 struct hard_iface *primary_if; 1458 int ret = 0; 1459 1460 primary_if = primary_if_get_selected(bat_priv); 1461 if (!primary_if) 1462 goto out; 1463 1464 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1465 goto allow; 1466 1467 /* in VLAN case, the mac header might not be set. */ 1468 skb_reset_mac_header(skb); 1469 1470 if (bla_process_claim(bat_priv, primary_if, skb)) 1471 goto handled; 1472 1473 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1474 1475 if (unlikely(atomic_read(&bat_priv->bla_num_requests))) 1476 /* don't allow broadcasts while requests are in flight */ 1477 if (is_multicast_ether_addr(ethhdr->h_dest)) 1478 goto handled; 1479 1480 memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); 1481 search_claim.vid = vid; 1482 1483 claim = claim_hash_find(bat_priv, &search_claim); 1484 1485 /* if no claim exists, allow it. */ 1486 if (!claim) 1487 goto allow; 1488 1489 /* check if we are responsible. */ 1490 if (compare_eth(claim->backbone_gw->orig, 1491 primary_if->net_dev->dev_addr)) { 1492 /* if yes, the client has roamed and we have 1493 * to unclaim it. 1494 */ 1495 handle_unclaim(bat_priv, primary_if, 1496 primary_if->net_dev->dev_addr, 1497 ethhdr->h_source, vid); 1498 goto allow; 1499 } 1500 1501 /* check if it is a multicast/broadcast frame */ 1502 if (is_multicast_ether_addr(ethhdr->h_dest)) { 1503 /* drop it. the responsible gateway has forwarded it into 1504 * the backbone network. 1505 */ 1506 goto handled; 1507 } else { 1508 /* we must allow it. at least if we are 1509 * responsible for the DESTINATION. 1510 */ 1511 goto allow; 1512 } 1513 allow: 1514 bla_update_own_backbone_gw(bat_priv, primary_if, vid); 1515 ret = 0; 1516 goto out; 1517 handled: 1518 ret = 1; 1519 out: 1520 if (primary_if) 1521 hardif_free_ref(primary_if); 1522 if (claim) 1523 claim_free_ref(claim); 1524 return ret; 1525 } 1526 1527 int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) 1528 { 1529 struct net_device *net_dev = (struct net_device *)seq->private; 1530 struct bat_priv *bat_priv = netdev_priv(net_dev); 1531 struct hashtable_t *hash = bat_priv->claim_hash; 1532 struct claim *claim; 1533 struct hard_iface *primary_if; 1534 struct hlist_node *node; 1535 struct hlist_head *head; 1536 uint32_t i; 1537 bool is_own; 1538 int ret = 0; 1539 1540 primary_if = primary_if_get_selected(bat_priv); 1541 if (!primary_if) { 1542 ret = seq_printf(seq, 1543 "BATMAN mesh %s disabled - please specify interfaces to enable it\n", 1544 net_dev->name); 1545 goto out; 1546 } 1547 1548 if (primary_if->if_status != IF_ACTIVE) { 1549 ret = seq_printf(seq, 1550 "BATMAN mesh %s disabled - primary interface not active\n", 1551 net_dev->name); 1552 goto out; 1553 } 1554 1555 seq_printf(seq, 1556 "Claims announced for the mesh %s (orig %pM, group id %04x)\n", 1557 net_dev->name, primary_if->net_dev->dev_addr, 1558 ntohs(bat_priv->claim_dest.group)); 1559 seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", 1560 "Client", "VID", "Originator", "CRC"); 1561 for (i = 0; i < hash->size; i++) { 1562 head = &hash->table[i]; 1563 1564 rcu_read_lock(); 1565 hlist_for_each_entry_rcu(claim, node, head, hash_entry) { 1566 is_own = compare_eth(claim->backbone_gw->orig, 1567 primary_if->net_dev->dev_addr); 1568 seq_printf(seq, " * %pM on % 5d by %pM [%c] (%04x)\n", 1569 claim->addr, claim->vid, 1570 claim->backbone_gw->orig, 1571 (is_own ? 'x' : ' '), 1572 claim->backbone_gw->crc); 1573 } 1574 rcu_read_unlock(); 1575 } 1576 out: 1577 if (primary_if) 1578 hardif_free_ref(primary_if); 1579 return ret; 1580 } 1581