~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/mac80211/mesh_plink.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44
44
 
45
45
enum plink_frame_type {
46
 
        PLINK_OPEN = 0,
 
46
        PLINK_OPEN = 1,
47
47
        PLINK_CONFIRM,
48
48
        PLINK_CLOSE
49
49
};
83
83
 */
84
84
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
85
85
{
86
 
        sta->plink_state = PLINK_LISTEN;
 
86
        sta->plink_state = NL80211_PLINK_LISTEN;
87
87
        sta->llid = sta->plid = sta->reason = 0;
88
88
        sta->plink_retries = 0;
89
89
}
105
105
        if (!sta)
106
106
                return NULL;
107
107
 
108
 
        sta->flags = WLAN_STA_AUTHORIZED;
 
108
        sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH;
109
109
        sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
110
110
        rate_control_rate_init(sta);
111
111
 
126
126
        struct ieee80211_sub_if_data *sdata = sta->sdata;
127
127
        bool deactivated = false;
128
128
 
129
 
        if (sta->plink_state == PLINK_ESTAB) {
 
129
        if (sta->plink_state == NL80211_PLINK_ESTAB) {
130
130
                mesh_plink_dec_estab_count(sdata);
131
131
                deactivated = true;
132
132
        }
133
 
        sta->plink_state = PLINK_BLOCKED;
 
133
        sta->plink_state = NL80211_PLINK_BLOCKED;
134
134
        mesh_path_flush_by_nexthop(sta);
135
135
 
136
136
        return deactivated;
161
161
                __le16 reason) {
162
162
        struct ieee80211_local *local = sdata->local;
163
163
        struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164
 
                        sdata->u.mesh.vendor_ie_len);
 
164
                        sdata->u.mesh.ie_len);
165
165
        struct ieee80211_mgmt *mgmt;
166
166
        bool include_plid = false;
167
167
        static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
181
181
                                          IEEE80211_STYPE_ACTION);
182
182
        memcpy(mgmt->da, da, ETH_ALEN);
183
183
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
184
 
        /* BSSID is left zeroed, wildcard value */
185
 
        mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK;
 
184
        memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 
185
        mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
186
186
        mgmt->u.action.u.plink_action.action_code = action;
187
187
 
188
188
        if (action == PLINK_CLOSE)
237
237
        return 0;
238
238
}
239
239
 
240
 
void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata,
241
 
                           bool peer_accepting_plinks)
 
240
void mesh_neighbour_update(u8 *hw_addr, u32 rates,
 
241
                struct ieee80211_sub_if_data *sdata,
 
242
                struct ieee802_11_elems *elems)
