OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008, 2009 open80211s Ltd. | 2 * Copyright (c) 2008, 2009 open80211s Ltd. |
3 * Author: Luis Carlos Cobo <luisca@cozybit.com> | 3 * Author: Luis Carlos Cobo <luisca@cozybit.com> |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 */ | 8 */ |
9 #include <linux/gfp.h> | 9 #include <linux/gfp.h> |
10 #include <linux/kernel.h> | 10 #include <linux/kernel.h> |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 405 |
406 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
gmt *mgmt, | 406 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
gmt *mgmt, |
407 size_t len, struct ieee80211_rx_status *rx_status) | 407 size_t len, struct ieee80211_rx_status *rx_status) |
408 { | 408 { |
409 struct ieee80211_local *local = sdata->local; | 409 struct ieee80211_local *local = sdata->local; |
410 struct ieee802_11_elems elems; | 410 struct ieee802_11_elems elems; |
411 struct sta_info *sta; | 411 struct sta_info *sta; |
412 enum plink_event event; | 412 enum plink_event event; |
413 enum plink_frame_type ftype; | 413 enum plink_frame_type ftype; |
414 size_t baselen; | 414 size_t baselen; |
415 » bool deactivated; | 415 » bool deactivated, matches_local = true; |
416 u8 ie_len; | 416 u8 ie_len; |
417 u8 *baseaddr; | 417 u8 *baseaddr; |
418 __le16 plid, llid, reason; | 418 __le16 plid, llid, reason; |
419 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | 419 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG |
420 static const char *mplstates[] = { | 420 static const char *mplstates[] = { |
421 [PLINK_LISTEN] = "LISTEN", | 421 [PLINK_LISTEN] = "LISTEN", |
422 [PLINK_OPN_SNT] = "OPN-SNT", | 422 [PLINK_OPN_SNT] = "OPN-SNT", |
423 [PLINK_OPN_RCVD] = "OPN-RCVD", | 423 [PLINK_OPN_RCVD] = "OPN-RCVD", |
424 [PLINK_CNF_RCVD] = "CNF_RCVD", | 424 [PLINK_CNF_RCVD] = "CNF_RCVD", |
425 [PLINK_ESTAB] = "ESTAB", | 425 [PLINK_ESTAB] = "ESTAB", |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 } | 480 } |
481 | 481 |
482 if (sta && sta->plink_state == PLINK_BLOCKED) { | 482 if (sta && sta->plink_state == PLINK_BLOCKED) { |
483 rcu_read_unlock(); | 483 rcu_read_unlock(); |
484 return; | 484 return; |
485 } | 485 } |
486 | 486 |
487 /* Now we will figure out the appropriate event... */ | 487 /* Now we will figure out the appropriate event... */ |
488 event = PLINK_UNDEFINED; | 488 event = PLINK_UNDEFINED; |
489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { | 489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { |
| 490 matches_local = false; |
490 switch (ftype) { | 491 switch (ftype) { |
491 case PLINK_OPEN: | 492 case PLINK_OPEN: |
492 event = OPN_RJCT; | 493 event = OPN_RJCT; |
493 break; | 494 break; |
494 case PLINK_CONFIRM: | 495 case PLINK_CONFIRM: |
495 event = CNF_RJCT; | 496 event = CNF_RJCT; |
496 break; | 497 break; |
497 case PLINK_CLOSE: | 498 case PLINK_CLOSE: |
498 /* avoid warning */ | 499 /* avoid warning */ |
499 break; | 500 break; |
500 } | 501 } |
501 » » spin_lock_bh(&sta->lock); | 502 » } |
| 503 |
| 504 » if (!sta && !matches_local) { |
| 505 » » rcu_read_unlock(); |
| 506 » » reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); |
| 507 » » llid = 0; |
| 508 » » mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, |
| 509 » » » » plid, reason); |
| 510 » » return; |
502 } else if (!sta) { | 511 } else if (!sta) { |
503 /* ftype == PLINK_OPEN */ | 512 /* ftype == PLINK_OPEN */ |
504 u32 rates; | 513 u32 rates; |
505 | 514 |
506 rcu_read_unlock(); | 515 rcu_read_unlock(); |
507 | 516 |
508 if (!mesh_plink_free_count(sdata)) { | 517 if (!mesh_plink_free_count(sdata)) { |
509 mpl_dbg("Mesh plink error: no more free plinks\n"); | 518 mpl_dbg("Mesh plink error: no more free plinks\n"); |
510 return; | 519 return; |
511 } | 520 } |
512 | 521 |
513 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); | 522 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); |
514 sta = mesh_plink_alloc(sdata, mgmt->sa, rates); | 523 sta = mesh_plink_alloc(sdata, mgmt->sa, rates); |
515 if (!sta) { | 524 if (!sta) { |
516 mpl_dbg("Mesh plink error: plink table full\n"); | 525 mpl_dbg("Mesh plink error: plink table full\n"); |
517 return; | 526 return; |
518 } | 527 } |
519 if (sta_info_insert_rcu(sta)) { | 528 if (sta_info_insert_rcu(sta)) { |
520 rcu_read_unlock(); | 529 rcu_read_unlock(); |
521 return; | 530 return; |
522 } | 531 } |
523 event = OPN_ACPT; | 532 event = OPN_ACPT; |
524 spin_lock_bh(&sta->lock); | 533 spin_lock_bh(&sta->lock); |
525 » } else { | 534 » } else if (matches_local) { |
526 spin_lock_bh(&sta->lock); | 535 spin_lock_bh(&sta->lock); |
527 switch (ftype) { | 536 switch (ftype) { |
528 case PLINK_OPEN: | 537 case PLINK_OPEN: |
529 if (!mesh_plink_free_count(sdata) || | 538 if (!mesh_plink_free_count(sdata) || |
530 (sta->plid && sta->plid != plid)) | 539 (sta->plid && sta->plid != plid)) |
531 event = OPN_IGNR; | 540 event = OPN_IGNR; |
532 else | 541 else |
533 event = OPN_ACPT; | 542 event = OPN_ACPT; |
534 break; | 543 break; |
535 case PLINK_CONFIRM: | 544 case PLINK_CONFIRM: |
(...skipping 21 matching lines...) Expand all Loading... |
557 event = CLS_IGNR; | 566 event = CLS_IGNR; |
558 else | 567 else |
559 event = CLS_ACPT; | 568 event = CLS_ACPT; |
560 break; | 569 break; |
561 default: | 570 default: |
562 mpl_dbg("Mesh plink: unknown frame subtype\n"); | 571 mpl_dbg("Mesh plink: unknown frame subtype\n"); |
563 spin_unlock_bh(&sta->lock); | 572 spin_unlock_bh(&sta->lock); |
564 rcu_read_unlock(); | 573 rcu_read_unlock(); |
565 return; | 574 return; |
566 } | 575 } |
| 576 } else { |
| 577 spin_lock_bh(&sta->lock); |
567 } | 578 } |
568 | 579 |
569 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n"
, | 580 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n"
, |
570 mgmt->sa, mplstates[sta->plink_state], | 581 mgmt->sa, mplstates[sta->plink_state], |
571 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), | 582 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), |
572 event); | 583 event); |
573 reason = 0; | 584 reason = 0; |
574 switch (sta->plink_state) { | 585 switch (sta->plink_state) { |
575 /* spin_unlock as soon as state is updated at each case */ | 586 /* spin_unlock as soon as state is updated at each case */ |
576 case PLINK_LISTEN: | 587 case PLINK_LISTEN: |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 default: | 777 default: |
767 /* should not get here, PLINK_BLOCKED is dealt with at the | 778 /* should not get here, PLINK_BLOCKED is dealt with at the |
768 * beginning of the function | 779 * beginning of the function |
769 */ | 780 */ |
770 spin_unlock_bh(&sta->lock); | 781 spin_unlock_bh(&sta->lock); |
771 break; | 782 break; |
772 } | 783 } |
773 | 784 |
774 rcu_read_unlock(); | 785 rcu_read_unlock(); |
775 } | 786 } |
OLD | NEW |