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