242
243
{
243
244
        struct ieee80211_local *local = sdata->local;
244
245
        struct sta_info *sta;
248
249
        sta = sta_info_get(sdata, hw_addr);
249
250
        if (!sta) {
250
251
                rcu_read_unlock();
251
 
 
252
 
                sta = mesh_plink_alloc(sdata, hw_addr, rates);
 
252
                /* Userspace handles peer allocation when security is enabled
 
253
                 * */
 
254
                if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
 
255
                        cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
 
256
                                        elems->ie_start, elems->total_len,
 
257
                                        GFP_KERNEL);
 
258
                else
 
259
                        sta = mesh_plink_alloc(sdata, hw_addr, rates);
253
260
                if (!sta)
254
261
                        return;
255
262
                if (sta_info_insert_rcu(sta)) {
260
267
 
261
268
        sta->last_rx = jiffies;
262
269
        sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
263
 
        if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN &&
 
270
        if (mesh_peer_accepts_plinks(elems) &&
 
271
                        sta->plink_state == NL80211_PLINK_LISTEN &&
264
272
                        sdata->u.mesh.accepting_plinks &&
265
273
                        sdata->u.mesh.mshcfg.auto_open_plinks)
266
274
                mesh_plink_open(sta);
300
308
        sdata = sta->sdata;
301
309
 
302
310
        switch (sta->plink_state) {
303
 
        case PLINK_OPN_RCVD:
304
 
        case PLINK_OPN_SNT:
 
311
        case NL80211_PLINK_OPN_RCVD:
 
312
        case NL80211_PLINK_OPN_SNT:
305
313
                /* retry timer */
306
314
                if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
307
315
                        u32 rand;
320
328
                }
321
329
                reason = cpu_to_le16(MESH_MAX_RETRIES);
322
330
                /* fall through on else */
323
 
        case PLINK_CNF_RCVD:
 
331
        case NL80211_PLINK_CNF_RCVD:
324
332
                /* confirm timer */
325
333
                if (!reason)
326
334
                        reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
327
 
                sta->plink_state = PLINK_HOLDING;
 
335
                sta->plink_state = NL80211_PLINK_HOLDING;
328
336
                mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
329
337
                spin_unlock_bh(&sta->lock);
330
338
                mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
331
339
                                    reason);
332
340
                break;
333
 
        case PLINK_HOLDING:
 
341
        case NL80211_PLINK_HOLDING:
334
342
                /* holding timer */
335
343
                del_timer(&sta->plink_timer);
336
344
                mesh_plink_fsm_restart(sta);
372
380
        __le16 llid;
373
381
        struct ieee80211_sub_if_data *sdata = sta->sdata;
374
382
 
 
383
        if (!test_sta_flags(sta, WLAN_STA_AUTH))
 
384
                return -EPERM;
 
385
 
375
386
        spin_lock_bh(&sta->lock);
376
387
        get_random_bytes(&llid, 2);
377
388
        sta->llid = llid;
378
 
        if (sta->plink_state != PLINK_LISTEN) {
 
389
        if (sta->plink_state != NL80211_PLINK_LISTEN) {
379
390
                spin_unlock_bh(&sta->lock);
380
391
                return -EBUSY;
381
392
        }
382
 
        sta->plink_state = PLINK_OPN_SNT;
 
393
        sta->plink_state = NL80211_PLINK_OPN_SNT;
383
394
        mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
384
395
        spin_unlock_bh(&sta->lock);
385
396
        mpl_dbg("Mesh plink: starting establishment with %pM\n",
396
407
 
397
408
        spin_lock_bh(&sta->lock);
398
409
        deactivated = __mesh_plink_deactivate(sta);
399
 
        sta->plink_state = PLINK_BLOCKED;
 
410
        sta->plink_state = NL80211_PLINK_BLOCKED;
400
411
        spin_unlock_bh(&sta->lock);
401
412
 
402
413
        if (deactivated)
419
430
        __le16 plid, llid, reason;
420
431
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
421
432
        static const char *mplstates[] = {
422
 
                [PLINK_LISTEN] = "LISTEN",
423
 
                [PLINK_OPN_SNT] = "OPN-SNT",
424
 
                [PLINK_OPN_RCVD] = "OPN-RCVD",
425
 
                [PLINK_CNF_RCVD] = "CNF_RCVD",
426
 
                [PLINK_ESTAB] = "ESTAB",
427
 
                [PLINK_HOLDING] = "HOLDING",
428
 
                [PLINK_BLOCKED] = "BLOCKED"
 
433
                [NL80211_PLINK_LISTEN] = "LISTEN",
 
434
                [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
 
435
                [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
 
436
                [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
 
437
                [NL80211_PLINK_ESTAB] = "ESTAB",
 
438
                [NL80211_PLINK_HOLDING] = "HOLDING",
 
439
                [NL80211_PLINK_BLOCKED] = "BLOCKED"
429
440
        };
430
441
#endif
431
442
 
449
460
                mpl_dbg("Mesh plink: missing necessary peer link ie\n");
450
461
                return;
451
462
        }
 
463
        if (elems.rsn_len &&
 
464
                        sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
 
465
                mpl_dbg("Mesh plink: can't establish link with secure peer\n");
 
466
                return;
 
467
        }
452
468
 
453
469
        ftype = mgmt->u.action.u.plink_action.action_code;
454
470
        ie_len = elems.peer_link_len;
480
496
                return;
481
497
        }
482
498
 
483
 
        if (sta && sta->plink_state == PLINK_BLOCKED) {
 
499
        if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) {
 
500
                mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
 
501
                rcu_read_unlock();
 
502
                return;
 
503
        }
 
504
 
 
505
        if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
484
506
                rcu_read_unlock();
485
507
                return;
486
508
        }
550
572
                                event = CNF_ACPT;
551
573
                        break;
552
574
                case PLINK_CLOSE:
553
 
                        if (sta->plink_state == PLINK_ESTAB)
 
575
                        if (sta->plink_state == NL80211_PLINK_ESTAB)
554
576
                                /* Do not check for llid or plid. This does not
555
577
                                 * follow the standard but since multiple plinks
556
578
                                 * per sta are not supported, it is necessary in
585
607
        reason = 0;
586
608
        switch (sta->plink_state) {
587
609
                /* spin_unlock as soon as state is updated at each case */
588
 
        case PLINK_LISTEN:
 
610
        case NL80211_PLINK_LISTEN:
589
611
                switch (event) {
590
612
                case CLS_ACPT:
591
613
                        mesh_plink_fsm_restart(sta);
592
614
                        spin_unlock_bh(&sta->lock);
593
615
                        break;
594
616
                case OPN_ACPT:
595
 
                        sta->plink_state = PLINK_OPN_RCVD;
 
617
                        sta->plink_state = NL80211_PLINK_OPN_RCVD;
596
618
                        sta->plid = plid;
597
619
                        get_random_bytes(&llid, 2);
598
620
                        sta->llid = llid;
609
631
                }
610
632
                break;
611
633
 
612
 
        case PLINK_OPN_SNT:
 
634
        case NL80211_PLINK_OPN_SNT:
613
635
                switch (event) {
614
636
                case OPN_RJCT:
615
637
                case CNF_RJCT:
618
640
                        if (!reason)
619
641
                                reason = cpu_to_le16(MESH_CLOSE_RCVD);
620
642
                        sta->reason = reason;
621
 
                        sta->plink_state = PLINK_HOLDING;
 
643
                        sta->plink_state = NL80211_PLINK_HOLDING;
622
644
                        if (!mod_plink_timer(sta,
623
645
                                             dot11MeshHoldingTimeout(sdata)))
624
646
                                sta->ignore_plink_timer = true;
630
652
                        break;
631
653
                case OPN_ACPT:
632
654
                        /* retry timer is left untouched */
633
 
                        sta->plink_state = PLINK_OPN_RCVD;
 
655
                        sta->plink_state = NL80211_PLINK_OPN_RCVD;
634
656
                        sta->plid = plid;
635
657
                        llid = sta->llid;
636
658
                        spin_unlock_bh(&sta->lock);
638
660
                                            plid, 0);
639
661
                        break;
640
662
                case CNF_ACPT:
641
 
                        sta->plink_state = PLINK_CNF_RCVD;
 
663
                        sta->plink_state = NL80211_PLINK_CNF_RCVD;
642
664
                        if (!mod_plink_timer(sta,
643
665
                                             dot11MeshConfirmTimeout(sdata)))
644
666
                                sta->ignore_plink_timer = true;
651
673
                }
652
674
                break;
653
675
 
654
 
        case PLINK_OPN_RCVD:
 
676
        case NL80211_PLINK_OPN_RCVD:
655
677
                switch (event) {
656
678
                case OPN_RJCT:
657
679
                case CNF_RJCT:
660
682
                        if (!reason)
661
683
                                reason = cpu_to_le16(MESH_CLOSE_RCVD);
662
684
                        sta->reason = reason;
663
 
                        sta->plink_state = PLINK_HOLDING;
 
685
                        sta->plink_state = NL80211_PLINK_HOLDING;
664
686
                        if (!mod_plink_timer(sta,
665
687
                                             dot11MeshHoldingTimeout(sdata)))
666
688
                                sta->ignore_plink_timer = true;
678
700
                        break;
679
701
                case CNF_ACPT:
680
702
                        del_timer(&sta->plink_timer);
681
 
                        sta->plink_state = PLINK_ESTAB;
 
703
                        sta->plink_state = NL80211_PLINK_ESTAB;
682
704
                        spin_unlock_bh(&sta->lock);
683
705
                        mesh_plink_inc_estab_count(sdata);
684
706
                        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
691
713
                }
692
714
                break;
693
715
 
694
 
        case PLINK_CNF_RCVD:
 
716
        case NL80211_PLINK_CNF_RCVD:
695
717
                switch (event) {
696
718
                case OPN_RJCT:
697
719
                case CNF_RJCT:
700
722
                        if (!reason)
701
723
                                reason = cpu_to_le16(MESH_CLOSE_RCVD);
702
724
                        sta->reason = reason;
703
 
                        sta->plink_state = PLINK_HOLDING;
 
725
                        sta->plink_state = NL80211_PLINK_HOLDING;
704
726
                        if (!mod_plink_timer(sta,
705
727
                                             dot11MeshHoldingTimeout(sdata)))
706
728
                                sta->ignore_plink_timer = true;
712
734
                        break;
713
735
                case OPN_ACPT:
714
736
                        del_timer(&sta->plink_timer);
715
 
                        sta->plink_state = PLINK_ESTAB;
 
737
                        sta->plink_state = NL80211_PLINK_ESTAB;
716
738
                        spin_unlock_bh(&sta->lock);
717
739
                        mesh_plink_inc_estab_count(sdata);
718
740
                        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
727
749
                }
728
750
                break;
729
751
 
730
 
        case PLINK_ESTAB:
 
752
        case NL80211_PLINK_ESTAB:
731
753
                switch (event) {
732
754
                case CLS_ACPT:
733
755
                        reason = cpu_to_le16(MESH_CLOSE_RCVD);
734
756
                        sta->reason = reason;
735
757
                        deactivated = __mesh_plink_deactivate(sta);
736
 
                        sta->plink_state = PLINK_HOLDING;
 
758
                        sta->plink_state = NL80211_PLINK_HOLDING;
737
759
                        llid = sta->llid;
738
760
                        mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
739
761
                        spin_unlock_bh(&sta->lock);
753
775
                        break;
754
776
                }
755
777
                break;
756
 
        case PLINK_HOLDING:
 
778
        case NL80211_PLINK_HOLDING:
757
779
                switch (event) {
758
780
                case CLS_ACPT:
759
781
                        if (del_timer(&sta->plink_timer))