Ticket #907: madwifi-refcnt.9.diff
| File madwifi-refcnt.9.diff, 78.0 kB (added by mentor, 5 years ago) |
|---|
-
net80211/ieee80211_node.c
old new 65 65 #define IEEE80211_AID_ISSET(_vap, _b) \ 66 66 ((_vap)->iv_aid_bitmap[IEEE80211_AID(_b) / 32] & (1 << (IEEE80211_AID(_b) % 32))) 67 67 68 static struct ieee80211_node *ieee80211_alloc_node(struct ieee80211vap *, const u_int8_t *); 69 68 70 static int ieee80211_sta_join1(struct ieee80211_node *); 69 71 70 static struct ieee80211_node *node_alloc(struct ieee80211_node_table *, 71 struct ieee80211vap *); 72 static struct ieee80211_node *node_alloc(struct ieee80211vap *); 72 73 static void node_cleanup(struct ieee80211_node *); 73 74 static void node_free(struct ieee80211_node *); 74 75 static u_int8_t node_getrssi(const struct ieee80211_node *); 75 76 76 static void _ ieee80211_free_node(struct ieee80211_node *);77 static void node_reclaim(struct ieee80211_node_table *, struct ieee80211_node*);77 static void _node_table_leave(struct ieee80211_node_table *, struct ieee80211_node *); 78 static void _node_table_join(struct ieee80211_node_table *, struct ieee80211_node *); 78 79 79 80 static void ieee80211_node_timeout(unsigned long); 80 81 … … 194 195 195 196 ieee80211_node_table_reset(&ic->ic_sta, vap); 196 197 if (vap->iv_bss != NULL) { 197 ieee80211_free_node(vap->iv_bss); 198 vap->iv_bss = NULL; 198 ieee80211_unref_node(&vap->iv_bss); 199 199 } 200 200 if (vap->iv_aid_bitmap != NULL) { 201 201 FREE(vap->iv_aid_bitmap, M_DEVBUF); … … 263 263 "%s: creating ibss on channel %u\n", __func__, 264 264 ieee80211_chan2ieee(ic, chan)); 265 265 266 /* Check to see if we already have a node for this mac */ 266 /* Check to see if we already have a node for this mac 267 * NB: we gain a node reference here 268 */ 267 269 ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr); 268 270 if (ni == NULL) { 269 ni = ieee80211_alloc_node (&ic->ic_sta,vap, vap->iv_myaddr);271 ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr); 270 272 if (ni == NULL) { 271 273 /* XXX recovery? */ 272 274 return; 273 275 } 274 276 } 275 else276 ieee80211_free_node(ni);277 277 278 278 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: %p<%s> refcnt %d\n", 279 279 __func__, vap->iv_bss, ether_sprintf(vap->iv_bss->ni_macaddr), … … 345 345 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 346 346 ni->ni_rates = ic->ic_sup_quarter_rates; 347 347 348 (void) ieee80211_sta_join1( ieee80211_ref_node(ni));348 (void) ieee80211_sta_join1(PASS_NODE(ni)); 349 349 } 350 350 EXPORT_SYMBOL(ieee80211_create_ibss); 351 351 … … 369 369 /* XXX multi-bss wrong */ 370 370 ieee80211_reset_erp(ic, ic->ic_curmode); 371 371 372 ni = ieee80211_alloc_node (&ic->ic_sta,vap, vap->iv_myaddr);372 ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr); 373 373 KASSERT(ni != NULL, ("unable to setup inital BSS node")); 374 374 obss = vap->iv_bss; 375 // Caller's reference 375 376 vap->iv_bss = ieee80211_ref_node(ni); 376 377 377 378 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: new bss %p<%s> refcnt %d\n", … … 381 382 if (obss != NULL) { 382 383 copy_bss(ni, obss); 383 384 ni->ni_intval = ic->ic_lintval; 384 ieee80211_free_node(obss); 385 // Caller's reference 386 ieee80211_unref_node(&obss); 385 387 } 386 388 } 387 389 … … 587 589 vap->iv_state == IEEE80211_S_RUN && ssid_equal(obss, selbs)); 588 590 vap->iv_bss = selbs; 589 591 if (obss != NULL) 590 ieee80211_ free_node(obss);592 ieee80211_unref_node(&obss); 591 593 ic->ic_bsschan = selbs->ni_chan; 592 594 ic->ic_curchan = ic->ic_bsschan; 593 595 ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); … … 644 646 645 647 ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr); 646 648 if (ni == NULL) { 647 ni = ieee80211_alloc_node (&ic->ic_sta,vap, se->se_macaddr);649 ni = ieee80211_alloc_node_table(vap, se->se_macaddr); 648 650 if (ni == NULL) { 649 651 /* XXX msg */ 650 652 return 0; 651 653 } 652 } else 653 ieee80211_free_node(ni); 654 } 654 655 655 656 /* 656 657 * Expand scan state into node's format. 657 658 * XXX may not need all this stuff 658 659 */ 659 ni->ni_authmode = vap->iv_bss->ni_authmode; /* inherit authmode from iv_bss */660 ni->ni_authmode = vap->iv_bss->ni_authmode; /* inherit authmode from iv_bss */ 660 661 /* inherit the WPA setup as well (structure copy!) */ 661 662 ni->ni_rsn = vap->iv_bss->ni_rsn; 662 663 IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid); … … 690 691 691 692 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 692 693 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr), 693 ieee80211_node_refcnt(ni) +1);694 ieee80211_node_refcnt(ni)); 694 695 695 return ieee80211_sta_join1( ieee80211_ref_node(ni));696 return ieee80211_sta_join1(PASS_NODE(ni)); 696 697 } 697 698 EXPORT_SYMBOL(ieee80211_sta_join); 698 699 … … 704 705 ieee80211_sta_leave(struct ieee80211_node *ni) 705 706 { 706 707 struct ieee80211vap *vap = ni->ni_vap; 707 struct ieee80211com *ic = vap->iv_ic;708 708 709 709 /* WDS/Repeater: Stop software beacon timer for STA */ 710 710 if (vap->iv_opmode == IEEE80211_M_STA && 711 711 vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) { 712 712 del_timer(&vap->iv_swbmiss); 713 713 } 714 715 ic->ic_node_cleanup(ni); 714 716 715 ieee80211_notify_node_leave(ni); 717 716 } 718 717 … … 721 720 */ 722 721 723 722 static void 724 ieee80211_node_table_init(struct ieee80211com *ic, 725 struct ieee80211_node_table *nt,const char *name, int inact)723 ieee80211_node_table_init(struct ieee80211com *ic, struct ieee80211_node_table *nt, 724 const char *name, int inact) 726 725 { 727 726 nt->nt_ic = ic; 728 IEEE80211_NODE_ LOCK_INIT(nt, ic->ic_dev->name);727 IEEE80211_NODE_TABLE_LOCK_INIT(nt, ic->ic_dev->name); 729 728 IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_dev->name); 730 729 TAILQ_INIT(&nt->nt_node); 731 730 nt->nt_name = name; … … 737 736 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 738 737 } 739 738 739 static __inline void _node_table_join(struct ieee80211_node_table *nt, struct ieee80211_node *ni) { 740 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 741 742 ni->ni_table = nt; 743 TAILQ_INSERT_TAIL(&nt->nt_node, ieee80211_ref_node(ni), ni_list); 744 LIST_INSERT_HEAD(&nt->nt_hash[IEEE80211_NODE_HASH(ni->ni_macaddr)], ni, ni_hash); 745 } 746 747 static __inline void _node_table_leave(struct ieee80211_node_table *nt, struct ieee80211_node *ni) { 748 struct ieee80211_node *hni; 749 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 750 751 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 752 LIST_FOREACH(hni, &nt->nt_hash[IEEE80211_NODE_HASH(ni->ni_macaddr)], ni_hash) { 753 LIST_REMOVE(ni, ni_hash); 754 } 755 ni->ni_table = NULL; 756 _ieee80211_unref_node(ni); 757 } 758 759 /* This is overridden by ath_node_alloc in ath/if_ath.c, and so 760 * should never get called. 761 */ 740 762 static struct ieee80211_node * 741 node_alloc(struct ieee80211 _node_table *nt, struct ieee80211vap *vap)763 node_alloc(struct ieee80211vap *vap) 742 764 { 743 765 struct ieee80211_node *ni; 744 766 … … 779 801 IEEE80211_UNLOCK_IRQ(ni->ni_ic); 780 802 } 781 803 } 782 /*783 * Clear AREF flag that marks the authorization refcnt bump784 * has happened. This is probably not needed as the node785 * should always be removed from the table so not found but786 * do it just in case.787 */788 ni->ni_flags &= ~IEEE80211_NODE_AREF;789 804 790 805 /* 791 806 * Drain power save queue and, if needed, clear TIM. … … 794 809 vap->iv_set_tim(ni, 0); 795 810 796 811 ni->ni_associd = 0; 797 if (ni->ni_challenge != NULL) { 798 FREE(ni->ni_challenge, M_DEVBUF); 799 ni->ni_challenge = NULL; 800 } 812 801 813 /* 802 814 * Preserve SSID, WPA, and WME ie's so the bss node is 803 815 * reusable during a re-auth/re-assoc state transition. … … 823 835 static void 824 836 node_free(struct ieee80211_node *ni) 825 837 { 838 #if 0 839 // We should 'cleanup' and then free'ing should be done automatically on decref 826 840 struct ieee80211com *ic = ni->ni_ic; 827 841 828 842 ic->ic_node_cleanup(ni); 843 #endif 844 KASSERT(ieee80211_node_refcnt(ni) == 0, ("node being free whilst still referenced")); 845 846 if (ni->ni_challenge != NULL) 847 FREE(ni->ni_challenge, M_DEVBUF); 829 848 if (ni->ni_wpa_ie != NULL) 830 849 FREE(ni->ni_wpa_ie, M_DEVBUF); 831 850 if (ni->ni_rsn_ie != NULL) … … 835 854 if (ni->ni_ath_ie != NULL) 836 855 FREE(ni->ni_ath_ie, M_DEVBUF); 837 856 IEEE80211_NODE_SAVEQ_DESTROY(ni); 857 838 858 FREE(ni, M_80211_NODE); 839 859 } 840 860 … … 851 871 * This interface is not intended for general use, it is 852 872 * used by the routines below to create entries with a 853 873 * specific purpose. 874 * Dont assume a BSS? 854 875 */ 855 876 struct ieee80211_node * 856 ieee80211_alloc_node (struct ieee80211_node_table *nt,857 struct ieee80211vap *vap,const u_int8_t *macaddr)877 ieee80211_alloc_node_table(struct ieee80211vap *vap, 878 const u_int8_t *macaddr) 858 879 { 859 struct ieee80211com *ic = nt->nt_ic; 880 struct ieee80211com *ic = vap->iv_ic; 881 struct ieee80211_node_table *nt = &ic->ic_sta; 860 882 struct ieee80211_node *ni; 861 int hash;862 int i;863 883 864 ni = ic->ic_node_alloc(nt, vap); 865 if (ni == NULL) { 866 /* XXX msg */ 867 vap->iv_stats.is_rx_nodealloc++; 868 return NULL; 869 } 884 ni = ieee80211_alloc_node(vap, macaddr); 885 if (ni != NULL) { 886 ni->ni_inact = ni->ni_inact_reload = nt->nt_inact_init; 870 887 871 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 872 "%s: %p<%s> in %s table, refcnt %d\n", __func__, ni, 873 ether_sprintf(macaddr), nt->nt_name, 874 ieee80211_node_refcnt(ni)+1); 888 WME_UAPSD_NODE_TRIGSEQINIT(ni); 889 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 875 890 876 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 877 hash = IEEE80211_NODE_HASH(macaddr); 878 ieee80211_node_initref(ni); /* mark referenced */ 879 ni->ni_chan = IEEE80211_CHAN_ANYC; 880 ni->ni_authmode = IEEE80211_AUTH_OPEN; 881 ni->ni_txpower = ic->ic_txpowlimit; /* max power */ 882 ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); 883 ni->ni_inact_reload = nt->nt_inact_init; 884 ni->ni_inact = ni->ni_inact_reload; 885 ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; 886 ni->ni_rxkeyoff = 0; 887 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 891 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 892 _node_table_join(nt, ni); 893 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 894 } 888 895 889 IEEE80211_NODE_LOCK_IRQ(nt); 890 ni->ni_vap = vap; 891 ni->ni_ic = ic; 892 ni->ni_table = nt; 893 TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); 894 LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); 895 #define N(a) (sizeof(a)/sizeof(a[0])) 896 for (i = 0; i < N(ni->ni_rxfrag); i++) 897 ni->ni_rxfrag[i] = NULL; 898 #undef N 899 ni->ni_challenge = NULL; 900 IEEE80211_NODE_UNLOCK_IRQ(nt); 896 return ni; 897 } 898 EXPORT_SYMBOL(ieee80211_alloc_node_table); 901 899 902 WME_UAPSD_NODE_TRIGSEQINIT(ni); 900 /* Allocate a node structure and initialise specialised structures 901 * This function does not add the node to the node table, thus this 902 * node will not be found using ieee80211_find_*node. 903 * This is useful when sending one off errors or request denials. 904 */ 905 static struct ieee80211_node * 906 ieee80211_alloc_node(struct ieee80211vap *vap, const u_int8_t *macaddr) 907 { 908 struct ieee80211com *ic = vap->iv_ic; 909 struct ieee80211_node *ni; 910 911 /* This always allocates zeroed memoery */ 912 ni = ic->ic_node_alloc(vap); 913 if (ni != NULL) { 914 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 915 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr), 916 ieee80211_node_refcnt(ni)+1); 903 917 918 ieee80211_node_initref(ni); /* mark referenced */ 919 920 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 921 922 ni->ni_chan = IEEE80211_CHAN_ANYC; 923 ni->ni_authmode = IEEE80211_AUTH_OPEN; 924 ni->ni_txpower = ic->ic_txpowlimit; 925 926 ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, 927 IEEE80211_KEYIX_NONE); 928 ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; 929 930 ni->ni_vap = vap; 931 ni->ni_ic = ic; 932 } else { 933 /* XXX msg */ 934 vap->iv_stats.is_rx_nodealloc++; 935 } 904 936 return ni; 905 937 } 906 EXPORT_SYMBOL(ieee80211_alloc_node);907 938 908 939 /* Add wds address to the node table */ 909 940 int … … 925 956 wds->wds_agingcount = WDS_AGING_COUNT; 926 957 hash = IEEE80211_NODE_HASH(macaddr); 927 958 IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr); 928 ieee80211_ref_node(ni); /* Reference node */929 wds->wds_ni = ni;930 IEEE80211_NODE_LOCK_IRQ(nt);959 960 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 961 wds->wds_ni = ieee80211_ref_node(ni); 931 962 LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash); 932 IEEE80211_NODE_ UNLOCK_IRQ(nt);963 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 933 964 return 0; 934 965 } 935 966 EXPORT_SYMBOL(ieee80211_add_wds_addr); … … 942 973 struct ieee80211_wds_addr *wds; 943 974 944 975 hash = IEEE80211_NODE_HASH(macaddr); 945 IEEE80211_NODE_ LOCK_IRQ(nt);976 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 946 977 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 947 978 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { 948 if (ieee80211_node_dectestref(wds->wds_ni)) { 949 _ieee80211_free_node(wds->wds_ni); 950 LIST_REMOVE(wds, wds_hash); 951 FREE(wds, M_80211_WDS); 952 break; 953 } 979 LIST_REMOVE(wds, wds_hash); 980 ieee80211_unref_node(&wds->wds_ni); 981 FREE(wds, M_80211_WDS); 982 break; 954 983 } 955 984 } 956 IEEE80211_NODE_ UNLOCK_IRQ(nt);985 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 957 986 } 958 987 EXPORT_SYMBOL(ieee80211_remove_wds_addr); 959 988 … … 965 994 int hash; 966 995 struct ieee80211_wds_addr *wds; 967 996 968 IEEE80211_NODE_ LOCK_IRQ(nt);997 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 969 998 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 970 999 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 971 1000 if (wds->wds_ni == ni) { 972 if (ieee80211_node_dectestref(ni)) { 973 _ieee80211_free_node(ni); 974 LIST_REMOVE(wds, wds_hash); 975 FREE(wds, M_80211_WDS); 976 } 1001 LIST_REMOVE(wds, wds_hash); 1002 ieee80211_unref_node(&wds->wds_ni); 1003 FREE(wds, M_80211_WDS); 977 1004 } 978 1005 } 979 1006 } 980 IEEE80211_NODE_ UNLOCK_IRQ(nt);1007 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 981 1008 } 982 1009 EXPORT_SYMBOL(ieee80211_del_wds_node); 983 1010 … … 988 1015 int hash; 989 1016 struct ieee80211_wds_addr *wds; 990 1017 991 IEEE80211_NODE_ LOCK_IRQ(nt);1018 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 992 1019 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 993 1020 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 994 1021 if (wds->wds_agingcount != WDS_AGING_STATIC) { 995 1022 if (!wds->wds_agingcount) { 996 if (ieee80211_node_dectestref(wds->wds_ni)) { 997 _ieee80211_free_node(wds->wds_ni); 998 LIST_REMOVE(wds, wds_hash); 999 FREE(wds, M_80211_WDS); 1000 } 1023 LIST_REMOVE(wds, wds_hash); 1024 ieee80211_unref_node(&wds->wds_ni); 1025 FREE(wds, M_80211_WDS); 1001 1026 } else 1002 1027 wds->wds_agingcount--; 1003 1028 } 1004 1029 } 1005 1030 } 1006 IEEE80211_NODE_ UNLOCK_IRQ(nt);1031 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1007 1032 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 1008 1033 } 1009 1034 1010 1035 1011 1036 /* 1012 * Craft a temporary node suitable for sending a management frame1013 * to the specified station. We craft only as much state as we1014 * need to do the work since the node will be immediately reclaimed1015 * once the send completes.1016 */1017 struct ieee80211_node *1018 ieee80211_tmp_node(struct ieee80211vap *vap, const u_int8_t *macaddr)1019 {1020 struct ieee80211com *ic = vap->iv_ic;1021 struct ieee80211_node *ni;1022 int i;1023 1024 ni = ic->ic_node_alloc(&ic->ic_sta,vap);1025 if (ni != NULL) {1026 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,1027 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr),1028 ieee80211_node_refcnt(ni)+1);1029 1030 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);1031 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);1032 ieee80211_node_initref(ni); /* mark referenced */1033 ni->ni_txpower = vap->iv_bss->ni_txpower;1034 ni->ni_vap = vap;1035 /* NB: required by ieee80211_fix_rate */1036 ieee80211_node_set_chan(ic, ni);1037 ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,1038 IEEE80211_KEYIX_NONE);1039 /* XXX optimize away */1040 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");1041 1042 ni->ni_table = NULL; /* NB: pedantic */1043 ni->ni_ic = ic;1044 #define N(a) (sizeof(a)/sizeof(a[0]))1045 for (i = 0; i < N(ni->ni_rxfrag); i++)1046 ni->ni_rxfrag[i] = NULL;1047 #undef N1048 ni->ni_challenge = NULL;1049 } else {1050 /* XXX msg */1051 vap->iv_stats.is_rx_nodealloc++;1052 }1053 return ni;1054 }1055 1056 /*1057 1037 * Add the specified station to the station table. 1058 1038 */ 1059 1039 struct ieee80211_node * 1060 ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr) 1040 ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr, 1041 unsigned char tmp) 1061 1042 { 1062 struct ieee80211com *ic = vap->iv_ic;1063 1043 struct ieee80211_node *ni; 1064 int i; 1044 1045 // HACK 1046 if (tmp) 1047 ni = ieee80211_alloc_node(vap, macaddr); 1048 else 1049 ni = ieee80211_alloc_node_table(vap, macaddr); 1065 1050 1066 ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr);1067 1051 if (ni != NULL) { 1068 /* 1069 * Inherit from iv_bss. 1070 */ 1071 ni->ni_authmode = vap->iv_bss->ni_authmode; 1072 ni->ni_txpower = vap->iv_bss->ni_txpower; 1073 ni->ni_vlan = vap->iv_bss->ni_vlan; /* XXX?? */ 1052 copy_bss(ni, vap->iv_bss); 1074 1053 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); 1075 ieee80211_node_set_chan(ic, ni); 1076 ni->ni_rsn = vap->iv_bss->ni_rsn; 1077 #define N(a) (sizeof(a)/sizeof(a[0])) 1078 for (i = 0; i < N(ni->ni_rxfrag); i++) 1079 ni->ni_rxfrag[i] = NULL; 1080 #undef N 1054 /* Do this only for nodes that already have a BSS. Otherwise 1055 * ic_bsschan is not set and we get a KASSERT failure. 1056 * Required by ieee80211_fix_rate */ 1057 ieee80211_node_set_chan(vap->iv_ic, ni); 1081 1058 } 1082 1059 return ni; 1083 1060 } … … 1085 1062 static struct ieee80211_node * 1086 1063 _ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr) 1087 1064 { 1088 struct ieee80211_node *ni;1089 1065 struct ieee80211_wds_addr *wds; 1090 1066 int hash; 1091 IEEE80211_NODE_ LOCK_ASSERT(nt);1067 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 1092 1068 1093 1069 hash = IEEE80211_NODE_HASH(macaddr); 1094 1070 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 1095 1071 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { 1096 ni = wds->wds_ni;1097 1072 if (wds->wds_agingcount != WDS_AGING_STATIC) 1098 1073 wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */ 1099 ieee80211_ref_node(ni); 1100 return ni; 1074 return ieee80211_ref_node(wds->wds_ni); 1101 1075 } 1102 1076 } 1103 1077 return NULL; … … 1115 1089 int hash; 1116 1090 struct ieee80211_wds_addr *wds; 1117 1091 1118 IEEE80211_NODE_ LOCK_ASSERT(nt);1092 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 1119 1093 1120 1094 hash = IEEE80211_NODE_HASH(macaddr); 1121 1095 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { … … 1136 1110 nodes. */ 1137 1111 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 1138 1112 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { 1139 ni = wds->wds_ni; 1140 ieee80211_ref_node(ni); 1141 return ni; 1113 return ieee80211_ref_node(wds->wds_ni); 1142 1114 } 1143 1115 } 1144 1116 return NULL; … … 1153 1125 { 1154 1126 struct ieee80211_node *ni; 1155 1127 1156 IEEE80211_NODE_ LOCK_IRQ(nt);1128 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1157 1129 ni = _ieee80211_find_wds_node(nt, macaddr); 1158 IEEE80211_NODE_ UNLOCK_IRQ(nt);1130 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1159 1131 return ni; 1160 1132 } 1161 1133 EXPORT_SYMBOL(ieee80211_find_wds_node); … … 1170 1142 { 1171 1143 struct ieee80211_node *ni; 1172 1144 1173 IEEE80211_NODE_ LOCK_IRQ(nt);1145 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1174 1146 ni = _ieee80211_find_node(nt, macaddr); 1175 IEEE80211_NODE_ UNLOCK_IRQ(nt);1147 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1176 1148 return ni; 1177 1149 } 1178 1150 #ifdef IEEE80211_DEBUG_REFCNT … … 1195 1167 { 1196 1168 struct ieee80211_node *ni; 1197 1169 1198 ni = ieee80211_dup_bss(vap, macaddr );1170 ni = ieee80211_dup_bss(vap, macaddr, 0); 1199 1171 if (ni != NULL) { 1200 1172 /* XXX no rate negotiation; just dup */ 1201 1173 ni->ni_rates = vap->iv_bss->ni_rates; … … 1218 1190 * driver has an opportunity to setup it's private state. 1219 1191 */ 1220 1192 struct ieee80211_node * 1221 ieee80211_add_neighbor(struct ieee80211vap *vap, const struct ieee80211_frame *wh,1193 ieee80211_add_neighbor(struct ieee80211vap *vap, const struct ieee80211_frame *wh, 1222 1194 const struct ieee80211_scanparams *sp) 1223 1195 { 1224 1196 struct ieee80211com *ic = vap->iv_ic; 1225 1197 struct ieee80211_node *ni; 1226 1198 1227 ni = ieee80211_dup_bss(vap, wh->i_addr2); /* XXX alloc_node? */ 1228 /* TODO: not really putting itself in a table */ 1199 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1); 1229 1200 if (ni != NULL) { 1230 1201 ni->ni_esslen = sp->ssid[1]; 1231 1202 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); … … 1300 1271 /* XXX check ic_bss first in station mode */ 1301 1272 /* XXX 4-address frames? */ 1302 1273 nt = &ic->ic_sta; 1303 IEEE80211_NODE_ LOCK_IRQ(nt);1274 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1304 1275 if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) 1305 1276 ni = _ieee80211_find_node(nt, wh->i_addr1); 1306 1277 else 1307 1278 ni = _ieee80211_find_node(nt, wh->i_addr2); 1308 IEEE80211_NODE_ UNLOCK_IRQ(nt);1279 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1309 1280 1310 1281 return ni; 1311 1282 #undef IS_PSPOLL … … 1342 1313 1343 1314 /* XXX can't hold lock across dup_bss due to recursive locking */ 1344 1315 nt = &vap->iv_ic->ic_sta; 1345 IEEE80211_NODE_ LOCK_IRQ(nt);1316 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1346 1317 ni = _ieee80211_find_node(nt, mac); 1347 IEEE80211_NODE_ UNLOCK_IRQ(nt);1318 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1348 1319 1349 1320 if (ni == NULL) { 1350 1321 if (vap->iv_opmode == IEEE80211_M_IBSS || … … 1371 1342 EXPORT_SYMBOL(ieee80211_find_txnode); 1372 1343 #endif 1373 1344 1374 /* Caller must lock the IEEE80211_NODE_LOCK 1375 * 1376 * Context: hwIRQ, softIRQ and process context 1345 /* Context: hwIRQ, softIRQ and process context 1377 1346 */ 1378 staticvoid1347 void 1379 1348 _ieee80211_free_node(struct ieee80211_node *ni) 1380 1349 { 1381 1350 struct ieee80211vap *vap = ni->ni_vap; … … 1389 1358 1390 1359 if (vap->iv_aid_bitmap != NULL) 1391 1360 IEEE80211_AID_CLR(vap, ni->ni_associd); 1392 if (nt != NULL) { 1393 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 1394 LIST_REMOVE(ni, ni_hash); 1395 } 1361 1396 1362 vap->iv_ic->ic_node_free(ni); 1397 1363 } 1364 EXPORT_SYMBOL(_ieee80211_free_node); 1398 1365 1399 void1400 #ifdef IEEE80211_DEBUG_REFCNT1401 ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line)1402 #else1403 ieee80211_free_node(struct ieee80211_node *ni)1404 #endif1405 {1406 struct ieee80211_node_table *nt = ni->ni_table;1407 struct ieee80211com *ic = ni->ni_ic;1408 1409 #ifdef IEEE80211_DEBUG_REFCNT1410 IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,1411 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni,1412 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1);1413 #endif1414 /*1415 * XXX: may need to lock out the following race. we dectestref1416 * and determine it's time to free the node. between the if()1417 * and lock, we take an rx intr to receive a frame from this1418 * node. the rx path (tasklet or intr) bumps this node's1419 * refcnt and xmits a response frame. eventually that response1420 * will get reaped, and the reaping code will attempt to use1421 * the node. the code below will delete the node prior1422 * to the reap and we could get a crash.1423 *1424 * as a stopgap before delving deeper, lock intrs to1425 * prevent this case.1426 */1427 IEEE80211_LOCK_IRQ(ic);1428 if (ieee80211_node_dectestref(ni)) {1429 /*1430 * Beware; if the node is marked gone then it's already1431 * been removed from the table and we cannot assume the1432 * table still exists. Regardless, there's no need to lock1433 * the table.1434 */1435 if (ni->ni_table != NULL) {1436 IEEE80211_NODE_LOCK(nt);1437 _ieee80211_free_node(ni);1438 IEEE80211_NODE_UNLOCK(nt);1439 } else1440 _ieee80211_free_node(ni);1441 }1442 IEEE80211_UNLOCK_IRQ(ic);1443 }1444 #ifdef IEEE80211_DEBUG_REFCNT1445 EXPORT_SYMBOL(ieee80211_free_node_debug);1446 #else1447 EXPORT_SYMBOL(ieee80211_free_node);1448 #endif1449 1450 /*1451 * Reclaim a node. If this is the last reference count then1452 * do the normal free work. Otherwise remove it from the node1453 * table and mark it gone by clearing the back-reference.1454 */1455 1366 static void 1456 node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)1457 {1458 1459 IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,1460 "%s: remove %p<%s> from %s table, refcnt %d\n",1461 __func__, ni, ether_sprintf(ni->ni_macaddr),1462 nt->nt_name, ieee80211_node_refcnt(ni)-1);1463 if (!ieee80211_node_dectestref(ni)) {1464 /*1465 * Other references are present, just remove the1466 * node from the table so it cannot be found. When1467 * the references are dropped storage will be1468 * reclaimed. This normally only happens for ic_bss.1469 */1470 TAILQ_REMOVE(&nt->nt_node, ni, ni_list);1471 LIST_REMOVE(ni, ni_hash);1472 ni->ni_table = NULL; /* clear reference */1473 } else1474 _ieee80211_free_node(ni);1475 }1476 1477 static void1478 1367 ieee80211_node_table_reset(struct ieee80211_node_table *nt, 1479 1368 struct ieee80211vap *match) 1480 1369 { 1481 1370 struct ieee80211_node *ni, *next; 1482 1371 1483 IEEE80211_NODE_ LOCK_IRQ(nt);1372 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1484 1373 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { 1485 1374 if (match != NULL && ni->ni_vap != match) 1486 1375 continue; … … 1492 1381 if (vap->iv_aid_bitmap != NULL) 1493 1382 IEEE80211_AID_CLR(vap, ni->ni_associd); 1494 1383 } 1495 node_reclaim(nt,ni);1384 ieee80211_node_leave(ni); 1496 1385 } 1497 IEEE80211_NODE_ UNLOCK_IRQ(nt);1386 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1498 1387 } 1499 1388 1500 1389 static void 1501 1390 ieee80211_node_table_cleanup(struct ieee80211_node_table *nt) 1502 1391 { 1392 struct ieee80211com *ic = nt->nt_ic; 1503 1393 struct ieee80211_node *ni, *next; 1504 1394 1505 1395 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { … … 1511 1401 if (vap->iv_aid_bitmap != NULL) 1512 1402 IEEE80211_AID_CLR(vap, ni->ni_associd); 1513 1403 } 1514 node_reclaim(nt,ni);1404 ic->ic_node_cleanup(ni); 1515 1405 } 1516 1406 del_timer(&nt->nt_wds_aging_timer); 1517 1407 IEEE80211_SCAN_LOCK_DESTROY(nt); 1518 IEEE80211_NODE_ LOCK_DESTROY(nt);1408 IEEE80211_NODE_TABLE_LOCK_DESTROY(nt); 1519 1409 } 1520 1410 1521 1411 /* … … 1543 1433 IEEE80211_SCAN_LOCK_IRQ(nt); 1544 1434 gen = ++nt->nt_scangen; 1545 1435 restart: 1546 IEEE80211_NODE_ LOCK_IRQ(nt);1436 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1547 1437 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1548 1438 if (ni->ni_scangen == gen) /* previously handled */ 1549 1439 continue; 1440 /* Temporary entries should no longer be in the node table */ 1550 1441 /* 1551 1442 * Ignore entries for which have yet to receive an 1552 1443 * authentication frame. These are transient and 1553 1444 * will be reclaimed when the last reference to them 1554 1445 * goes away (when frame xmits complete). 1555 1446 */ 1556 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1557 (ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1558 continue; 1447 /* 1448 *if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1449 * (ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1450 * continue; 1451 */ 1559 1452 ni->ni_scangen = gen; 1560 1453 /* 1561 1454 * Free fragment if not needed anymore … … 1607 1500 * ref for us as needed. 1608 1501 */ 1609 1502 ieee80211_ref_node(ni); 1610 IEEE80211_NODE_ UNLOCK_IRQ_EARLY(nt);1503 IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 1611 1504 ieee80211_send_nulldata(ni); 1612 1505 /* XXX stat? */ 1613 1506 goto restart; … … 1630 1523 */ 1631 1524 ni->ni_vap->iv_stats.is_node_timeout++; 1632 1525 ieee80211_ref_node(ni); 1633 IEEE80211_NODE_ UNLOCK_IRQ_EARLY(nt);1526 IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 1634 1527 if (ni->ni_associd != 0) { 1635 1528 IEEE80211_SEND_MGMT(ni, 1636 1529 IEEE80211_FC0_SUBTYPE_DEAUTH, 1637 1530 IEEE80211_REASON_AUTH_EXPIRE); 1638 1531 } 1639 1532 ieee80211_node_leave(ni); 1640 ieee80211_ free_node(ni);1533 ieee80211_unref_node(&ni); 1641 1534 goto restart; 1642 1535 } 1643 1536 } 1644 IEEE80211_NODE_ UNLOCK_IRQ(nt);1537 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1645 1538 1646 1539 IEEE80211_SCAN_UNLOCK_IRQ(nt); 1647 1540 } … … 1664 1557 void 1665 1558 ieee80211_iterate_nodes(struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg) 1666 1559 { 1667 struct ieee80211_node * ni;1560 struct ieee80211_node *tni, *ni; 1668 1561 u_int gen; 1669 1562 1670 1563 IEEE80211_SCAN_LOCK_IRQ(nt); 1671 1564 gen = ++nt->nt_scangen; 1565 1672 1566 restart: 1673 IEEE80211_NODE_LOCK(nt); 1674 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1675 if (ni->ni_scangen != gen) { 1676 ni->ni_scangen = gen; 1677 (void) ieee80211_ref_node(ni); 1678 IEEE80211_NODE_UNLOCK(nt); 1567 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1568 TAILQ_FOREACH(tni, &nt->nt_node, ni_list) { 1569 if (tni->ni_scangen != gen) { 1570 tni->ni_scangen = gen; 1571 1572 ni = ieee80211_ref_node(tni); 1573 IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 1574 1679 1575 (*f)(arg, ni); 1680 ieee80211_free_node(ni); 1576 1577 ieee80211_unref_node(&ni); 1681 1578 goto restart; 1682 1579 } 1683 1580 } 1684 IEEE80211_NODE_ UNLOCK(nt);1581 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1685 1582 1686 1583 IEEE80211_SCAN_UNLOCK_IRQ(nt); 1687 1584 } … … 1955 1852 "station with aid %d leaves (refcnt %u)", 1956 1853 IEEE80211_NODE_AID(ni), ieee80211_node_refcnt(ni)); 1957 1854 1855 /* From this point onwards we can no longer find the node, 1856 * so no more references are generated 1857 */ 1858 ieee80211_remove_wds_addr(nt, ni->ni_macaddr); 1859 ieee80211_del_wds_node(nt, ni); 1860 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1861 _node_table_leave(nt, ni); 1862 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1863 1958 1864 /* 1959 1865 * If node wasn't previously associated all 1960 1866 * we need to do is reclaim the reference. 1867 * This also goes for nodes that are auth'ed but 1868 * not associated. 1961 1869 */ 1962 1870 /* XXX ibss mode bypasses 11g and notification */ 1963 1871 if (ni->ni_associd == 0) … … 1975 1883 IEEE80211_LOCK_IRQ(ic); 1976 1884 if (vap->iv_aid_bitmap != NULL) 1977 1885 IEEE80211_AID_CLR(vap, ni->ni_associd); 1886 1978 1887 ni->ni_associd = 0; 1979 1888 vap->iv_sta_assoc--; 1980 1889 ic->ic_sta_assoc--; 1890 1981 1891 #ifdef ATH_SUPERG_XR 1982 1892 if (ni->ni_vap->iv_flags & IEEE80211_F_XR) 1983 1893 ic->ic_xr_sta_assoc--; … … 1988 1898 if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 1989 1899 ieee80211_node_leave_11g(ni); 1990 1900 IEEE80211_UNLOCK_IRQ(ic); 1901 1991 1902 /* 1992 1903 * Cleanup station state. In particular clear various 1993 1904 * state that might otherwise be reused if the node … … 1997 1908 ieee80211_sta_leave(ni); 1998 1909 done: 1999 1910 /* 2000 * Remove the node from any table it's recorded in and 2001 * drop the caller's reference. Removal from the table 2002 * is important to ensure the node is not reprocessed 2003 * for inactivity. 1911 * Run a cleanup and then drop the caller's reference 2004 1912 */ 2005 if (nt != NULL) { 2006 IEEE80211_NODE_LOCK_IRQ(nt); 2007 node_reclaim(nt, ni); 2008 IEEE80211_NODE_UNLOCK_IRQ(nt); 2009 ieee80211_remove_wds_addr(nt,ni->ni_macaddr); 2010 ieee80211_del_wds_node(nt,ni); 2011 } else 2012 ieee80211_free_node(ni); 1913 ic->ic_node_cleanup(ni); 1914 ieee80211_unref_node(&ni); 2013 1915 } 2014 1916 EXPORT_SYMBOL(ieee80211_node_leave); 2015 1917 … … 2069 1971 void 2070 1972 ieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap) 2071 1973 { 2072 if (ni != NULL) { 2073 struct ieee80211_node_table *nt = ni->ni_table; 2074 if (!nt) 2075 nt = &vap->iv_ic->ic_sta; 2076 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); 2077 ni->ni_prev_vap = ni->ni_vap; 2078 ni->ni_vap = vap; 2079 ni->ni_ic = vap->iv_ic; 2080 /* 2081 * if node not found in the node table 2082 * add it to the node table . 2083 */ 2084 if(nt && ieee80211_find_node(nt, ni->ni_macaddr) != ni) { 2085 int hash = IEEE80211_NODE_HASH(ni->ni_macaddr); 2086 IEEE80211_NODE_LOCK_IRQ(nt); 2087 TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); 2088 LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); 2089 ni->ni_table = nt; 2090 IEEE80211_NODE_UNLOCK_IRQ(nt); 2091 } 2092 } 1974 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); 1975 ni->ni_prev_vap = ni->ni_vap; 1976 ni->ni_vap = vap; 1977 ni->ni_ic = vap->iv_ic; 2093 1978 } -
net80211/ieee80211_node.h
old new 52 52 * authorized. The latter timeout is shorter to more aggressively 53 53 * reclaim nodes that leave part way through the 802.1x exchange. 54 54 */ 55 #define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */55 #define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */ 56 56 #define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */ 57 57 #define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */ 58 58 #define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */ 59 59 #define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */ 60 60 #define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */ 61 61 62 #define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */62 #define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */ 63 63 64 64 #define IEEE80211_NODE_HASHSIZE 32 65 65 /* simple hash is enough for variation of macaddr */ … … 94 94 struct ieee80211_node_table *ni_table; 95 95 TAILQ_ENTRY(ieee80211_node) ni_list; 96 96 LIST_ENTRY(ieee80211_node) ni_hash; 97 atomic_t ni_refcnt; 97 // ieee80211_node_lock_t ni_nodelock; /* on node - notably for ref counting */ 98 ieee80211_node_ref_count_t ni_refcnt; 98 99 u_int ni_scangen; /* gen# for timeout scan */ 99 100 u_int8_t ni_authmode; /* authentication algorithm */ 100 101 u_int16_t ni_flags; /* special-purpose state */ … … 121 122 u_int16_t ni_associd; /* assoc response */ 122 123 u_int16_t ni_txpower; /* current transmit power (in 0.5 dBm) */ 123 124 u_int16_t ni_vlan; /* vlan tag */ 124 u_int32_t *ni_challenge; /* shared-key challenge */125 u_int32_t *ni_challenge; /* shared-key challenge */ 125 126 u_int8_t *ni_wpa_ie; /* captured WPA ie */ 126 127 u_int8_t *ni_rsn_ie; /* captured RSN ie */ 127 128 u_int8_t *ni_wme_ie; /* captured WME ie */ 128 129 u_int8_t *ni_ath_ie; /* captured Atheros ie */ 129 u_int16_t ni_txseqs[17]; /* tx seq per-tid */130 u_int16_t ni_rxseqs[17]; /* rx seq previous per-tid*/130 u_int16_t ni_txseqs[17]; /* tx seq per-tid */ 131 u_int16_t ni_rxseqs[17]; /* rx seq previous per-tid*/ 131 132 u_int32_t ni_rxfragstamp; /* time stamp of last rx frag */ 132 133 struct sk_buff *ni_rxfrag[3]; /* rx frag reassembly */ 133 134 struct ieee80211_rsnparms ni_rsn; /* RSN/WPA parameters */ … … 156 157 struct ieee80211_channel *ni_chan; 157 158 u_int16_t ni_fhdwell; /* FH only */ 158 159 u_int8_t ni_fhindex; /* FH only */ 159 u_int8_t ni_erp; /* ERP from beacon/probe resp */160 u_int8_t ni_erp; /* ERP from beacon/probe resp */ 160 161 u_int16_t ni_timoff; /* byte offset to TIM ie */ 161 162 162 163 /* others */ … … 168 169 struct ieee80211vap *ni_prev_vap; /* previously associated vap */ 169 170 u_int8_t ni_uapsd; /* U-APSD per-node flags matching WMM STA Qos Info field */ 170 171 u_int8_t ni_uapsd_maxsp; /* maxsp from flags above */ 171 u_int16_t ni_uapsd_trigseq[WME_NUM_AC]; /* trigger suppression on retry */172 u_int16_t ni_uapsd_trigseq[WME_NUM_AC]; /* trigger suppression on retry */ 172 173 __le16 ni_pschangeseq; 173 174 }; 174 175 MALLOC_DECLARE(M_80211_NODE); … … 186 187 #define WME_UAPSD_NODE_INVALIDSEQ 0xffff 187 188 #define WME_UAPSD_NODE_TRIGSEQINIT(_ni) (memset(&(_ni)->ni_uapsd_trigseq[0], 0xff, sizeof((_ni)->ni_uapsd_trigseq))) 188 189 189 static __inline struct ieee80211_node *190 ieee80211_ref_node(struct ieee80211_node *ni)191 {192 ieee80211_node_incref(ni);193 return ni;194 }195 196 static __inline void197 ieee80211_unref_node(struct ieee80211_node **ni)198 {199 ieee80211_node_decref(*ni);200 *ni = NULL; /* guard against use */201 }202 203 190 void ieee80211_node_attach(struct ieee80211com *); 204 191 void ieee80211_node_detach(struct ieee80211com *); 205 192 void ieee80211_node_vattach(struct ieee80211vap *); … … 242 229 * is a second table for associated stations or neighbors. 243 230 */ 244 231 struct ieee80211_node_table { 232 const char *nt_name; /* for debugging */ 245 233 struct ieee80211com *nt_ic; /* back reference */ 246 ieee80211_node_ lock_t nt_nodelock; /* on node table */234 ieee80211_node_table_lock_t nt_nodelock; /* on node table */ 247 235 TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ 248 236 ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; 249 237 ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE]; 250 const char *nt_name; /* for debugging */251 238 ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */ 252 239 u_int nt_scangen; /* gen# for timeout scan */ 253 240 int nt_inact_init; /* initial node inact setting */ 254 241 struct timer_list nt_wds_aging_timer; /* timer to age out wds entries */ 255 242 }; 256 243 257 struct ieee80211_node *ieee80211_alloc_node(struct ieee80211_node_table *, 258 struct ieee80211vap *, const u_int8_t *); 259 struct ieee80211_node *ieee80211_tmp_node(struct ieee80211vap *, 244 struct ieee80211_node *ieee80211_alloc_node_table(struct ieee80211vap *, 260 245 const u_int8_t *); 261 struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *, 262 const u_int8_t * );246 struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *, 247 const u_int8_t *, unsigned char); 263 248 void ieee80211_node_reset(struct ieee80211_node *, struct ieee80211vap *); 264 249 #ifdef IEEE80211_DEBUG_REFCNT 265 void ieee80211_free_node_debug(struct ieee80211_node *, const char *, int);266 250 struct ieee80211_node *ieee80211_find_node_debug(struct ieee80211_node_table *, 267 251 const u_int8_t *, const char *, int); 268 252 struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *, 269 253 const struct ieee80211_frame_min *, const char *, int); 270 254 struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211vap *, 271 255 const u_int8_t *, const char *, int); 272 #define ieee80211_ free_node(ni) \273 ieee80211_ free_node_debug(ni, __func__, __LINE__)274 #define ieee80211_find_node( nt,mac) \275 ieee80211_find_node_debug( nt,mac, __func__, __LINE__)276 #define ieee80211_find_rxnode( nt,wh) \277 ieee80211_find_rxnode_debug( nt,wh, __func__, __LINE__)278 #define ieee80211_find_txnode( nt,mac) \279 ieee80211_find_txnode_debug( nt,mac, __func__, __LINE__)256 #define ieee80211_unref_node(_ni) \ 257 ieee80211_unref_node_debug(_ni, __func__, __LINE__) 258 #define ieee80211_find_node(_nt, _mac) \ 259 ieee80211_find_node_debug(_nt, _mac, __func__, __LINE__) 260 #define ieee80211_find_rxnode(_nt, _wh) \ 261 ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__) 262 #define ieee80211_find_txnode(_nt, _mac) \ 263 ieee80211_find_txnode_debug(_nt, _mac, __func__, __LINE__) 280 264 #else 281 void ieee80211_free_node(struct ieee80211_node *);282 265 283 266 struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *, 284 267 const u_int8_t *); … … 287 270 struct ieee80211_node *ieee80211_find_txnode(struct ieee80211vap *, 288 271 const u_int8_t *); 289 272 #endif 273 274 void _ieee80211_free_node(struct ieee80211_node *); 275 276 static __inline struct ieee80211_node * 277 ieee80211_ref_node(struct ieee80211_node *ni) 278 { 279 ieee80211_node_incref(ni); 280 return ni; 281 } 282 283 static __inline struct ieee80211_node * 284 _ieee80211_pass_node(struct ieee80211_node **pni) { 285 struct ieee80211_node *tmp = *pni; 286 *pni = NULL; 287 return (tmp); 288 } 289 290 #define PASS_NODE(_ni) \ 291 _ieee80211_pass_node(&_ni) 292 293 static __inline int 294 _ieee80211_unref_node(struct ieee80211_node *ni) { 295 if (ieee80211_node_dectestref(ni)) { 296 _ieee80211_free_node(ni); 297 return 1; 298 } else { 299 return 0; 300 } 301 } 302 303 static __inline void 304 #ifdef IEEE80211_DEBUG_REFCNT 305 ieee80211_unref_node_debug(struct ieee80211_node **pni, const char *func, int line) 306 #else 307 ieee80211_unref_node(struct ieee80211_node **pni) 308 #endif 309 { 310 struct ieee80211_node *ni = *pni; 311 #ifdef IEEE80211_DEBUG_REFCNT 312 IEEE80211_DPRINTF(NULL, IEEE80211_MSG_NODE, 313 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni, 314 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1); 315 #endif 316 _ieee80211_unref_node(ni); 317 *pni = NULL; /* guard against use */ 318 } 319 290 320 int ieee80211_add_wds_addr(struct ieee80211_node_table *, struct ieee80211_node *, 291 321 const u_int8_t *, u_int8_t); 292 322 void ieee80211_remove_wds_addr(struct ieee80211_node_table *, const u_int8_t *); -
net80211/ieee80211_debug.h
old new 1 /*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2 as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $Id: ieee80211_var.h 1969 2007-01-16 03:05:18Z scottr $ 33 */ 34 #ifndef _NET80211_IEEE80211_DEBUG_H_ 35 #define _NET80211_IEEE80211_DEBUG_H_ 36 37 #define IEEE80211_DEBUG 38 #define IEEE80211_DEBUG_REFCNT /* node refcnt stuff */ 39 40 #include <net80211/ieee80211.h> 41 42 #define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */ 43 #define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalent */ 44 #define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */ 45 #define IEEE80211_MSG_INPUT 0x08000000 /* input handling */ 46 #define IEEE80211_MSG_XRATE 0x04000000 /* rate set handling */ 47 #define IEEE80211_MSG_ELEMID 0x02000000 /* element id parsing */ 48 #define IEEE80211_MSG_NODE 0x01000000 /* node handling */ 49 #define IEEE80211_MSG_ASSOC 0x00800000 /* association handling */ 50 #define IEEE80211_MSG_AUTH 0x00400000 /* authentication handling */ 51 #define IEEE80211_MSG_SCAN 0x00200000 /* scanning */ 52 #define IEEE80211_MSG_OUTPUT 0x00100000 /* output handling */ 53 #define IEEE80211_MSG_STATE 0x00080000 /* state machine */ 54 #define IEEE80211_MSG_POWER 0x00040000 /* power save handling */ 55 #define IEEE80211_MSG_DOT1X 0x00020000 /* 802.1x authenticator */ 56 #define IEEE80211_MSG_DOT1XSM 0x00010000 /* 802.1x state machine */ 57 #define IEEE80211_MSG_RADIUS 0x00008000 /* 802.1x radius client */ 58 #define IEEE80211_MSG_RADDUMP 0x00004000 /* dump 802.1x radius packets */ 59 #define IEEE80211_MSG_RADKEYS 0x00002000 /* dump 802.1x keys */ 60 #define IEEE80211_MSG_WPA 0x00001000 /* WPA/RSN protocol */ 61 #define IEEE80211_MSG_ACL 0x00000800 /* ACL handling */ 62 #define IEEE80211_MSG_WME 0x00000400 /* WME protocol */ 63 #define IEEE80211_MSG_SUPG 0x00000200 /* SUPERG */ 64 #define IEEE80211_MSG_DOTH 0x00000100 /* 11.h */ 65 #define IEEE80211_MSG_INACT 0x00000080 /* inactivity handling */ 66 #define IEEE80211_MSG_ROAM 0x00000040 /* sta-mode roaming */ 67 68 #define IEEE80211_MSG_ANY 0xffffffff /* anything */ 69 70 #ifdef IEEE80211_DEBUG 71 int ieee80211_msg_is_reported(struct ieee80211vap *, unsigned int msg); 72 #define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do { \ 73 if (ieee80211_msg_is_reported(_vap, _m)) \ 74 ieee80211_note(_vap, _fmt, __VA_ARGS__); \ 75 } while (0) 76 #define IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...) do { \ 77 if (ieee80211_msg_is_reported(_vap, _m)) \ 78 ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\ 79 } while (0) 80 #define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) do { \ 81 if (ieee80211_msg_is_reported(_vap, _m)) \ 82 ieee80211_note_mac(_vap, _mac, _fmt, __VA_ARGS__); \ 83 } while (0) 84 #define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) do { \ 85 if (ieee80211_msg_is_reported(_vap, _m)) \ 86 ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__); \ 87 } while (0) 88 struct ieee80211vap; 89 struct ieee80211_frame; 90 void ieee80211_note(struct ieee80211vap *, const char *, ...); 91 void ieee80211_note_mac(struct ieee80211vap *, 92 const u_int8_t mac[IEEE80211_ADDR_LEN], const char *, ...); 93 void ieee80211_note_frame(struct ieee80211vap *, 94 const struct ieee80211_frame *, const char *, ...); 95 #define ieee80211_msg_debug(_vap) \ 96 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_DEBUG) 97 #define ieee80211_msg_dumppkts(_vap) \ 98 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_DUMPPKTS) 99 #define ieee80211_msg_input(_vap) \ 100 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_INPUT) 101 #define ieee80211_msg_radius(_vap) \ 102 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_RADIUS) 103 #define ieee80211_msg_dumpradius(_vap) \ 104 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_RADDUMP) 105 #define ieee80211_msg_dumpradkeys(_vap) \ 106 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_RADKEYS) 107 #define ieee80211_msg_scan(_vap) \ 108 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_SCAN) 109 #define ieee80211_msg_assoc(_vap) \ 110 ieee80211_msg_is_reported(_vap, IEEE80211_MSG_ASSOC) 111 #else /* IEEE80211_DEBUG */ 112 #define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) 113 #define IEEE80211_NOTE(_vap, _m, _wh, _fmt, ...) 114 #define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) 115 #define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) 116 #endif /* IEEE80211_DEBUG */ 117 118 #endif /* _NET80211_IEEE80211_DEBUG_H_ */ 119 -
net80211/ieee80211_scan_sta.c
old new 762 762 if (se->se_rssi < STA_RSSI_MIN) 763 763 fail |= 0x100; 764 764 #ifdef IEEE80211_DEBUG 765 if (ieee80211_msg (vap, IEEE80211_MSG_SCAN | IEEE80211_MSG_ROAM)) {765 if (ieee80211_msg_is_reported(vap, IEEE80211_MSG_SCAN | IEEE80211_MSG_ROAM)) { 766 766 printf(" %03x", fail); 767 767 printf(" %c %s", 768 768 fail & 0x40 ? '=' : fail & 0x80 ? '^' : fail ? '-' : '+', -
net80211/ieee80211_wireless.c
old new 3160 3160 error = -ENXIO; 3161 3161 ieee80211_key_update_end(vap); 3162 3162 if (ni != NULL) 3163 ieee80211_ free_node(ni);3163 ieee80211_unref_node(&ni); 3164 3164 #ifdef ATH_SUPERG_XR 3165 3165 /* set the same params on the xr vap device if exists */ 3166 3166 if (vap->iv_xrvap && !(vap->iv_flags & IEEE80211_F_XR)) … … 3220 3220 memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata)); 3221 3221 } 3222 3222 if (ni != NULL) 3223 ieee80211_ free_node(ni);3223 ieee80211_unref_node(&ni); 3224 3224 return (copy_to_user(iwr->u.data.pointer, &ik, sizeof(ik)) ? -EFAULT : 0); 3225 3225 } 3226 3226 … … 3243 3243 return -EINVAL; /* XXX */ 3244 3244 /* XXX error return */ 3245 3245 ieee80211_crypto_delkey(vap, &ni->ni_ucastkey, ni); 3246 ieee80211_ free_node(ni);3246 ieee80211_unref_node(&ni); 3247 3247 } else { 3248 3248 if (kid >= IEEE80211_WEP_NKID) 3249 3249 return -EINVAL; … … 3345 3345 if (ni == NULL) 3346 3346 return -EINVAL; 3347 3347 domlme(mlme, ni); 3348 ieee80211_ free_node(ni);3348 ieee80211_unref_node(&ni); 3349 3349 } else 3350 3350 ieee80211_iterate_nodes(&ic->ic_sta, domlme, mlme); 3351 3351 break; … … 3364 3364 ieee80211_node_authorize(ni); 3365 3365 else 3366 3366 ieee80211_node_unauthorize(ni); 3367 ieee80211_ free_node(ni);3367 ieee80211_unref_node(&ni); 3368 3368 break; 3369 3369 case IEEE80211_MLME_CLEAR_STATS: 3370 3370 if (vap->iv_opmode != IEEE80211_M_HOSTAP) … … 3375 3375 3376 3376 /* clear statistics */ 3377 3377 memset(&ni->ni_stats, 0, sizeof(struct ieee80211_nodestats)); 3378 ieee80211_ free_node(ni);3378 ieee80211_unref_node(&ni); 3379 3379 break; 3380 3380 default: 3381 3381 return -EINVAL; … … 3745 3745 ielen = sizeof(wpaie.rsn_ie); 3746 3746 memcpy(wpaie.rsn_ie, ni->ni_rsn_ie, ielen); 3747 3747 } 3748 ieee80211_ free_node(ni);3748 ieee80211_unref_node(&ni); 3749 3749 return (copy_to_user(iwr->u.data.pointer, &wpaie, sizeof(wpaie)) ? 3750 3750 -EFAULT : 0); 3751 3751 } … … 3772 3772 /* NB: copy out only the statistics */ 3773 3773 error = copy_to_user(iwr->u.data.pointer + off, &ni->ni_stats, 3774 3774 iwr->u.data.length - off); 3775 ieee80211_ free_node(ni);3775 ieee80211_unref_node(&ni); 3776 3776 return (error ? -EFAULT : 0); 3777 3777 } 3778 3778 -
net80211/ieee80211_input.c
old new 310 310 /* 311 311 * Try to find sender in local node table. 312 312 */ 313 ieee80211_ free_node(ni);313 ieee80211_unref_node(&ni); 314 314 ni = ieee80211_find_node(vap->iv_bss->ni_table, wh->i_addr2); 315 315 if (ni == NULL) { 316 316 /* … … 491 491 nt = &ic->ic_sta; 492 492 ni_wds = ieee80211_find_wds_node(nt, wh->i_addr3); 493 493 if (ni_wds) { 494 ieee80211_ free_node(ni_wds); /* Decr ref count */494 ieee80211_unref_node(&ni_wds); /* Decr ref count */ 495 495 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 496 496 wh, NULL, "%s", 497 497 "multicast echo originated from node behind me"); … … 571 571 if (ni_wds == NULL) 572 572 ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0); 573 573 else 574 ieee80211_ free_node(ni_wds); /* Decr ref count */574 ieee80211_unref_node(&ni_wds); /* Decr ref count */ 575 575 } 576 576 577 577 /* … … 930 930 } 931 931 ni = ieee80211_ref_node(vap->iv_bss); 932 932 type = ieee80211_input(ni, skb1, rssi, rstamp); 933 ieee80211_ free_node(ni);933 ieee80211_unref_node(&ni); 934 934 } 935 935 if (skb != NULL) /* no vaps, reclaim skb */ 936 936 dev_kfree_skb(skb); … … 980 980 } 981 981 982 982 /* 983 * Use this lock to make sure ni->ni_rxfrag[0] is984 * not freed by the timer process while we use it.985 * XXX bogus986 */987 IEEE80211_NODE_LOCK_IRQ(ni->ni_table);988 989 /*990 983 * Update the time stamp. As a side effect, it 991 984 * also makes sure that the timer will not change 992 985 * ni->ni_rxfrag[0] for at least 1 second, or in 993 986 * other words, for the remaining of this function. 987 * XXX HUGE HORRIFIC HACK 994 988 */ 995 989 ni->ni_rxfragstamp = jiffies; 996 990 997 IEEE80211_NODE_UNLOCK_IRQ(ni->ni_table);998 999 991 /* 1000 992 * Validate that fragment is in order and 1001 993 * related to the previous ones. … … 1124 1116 skb = NULL; 1125 1117 } 1126 1118 /* XXX statistic? */ 1127 ieee80211_ free_node(ni1);1119 ieee80211_unref_node(&ni1); 1128 1120 } 1129 1121 } 1130 1122 if (skb1 != NULL) { … … 1248 1240 int rssi, u_int32_t rstamp, u_int16_t seq, u_int16_t status) 1249 1241 { 1250 1242 struct ieee80211vap *vap = ni->ni_vap; 1243 unsigned int tmpnode = 0; 1251 1244 1252 1245 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { 1253 1246 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, … … 1255 1248 "bad sta auth mode %u", ni->ni_authmode); 1256 1249 vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ 1257 1250 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1258 /* XXX hack to workaround calling convention */1259 1260 /* XXX To send the frame to the requesting STA, we have to1261 * create a node for the station that we're going to reject.1262 * The node will be freed automatically */1263 1251 if (ni == vap->iv_bss) { 1264 ni = ieee80211_dup_bss(vap, wh->i_addr2); 1252 ieee80211_unref_node(&ni); 1253 ni = ieee80211_dup_bss(vap, wh->i_addr2, 0); 1265 1254 if (ni == NULL) 1266 1255 return; 1267 1256 1268 1257 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 1269 1258 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr), 1270 1259 ieee80211_node_refcnt(ni)); 1260 tmpnode = 1; 1271 1261 } 1272 1262 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, 1273 1263 (seq + 1) | (IEEE80211_STATUS_ALG<<16)); 1264 1265 if (tmpnode) 1266 ieee80211_unref_node(&ni); 1274 1267 return; 1275 1268 } 1276 1269 } … … 1298 1291 } 1299 1292 /* always accept open authentication requests */ 1300 1293 if (ni == vap->iv_bss) { 1301 ni = ieee80211_dup_bss(vap, wh->i_addr2); 1294 ieee80211_unref_node(&ni); 1295 ni = ieee80211_dup_bss(vap, wh->i_addr2, 0); 1302 1296 if (ni == NULL) 1303 1297 return; 1304 1298 1305 1299 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 1306 1300 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr), 1307 1301 ieee80211_node_refcnt(ni)); 1308 1309 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1310 (void) ieee80211_ref_node(ni); 1311 /* 1312 * Mark the node as referenced to reflect that it's 1313 * reference count has been bumped to ensure it remains 1314 * after the transaction completes. 1315 */ 1316 ni->ni_flags |= IEEE80211_NODE_AREF; 1317 1302 tmpnode = 1; 1303 } 1304 1318 1305 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1319 1306 IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1320 1307 ni, "station authenticated (%s)", "open"); … … 1324 1311 */ 1325 1312 if (ni->ni_authmode != IEEE80211_AUTH_8021X) 1326 1313 ieee80211_node_authorize(ni); 1314 if (tmpnode) 1315 ieee80211_unref_node(&ni); 1327 1316 break; 1328 1317 1329 1318 case IEEE80211_M_STA: … … 1362 1351 int istmp; 1363 1352 1364 1353 if (ni == vap->iv_bss) { 1365 ni = ieee80211_tmp_node(vap, mac); 1354 ieee80211_unref_node(&ni); 1355 ni = ieee80211_dup_bss(vap, mac, 1); 1366 1356 if (ni == NULL) { 1367 1357 /* XXX msg */ 1368 1358 return; … … 1372 1362 istmp = 0; 1373 1363 IEEE80211_SEND_MGMT(ni, subtype, arg); 1374 1364 if (istmp) 1375 ieee80211_ free_node(ni);1365 ieee80211_unref_node(&ni); 1376 1366 } 1377 1367 1378 1368 static int … … 1398 1388 { 1399 1389 struct ieee80211vap *vap = ni->ni_vap; 1400 1390 u_int8_t *challenge; 1401 int allocbs , estatus;1391 int allocbs = 0, estatus = 0; 1402 1392 1403 1393 /* 1404 1394 * NB: this can happen as we allow pre-shared key … … 1408 1398 * ordering in which case this check would just be 1409 1399 * for sanity/consistency. 1410 1400 */ 1411 estatus = 0; /* NB: silence compiler */1412 1401 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 1413 1402 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1414 1403 ni->ni_macaddr, "shared key auth", … … 1488 1477 switch (seq) { 1489 1478 case IEEE80211_AUTH_SHARED_REQUEST: 1490 1479 if (ni == vap->iv_bss) { 1491 ni = ieee80211_dup_bss(vap, wh->i_addr2); 1480 ieee80211_unref_node(&ni); 1481 ni = ieee80211_dup_bss(vap, wh->i_addr2, 0); 1492 1482 if (ni == NULL) { 1493 1483 /* NB: no way to return an error */ 1494 1484 return; … … 1499 1489 ieee80211_node_refcnt(ni)); 1500 1490 1501 1491 allocbs = 1; 1502 } else {1503 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)1504 (void) ieee80211_ref_node(ni);1505 allocbs = 0;1506 1492 } 1507 /* 1508 * Mark the node as referenced to reflect that it's 1509 * reference count has been bumped to ensure it remains 1510 * after the transaction completes. 1511 */ 1512 ni->ni_flags |= IEEE80211_NODE_AREF; 1493 1513 1494 ni->ni_rssi = rssi; 1514 1495 ni->ni_rstamp = rstamp; 1515 1496 ni->ni_last_rx = jiffies; … … 1603 1584 } 1604 1585 return; 1605 1586 bad: 1606 /* 1607 * Send an error response; but only when operating as an AP. 1608 */ 1587 /* Send an error response; but only when operating as an AP. */ 1609 1588 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1610 1589 /* XXX hack to workaround calling convention */ 1611 1590 ieee80211_send_error(ni, wh->i_addr2, 1612 1591 IEEE80211_FC0_SUBTYPE_AUTH, 1613 1592 (seq + 1) | (estatus<<16)); 1593 ieee80211_node_leave(ni); 1614 1594 } else if (vap->iv_opmode == IEEE80211_M_STA) { 1615 1595 /* 1616 1596 * Kick the state machine. This short-circuits … … 2074 2054 /* optional RSN capabilities */ 2075 2055 if (len > 2) 2076 2056 rsn_parm->rsn_caps = LE_READ_2(frm); 2077 /* XXX PMKID */2057 /* XXX PMKID */ 2078 2058 2079 2059 return 0; 2080 2060 } … … 2568 2548 u_int8_t *frm, *efrm; 2569 2549 u_int8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath; 2570 2550 u_int8_t rate; 2571 int reassoc, resp, allocbs ;2551 int reassoc, resp, allocbs = 0; 2572 2552 u_int8_t qosinfo; 2573 2553 2574 2554 wh = (struct ieee80211_frame *) skb->data; … … 2849 2829 } 2850 2830 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { 2851 2831 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 2852 /*2853 * Create a new entry in the neighbor table.2854 */2855 2832 ni = ieee80211_add_neighbor(vap, wh, &scan); 2856 2833 } else { 2857 2834 /* … … 2965 2942 */ 2966 2943 ni = ieee80211_fakeup_adhoc_node(vap, 2967 2944 wh->i_addr2); 2968 } else 2969 ni = ieee80211_tmp_node(vap, wh->i_addr2); 2945 } else { 2946 ieee80211_unref_node(&ni); 2947 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1); 2948 } 2970 2949 if (ni == NULL) 2971 2950 return; 2972 2951 allocbs = 1; 2973 } else2974 allocbs = 0; 2952 } 2953 2975 2954 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, 2976 2955 "%s", "recv probe req"); 2977 2956 ni->ni_rssi = rssi; … … 2994 2973 * Temporary node created just to send a 2995 2974 * response, reclaim immediately 2996 2975 */ 2997 ieee80211_ free_node(ni);2976 ieee80211_unref_node(&ni); 2998 2977 } else if (ath != NULL) 2999 2978 ieee80211_saveath(ni, ath); 3000 2979 break; … … 3024 3003 ni = vap->iv_xrvap->iv_bss; 3025 3004 else { 3026 3005 ieee80211_node_leave(ni); 3006 /* This would be a stupid place to add a node to the table 3007 * XR stuff needs work anyway 3008 */ 3027 3009 ieee80211_node_reset(ni, vap->iv_xrvap); 3028 3010 } 3029 3011 vap = vap->iv_xrvap; … … 3036 3018 #endif 3037 3019 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, 3038 3020 "recv auth frame with algorithm %d seq %d", algo, seq); 3039 /* 3040 * Consult the ACL policy module if setup. 3041 */ 3021 /* Consult the ACL policy module if setup. */ 3042 3022 if (vap->iv_acl != NULL && 3043 3023 !vap->iv_acl->iac_check(vap, wh->i_addr2)) { 3044 3024 IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, … … 3071 3051 /* XXX not right */ 3072 3052 ieee80211_send_error(ni, wh->i_addr2, 3073 3053 IEEE80211_FC0_SUBTYPE_AUTH, 3074 (seq +1) | (IEEE80211_STATUS_ALG << 16));3054 (seq + 1) | (IEEE80211_STATUS_ALG << 16)); 3075 3055 } 3076 3056 return; 3077 3057 } -
net80211/ieee80211_output.c
old new 254 254 goto bad; 255 255 } 256 256 257 cb->ni = ni;257 cb->ni = ieee80211_ref_node(ni); 258 258 259 259 /* power-save checks */ 260 260 if (WME_UAPSD_AC_CAN_TRIGGER(skb->priority, ni)) { … … 293 293 } 294 294 #endif 295 295 ieee80211_parent_queue_xmit(skb); 296 ieee80211_unref_node(&ni); 296 297 return 0; 297 298 298 299 bad: 299 300 if (skb != NULL) 300 301 dev_kfree_skb(skb); 301 302 if (ni != NULL) 302 ieee80211_ free_node(ni);303 ieee80211_unref_node(&ni); 303 304 return 0; 304 305 } 305 306 … … 453 454 if (skb == NULL) { 454 455 /* XXX debug msg */ 455 456 vap->iv_stats.is_tx_nobuf++; 456 ieee80211_ free_node(ni);457 ieee80211_unref_node(&ni); 457 458 return -ENOMEM; 458 459 } 459 460 cb = (struct ieee80211_cb *)skb->cb; … … 507 508 u_int8_t *frm; 508 509 int tid; 509 510 510 ieee80211_ref_node(ni);511 511 skb = ieee80211_getmgtframe(&frm, 2); 512 512 if (skb == NULL) { 513 513 /* XXX debug msg */ 514 514 vap->iv_stats.is_tx_nobuf++; 515 ieee80211_free_node(ni);516 515 return -ENOMEM; 517 516 } 518 517 cb = (struct ieee80211_cb *)skb->cb; 519 cb->ni = ni;518 cb->ni = ieee80211_ref_node(ni); 520 519 521 520 skb->priority = ac; 522 521 qwh = (struct ieee80211_qosframe *)skb_push(skb, sizeof(struct ieee80211_qosframe)); … … 865 864 nt = &ic->ic_sta; 866 865 ni_wds = ieee80211_find_wds_node(nt, eh.ether_shost); 867 866 if (ni_wds) 868 ieee80211_ free_node(ni_wds); /* Decr ref count */867 ieee80211_unref_node(&ni_wds); /* Decr ref count */ 869 868 else 870 869 ieee80211_add_wds_addr(nt, ni, eh.ether_shost, 0); 871 870 } … … 1719 1718 __func__, __LINE__, 1720 1719 ni, ether_sprintf(ni->ni_macaddr), 1721 1720 ieee80211_node_refcnt(ni) + 1); 1722 ieee80211_ref_node(ni);1723 1721 1724 1722 /* 1725 1723 * prreq frame format … … 1735 1733 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); 1736 1734 if (skb == NULL) { 1737 1735 vap->iv_stats.is_tx_nobuf++; 1738 ieee80211_free_node(ni);1739 1736 return -ENOMEM; 1740 1737 } 1741 1738 … … 1758 1755 skb_trim(skb, frm - skb->data); 1759 1756 1760 1757 cb = (struct ieee80211_cb *)skb->cb; 1761 cb->ni = ni;1758 cb->ni = ieee80211_ref_node(ni); 1762 1759 1763 1760 wh = (struct ieee80211_frame *) 1764 1761 skb_push(skb, sizeof(struct ieee80211_frame)); … … 2233 2230 mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ); 2234 2231 return 0; 2235 2232 bad: 2236 ieee80211_ free_node(ni);2233 ieee80211_unref_node(&ni); 2237 2234 return ret; 2238 2235 #undef senderr 2239 2236 } -
net80211/ieee80211_power.c
old new 109 109 int 110 110 ieee80211_node_saveq_drain(struct ieee80211_node *ni) 111 111 { 112 struct ieee80211_cb *cb = NULL; 112 113 struct sk_buff *skb; 113 114 int qlen; 114 115 115 116 IEEE80211_NODE_SAVEQ_LOCK(ni); 116 117 qlen = skb_queue_len(&ni->ni_savedq); 117 118 while ((skb = __skb_dequeue(&ni->ni_savedq)) != NULL) { 118 ieee80211_free_node(ni); 119 cb = (struct ieee80211_cb *) skb->cb; 120 ieee80211_unref_node(&cb->ni); 119 121 dev_kfree_skb_any(skb); 120 122 } 121 123 IEEE80211_NODE_SAVEQ_UNLOCK(ni); -
net80211/ieee80211_var.h
old new 37 37 /* 38 38 * Definitions for IEEE 802.11 drivers. 39 39 */ 40 #define IEEE80211_DEBUG 41 #undef IEEE80211_DEBUG_REFCNT /* node refcnt stuff */ 40 #include <net80211/ieee80211_debug.h> 42 41 43 42 #include <net80211/ieee80211_linux.h> 44 43 … … 230 229 /* new station association callback/notification */ 231 230 void (*ic_newassoc)(struct ieee80211_node *, int); 232 231 /* node state management */ 233 struct ieee80211_node *(*ic_node_alloc)(struct ieee80211_node_table *, 234 struct ieee80211vap *); 232 struct ieee80211_node *(*ic_node_alloc)(struct ieee80211vap *); 235 233 void (*ic_node_free)(struct ieee80211_node *); 236 234 void (*ic_node_cleanup)(struct ieee80211_node *); 237 235 u_int8_t (*ic_node_getrssi)(const struct ieee80211_node *); … … 406 404 u_int32_t app_filter; /* filters which management frames are forwarded to app */ 407 405 408 406 }; 407 408 static __inline int ieee80211_is_printed(struct ieee80211vap *vap, unsigned m) 409 { 410 return !!(vap->iv_debug & m); 411 } 412 409 413 MALLOC_DECLARE(M_80211_VAP); 410 414 411 415 #define IEEE80211_ADDR_NULL(a1) (memcmp(a1, "\x00\x00\x00\x00\x00\x00", \ … … 613 617 size = roundup(size, sizeof(u_int32_t)); 614 618 return size; 615 619 } 616 617 #define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */618 #define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalent */619 #define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */620 #define IEEE80211_MSG_INPUT 0x08000000 /* input handling */621 #define IEEE80211_MSG_XRATE 0x04000000 /* rate set handling */622 #define IEEE80211_MSG_ELEMID 0x02000000 /* element id parsing */623 #define IEEE80211_MSG_NODE 0x01000000 /* node handling */624 #define IEEE80211_MSG_ASSOC 0x00800000 /* association handling */625 #define IEEE80211_MSG_AUTH 0x00400000 /* authentication handling */626 #define IEEE80211_MSG_SCAN 0x00200000 /* scanning */627 #define IEEE80211_MSG_OUTPUT 0x00100000 /* output handling */628 #define IEEE80211_MSG_STATE 0x00080000 /* state machine */629 #define IEEE80211_MSG_POWER 0x00040000 /* power save handling */630 #define IEEE80211_MSG_DOT1X 0x00020000 /* 802.1x authenticator */631 #define IEEE80211_MSG_DOT1XSM 0x00010000 /* 802.1x state machine */632 #define IEEE80211_MSG_RADIUS 0x00008000 /* 802.1x radius client */633 #define IEEE80211_MSG_RADDUMP 0x00004000 /* dump 802.1x radius packets */634 #define IEEE80211_MSG_RADKEYS 0x00002000 /* dump 802.1x keys */635 #define IEEE80211_MSG_WPA 0x00001000 /* WPA/RSN protocol */636 #define IEEE80211_MSG_ACL 0x00000800 /* ACL handling */637 #define IEEE80211_MSG_WME 0x00000400 /* WME protocol */638 #define IEEE80211_MSG_SUPG 0x00000200 /* SUPERG */639 #define IEEE80211_MSG_DOTH 0x00000100 /* 11.h */640 #define IEEE80211_MSG_INACT 0x00000080 /* inactivity handling */641 #define IEEE80211_MSG_ROAM 0x00000040 /* sta-mode roaming */642 643 #define IEEE80211_MSG_ANY 0xffffffff /* anything */644 645 #ifdef IEEE80211_DEBUG646 #define ieee80211_msg(_vap, _m) ((_vap)->iv_debug & (_m))647 #define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do { \648 if (ieee80211_msg(_vap, _m)) \649 ieee80211_note(_vap, _fmt, __VA_ARGS__); \650 } while (0)651 #define IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...) do { \652 if (ieee80211_msg(_vap, _m)) \653 ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\654 } while (0)655 #define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) do { \656 if (ieee80211_msg(_vap, _m)) \657 ieee80211_note_mac(_vap, _mac, _fmt, __VA_ARGS__); \658 } while (0)659 #define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) do { \660 if (ieee80211_msg(_vap, _m)) \661 ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__); \662 } while (0)663 void ieee80211_note(struct ieee80211vap *, const char *, ...);664 void ieee80211_note_mac(struct ieee80211vap *,665 const u_int8_t mac[IEEE80211_ADDR_LEN], const char *, ...);666 void ieee80211_note_frame(struct ieee80211vap *,667 const struct ieee80211_frame *, const char *, ...);668 #define ieee80211_msg_debug(_vap) \669 ieee80211_msg(_vap, IEEE80211_MSG_DEBUG)670 #define ieee80211_msg_dumppkts(_vap) \671 ieee80211_msg(_vap, IEEE80211_MSG_DUMPPKTS)672 #define ieee80211_msg_input(_vap) \673 ieee80211_msg(_vap, IEEE80211_MSG_INPUT)674 #define ieee80211_msg_radius(_vap) \675 ieee80211_msg(_vap, IEEE80211_MSG_RADIUS)676 #define ieee80211_msg_dumpradius(_vap) \677 ieee80211_msg(_vap, IEEE80211_MSG_RADDUMP)678 #define ieee80211_msg_dumpradkeys(_vap) \679 ieee80211_msg(_vap, IEEE80211_MSG_RADKEYS)680 #define ieee80211_msg_scan(_vap) \681 ieee80211_msg(_vap, IEEE80211_MSG_SCAN)682 #define ieee80211_msg_assoc(_vap) \683 ieee80211_msg(_vap, IEEE80211_MSG_ASSOC)684 #else /* IEEE80211_DEBUG */685 #define IEEE80211_DPRINTF(_vap, _m, _fmt, ...)686 #define IEEE80211_NOTE(_vap, _m, _wh, _fmt, ...)687 #define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...)688 #define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...)689 #endif /* IEEE80211_DEBUG */690 691 620 #endif /* _NET80211_IEEE80211_VAR_H_ */ -
net80211/ieee80211_proto.c
old new 1456 1456 */ 1457 1457 if (vap->iv_opmode == IEEE80211_M_WDS) { 1458 1458 struct ieee80211_node *wds_ni; 1459 wds_ni = ieee80211_alloc_node (&ic->ic_sta,vap, vap->wds_mac);1459 wds_ni = ieee80211_alloc_node_table(vap, vap->wds_mac); 1460 1460 if (wds_ni != NULL) { 1461 1461 if (ieee80211_add_wds_addr(&ic->ic_sta, wds_ni, vap->wds_mac, 1) == 0) { 1462 1462 ieee80211_node_authorize(wds_ni); -
net80211/ieee80211_linux.h
old new 63 63 64 64 #define IEEE80211_RESCHEDULE schedule 65 65 66 /* Locking */ 67 /* NB: beware, spin_is_locked() is not usefully defined for !(DEBUG || SMP) 68 * because spinlocks do not exist in this configuration. Instead IRQs 69 * or pre-emption are simply disabled, as this is all that is needed. 70 */ 71 66 72 /* 67 73 * Beacon handler locking definitions. 68 74 * Beacon locking … … 85 91 #define IEEE80211_LOCK(_ic) spin_lock(&(_ic)->ic_comlock) 86 92 #define IEEE80211_UNLOCK(_ic) spin_unlock(&(_ic)->ic_comlock) 87 93 88 /* NB: beware, spin_is_locked() is unusable for !SMP */ 89 #if defined(CONFIG_SMP) 94 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 90 95 #define IEEE80211_LOCK_ASSERT(_ic) \ 91 96 KASSERT(spin_is_locked(&(_ic)->ic_comlock),("ieee80211com not locked!")) 92 97 #else 93 98 #define IEEE80211_LOCK_ASSERT(_ic) 94 99 #endif 95 100 101 96 102 #define IEEE80211_VAPS_LOCK_INIT(_ic, _name) \ 97 103 spin_lock_init(&(_ic)->ic_vapslock) 98 104 #define IEEE80211_VAPS_LOCK_DESTROY(_ic) … … 108 114 } while (0) 109 115 #define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic) spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags) 110 116 111 112 /* NB: beware, spin_is_locked() is unusable for !SMP */ 113 #if defined(CONFIG_SMP) 117 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 114 118 #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \ 115 KASSERT(spin_is_locked(&(_ic)->ic_vapslock),("ieee80211com_vaps not locked!")) 119 KASSERT(spin_is_locked(&(_ic)->ic_vapslock), \ 120 ("ieee80211com_vaps not locked!")) 116 121 #else 117 122 #define IEEE80211_VAPS_LOCK_ASSERT(_ic) 118 123 #endif … … 121 126 /* 122 127 * Node locking definitions. 123 128 */ 129 #if 0 130 124 131 typedef spinlock_t ieee80211_node_lock_t; 125 #define IEEE80211_NODE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock) 126 #define IEEE80211_NODE_LOCK_DESTROY(_nt) 127 #define IEEE80211_NODE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock) 128 #define IEEE80211_NODE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock) 129 #define IEEE80211_NODE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock) 130 #define IEEE80211_NODE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock) 131 #define IEEE80211_NODE_LOCK_IRQ(_nt) do { \ 132 #define IEEE80211_NODE_LOCK_INIT(_ni, _name) spin_lock_init(&(_ni)->ni_nodelock) 133 #define IEEE80211_NODE_LOCK_DESTROY(_ni) 134 #if 0 /* We should always be contesting in the same contexts */ 135 #define IEEE80211_NODE_LOCK(_ni) spin_lock(&(_ni)->ni_nodelock) 136 #define IEEE80211_NODE_UNLOCK(_ni) spin_unlock(&(_ni)->ni_nodelock) 137 #define IEEE80211_NODE_LOCK_BH(_ni) spin_lock_bh(&(_ni)->ni_nodelock) 138 #define IEEE80211_NODE_UNLOCK_BH(_ni) spin_unlock_bh(&(_ni)->ni_nodelock) 139 #endif 140 #define IEEE80211_NODE_LOCK_IRQ(_ni) do { \ 132 141 unsigned long __node_lockflags; \ 142 spin_lock_irqsave(&(_ni)->ni_nodelock, __node_lockflags); 143 #define IEEE80211_NODE_UNLOCK_IRQ(_ni) \ 144 spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); \ 145 } while(0) 146 #define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_ni) \ 147 spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); 148 149 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 150 #define IEEE80211_NODE_LOCK_ASSERT(_nt) \ 151 KASSERT(spin_is_locked(&(_ni)->ni_nodelock), \ 152 ("802.11 node not locked!")) 153 #else 154 #define IEEE80211_NODE_LOCK_ASSERT(_ni) 155 #endif 156 157 #endif /* node lock */ 158 159 /* 160 * Node table locking definitions. 161 */ 162 typedef spinlock_t ieee80211_node_table_lock_t; 163 #define IEEE80211_NODE_TABLE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock) 164 #define IEEE80211_NODE_TABLE_LOCK_DESTROY(_nt) 165 #if 0 /* We should always be contesting in the same contexts */ 166 #define IEEE80211_NODE_TABLE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock) 167 #define IEEE80211_NODE_TABLE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock) 168 #define IEEE80211_NODE_TABLE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock) 169 #define IEEE80211_NODE_TABLE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock) 170 #endif 171 #define IEEE80211_NODE_TABLE_LOCK_IRQ(_nt) do { \ 172 unsigned long __node_lockflags; \ 133 173 spin_lock_irqsave(&(_nt)->nt_nodelock, __node_lockflags); 134 #define IEEE80211_NODE_ UNLOCK_IRQ(_nt) \174 #define IEEE80211_NODE_TABLE_UNLOCK_IRQ(_nt) \ 135 175 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); \ 136 176 } while(0) 137 #define IEEE80211_NODE_ UNLOCK_IRQ_EARLY(_nt) \177 #define IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(_nt) \ 138 178 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); 139 179 140 /* NB: beware, *_is_locked() are bogusly defined for UP+!PREEMPT */ 141 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 142 #define IEEE80211_NODE_LOCK_ASSERT(_nt) \ 143 KASSERT(spinlock_is_locked(&(_nt)->nt_nodelock), \ 180 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 181 #define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) \ 182 KASSERT(spin_is_locked(&(_nt)->nt_nodelock), \ 144 183 ("802.11 node table not locked!")) 145 184 #else 146 #define IEEE80211_NODE_ LOCK_ASSERT(_nt)185 #define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) 147 186 #endif 148 187 149 188 /* … … 163 202 #define IEEE80211_SCAN_UNLOCK_IRQ_EARLY(_nt) \ 164 203 spin_unlock_irqrestore(&(_nt)->nt_scanlock, __scan_lockflags); 165 204 166 /* NB: beware, spin_is_locked() is unusable for !SMP */ 167 #if defined(CONFIG_SMP) 205 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 168 206 #define IEEE80211_SCAN_LOCK_ASSERT(_nt) \ 169 207 KASSERT(spin_is_locked(&(_nt)->nt_scanlock), ("scangen not locked!")) 170 208 #else … … 182 220 #define ACL_LOCK_BH(_as) spin_lock_bh(&(_as)->as_lock) 183 221 #define ACL_UNLOCK_BH(_as) spin_unlock_bh(&(_as)->as_lock) 184 222 185 /* NB: beware, spin_is_locked() is unusable for !SMP */ 186 #if defined(CONFIG_SMP) 223 #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked) 187 224 #define ACL_LOCK_ASSERT(_as) \ 188 225 KASSERT(spin_is_locked(&(_as)->as_lock), ("ACL not locked!")) 189 226 #else … … 299 336 * is the last reference, otherwise 0 300 337 * ieee80211_node_refcnt reference count for printing (only) 301 338 */ 339 typedef atomic_t ieee80211_node_ref_count_t; 302 340 #define ieee80211_node_initref(_ni) atomic_set(&(_ni)->ni_refcnt, 1) 303 341 #define ieee80211_node_incref(_ni) atomic_inc(&(_ni)->ni_refcnt) 304 342 #define ieee80211_node_decref(_ni) atomic_dec(&(_ni)->ni_refcnt) … … 379 417 /* msecs_to_jiffies appeared in 2.6.7 and 2.4.29 */ 380 418 #include <linux/delay.h> 381 419 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ 382 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \383 LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)420 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \ 421 LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29) 384 422 385 423 /* The following definitions and inline functions are 386 424 * copied from the kernel src, include/linux/jiffies.h */ -
ath/if_ath.c
old new 159 159 static int ath_desc_alloc(struct ath_softc *); 160 160 static void ath_desc_free(struct ath_softc *); 161 161 static void ath_desc_swap(struct ath_desc *); 162 static struct ieee80211_node *ath_node_alloc(struct ieee80211_node_table *, 163 struct ieee80211vap *); 162 static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *); 164 163 static void ath_node_cleanup(struct ieee80211_node *); 165 164 static void ath_node_free(struct ieee80211_node *); 166 165 static u_int8_t ath_node_getrssi(const struct ieee80211_node *); … … 2462 2461 if (ath_tx_start(sc->sc_dev, ni, bf_ff, bf_ff->bf_skb, 0) == 0) 2463 2462 continue; 2464 2463 bad: 2465 ieee80211_ free_node(ni);2464 ieee80211_unref_node(&ni); 2466 2465 if (bf_ff->bf_skb != NULL) { 2467 2466 dev_kfree_skb(bf_ff->bf_skb); 2468 2467 bf_ff->bf_skb = NULL; … … 2603 2602 ATH_FF_MAGIC_PUT(skb); 2604 2603 2605 2604 /* decrement extra node reference made when an_tx_ffbuf[] was set */ 2606 //ieee80211_ free_node(ni); /* XXX where was it set ? */2605 //ieee80211_unref_node(&ni); /* XXX where was it set ? */ 2607 2606 2608 2607 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF, 2609 2608 "%s: aggregating fast-frame\n", __func__); … … 2662 2661 ff_flushbad: 2663 2662 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF, 2664 2663 "%s: ff stageq flush failure\n", __func__); 2665 ieee80211_ free_node(ni);2664 ieee80211_unref_node(&ni); 2666 2665 if (bf_ff->bf_skb) { 2667 2666 dev_kfree_skb(bf_ff->bf_skb); 2668 2667 bf_ff->bf_skb = NULL; … … 2787 2786 tbf->bf_node = NULL; 2788 2787 2789 2788 if (ni != NULL) 2790 ieee80211_ free_node(ni);2789 ieee80211_unref_node(&ni); 2791 2790 2792 2791 STAILQ_INSERT_TAIL(&sc->sc_txbuf, tbf, bf_list); 2793 2792 } … … 2869 2868 /* fall thru... */ 2870 2869 bad: 2871 2870 if (ni != NULL) 2872 ieee80211_ free_node(ni);2871 ieee80211_unref_node(&ni); 2873 2872 if (bf != NULL) { 2874 2873 bf->bf_skb = NULL; 2875 2874 bf->bf_node = NULL; … … 3255 3254 */ 3256 3255 ni = sc->sc_keyixmap[keyix]; 3257 3256 if (ni != NULL) { 3258 ieee80211_ free_node(ni);3257 ieee80211_unref_node(&ni); 3259 3258 sc->sc_keyixmap[keyix] = NULL; 3260 3259 } 3261 3260 /* … … 3266 3265 ath_hal_keyreset(ah, keyix + 32); /* RX key */ 3267 3266 ni = sc->sc_keyixmap[keyix + 32]; 3268 3267 if (ni != NULL) { /* as above... */ 3269 ieee80211_ free_node(ni);3268 ieee80211_unref_node(&ni); 3270 3269 sc->sc_keyixmap[keyix + 32] = NULL; 3271 3270 } 3272 3271 } … … 3279 3278 ath_hal_keyreset(ah, keyix + rxkeyoff); 3280 3279 ni = sc->sc_keyixmap[keyix + rxkeyoff]; 3281 3280 if (ni != NULL) { /* as above... */ 3282 ieee80211_ free_node(ni);3281 ieee80211_unref_node(&ni); 3283 3282 sc->sc_keyixmap[keyix + rxkeyoff] = NULL; 3284 3283 } 3285 3284 } … … 3835 3834 dev_kfree_skb(bf->bf_skb); 3836 3835 bf->bf_skb = NULL; 3837 3836 } 3838 if (bf->bf_node != NULL) { 3839 ieee80211_free_node(bf->bf_node); 3840 bf->bf_node = NULL; 3841 } 3837 if (bf->bf_node != NULL) 3838 ieee80211_unref_node(&bf->bf_node); 3842 3839 3843 3840 /* 3844 3841 * NB: the beacon data buffer must be 32-bit aligned; … … 4382 4379 dev_kfree_skb(bf->bf_skb); 4383 4380 bf->bf_skb = NULL; 4384 4381 } 4385 if (bf->bf_node != NULL) { 4386 ieee80211_free_node(bf->bf_node); 4387 bf->bf_node = NULL; 4388 } 4382 if (bf->bf_node != NULL) 4383 ieee80211_unref_node(&bf->bf_node); 4389 4384 STAILQ_INSERT_TAIL(&sc->sc_bbuf, bf, bf_list); 4390 4385 } 4391 4386 … … 4404 4399 dev_kfree_skb(bf->bf_skb); 4405 4400 bf->bf_skb = NULL; 4406 4401 } 4407 if (bf->bf_node != NULL) { 4408 ieee80211_free_node(bf->bf_node); 4409 bf->bf_node = NULL; 4410 } 4402 if (bf->bf_node != NULL) 4403 ieee80211_unref_node(&bf->bf_node); 4411 4404 } 4412 4405 } 4413 4406 … … 4692 4685 /* 4693 4686 * Reclaim node reference. 4694 4687 */ 4695 ieee80211_ free_node(ni);4688 ieee80211_unref_node(&ni); 4696 4689 } 4697 4690 } 4698 4691 … … 4751 4744 } 4752 4745 4753 4746 static struct ieee80211_node * 4754 ath_node_alloc(struct ieee80211 _node_table *nt,struct ieee80211vap *vap)4747 ath_node_alloc(struct ieee80211vap *vap) 4755 4748 { 4756 struct ath_softc *sc = nt->nt_ic->ic_dev->priv;4749 struct ath_softc *sc = vap->iv_ic->ic_dev->priv; 4757 4750 const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space; 4758 4751 struct ath_node *an; 4759 4752 4760 4753 an = kmalloc(space, GFP_ATOMIC); 4761 if (an == NULL) 4754 if (an != NULL) { 4755 memset(an, 0, space); 4756 an->an_decomp_index = INVALID_DECOMP_INDEX; 4757 an->an_avgrssi = ATH_RSSI_DUMMY_MARKER; 4758 an->an_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; 4759 an->an_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; 4760 an->an_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; 4761 /* 4762 * ath_rate_node_init needs a vap pointer in node 4763 * to decide which mgt rate to use 4764 */ 4765 an->an_node.ni_vap = vap; 4766 sc->sc_rc->ops->node_init(sc, an); 4767 4768 /* U-APSD init */ 4769 STAILQ_INIT(&an->an_uapsd_q); 4770 an->an_uapsd_qdepth = 0; 4771 STAILQ_INIT(&an->an_uapsd_overflowq); 4772 an->an_uapsd_overflowqdepth = 0; 4773 ATH_NODE_UAPSD_LOCK_INIT(an); 4774 4775 DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an); 4776 return &an->an_node; 4777 } else { 4762 4778 return NULL; 4763 memset(an, 0, space); 4764 an->an_decomp_index = INVALID_DECOMP_INDEX; 4765 an->an_avgrssi = ATH_RSSI_DUMMY_MARKER; 4766 an->an_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; 4767 an->an_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; 4768 an->an_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; 4769 /* 4770 * ath_rate_node_init needs a VAP pointer in node 4771 * to decide which mgt rate to use 4772 */ 4773 an->an_node.ni_vap = vap; 4774 sc->sc_rc->ops->node_init(sc, an); 4775 4776 /* U-APSD init */ 4777 STAILQ_INIT(&an->an_uapsd_q); 4778 an->an_uapsd_qdepth = 0; 4779 STAILQ_INIT(&an->an_uapsd_overflowq); 4780 an->an_uapsd_overflowqdepth = 0; 4781 ATH_NODE_UAPSD_LOCK_INIT(an); 4782 4783 DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an); 4784 return &an->an_node; 4779 } 4785 4780 } 4786 4781 4787 4782 static void … … 4791 4786 struct ath_softc *sc = ni->ni_ic->ic_dev->priv; 4792 4787 struct ath_node *an = ATH_NODE(ni); 4793 4788 struct ath_buf *bf; 4789 struct ieee80211_cb *cb = NULL; 4794 4790 4795 4791 /* 4796 4792 * U-APSD cleanup … … 4805 4801 while (an->an_uapsd_qdepth) { 4806 4802 bf = STAILQ_FIRST(&an->an_uapsd_q); 4807 4803 STAILQ_REMOVE_HEAD(&an->an_uapsd_q, bf_list); 4808 bf->bf_desc->ds_link = (u_int32_t)NULL;4809 4804 4805 cb = (struct ieee80211_cb *) bf->bf_skb->cb; 4806 ieee80211_unref_node(&cb->ni); 4810 4807 dev_kfree_skb_any(bf->bf_skb); 4808 4809 bf->bf_desc->ds_link = 0; 4811 4810 bf->bf_skb = NULL; 4812 4811 bf->bf_node = NULL; 4812 4813 4813 ATH_TXBUF_LOCK_IRQ(sc); 4814 4814 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); 4815 4815 ATH_TXBUF_UNLOCK_IRQ(sc); 4816 ieee80211_free_node(ni);4817 4816 4818 4817 an->an_uapsd_qdepth--; 4819 4818 } … … 4821 4820 while (an->an_uapsd_overflowqdepth) { 4822 4821 bf = STAILQ_FIRST(&an->an_uapsd_overflowq); 4823 4822 STAILQ_REMOVE_HEAD(&an->an_uapsd_overflowq, bf_list); 4824 bf->bf_desc->ds_link = (u_int32_t)NULL;4825 4823 4824 cb = (struct ieee80211_cb *) bf->bf_skb->cb; 4825 ieee80211_unref_node(&cb->ni); 4826 4826 dev_kfree_skb_any(bf->bf_skb); 4827 4827 4828 bf->bf_skb = NULL; 4828 4829 bf->bf_node = NULL; 4830 bf->bf_desc->ds_link = 0; 4831 4829 4832 ATH_TXBUF_LOCK_IRQ(sc); 4830 4833 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); 4831 4834 ATH_TXBUF_UNLOCK_IRQ(sc); 4832 ieee80211_free_node(ni);4833 4835 4834 4836 an->an_uapsd_overflowqdepth--; 4835 4837 } 4836 4838 4839 // Clean up node-specific rate things - this currently appears to always be a no-op 4840 sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni)); 4841 4837 4842 ATH_NODE_UAPSD_LOCK_IRQ(an); 4838 4843 sc->sc_node_cleanup(ni); 4839 4844 ATH_NODE_UAPSD_UNLOCK_IRQ(an); … … 4844 4849 { 4845 4850 struct ath_softc *sc = ni->ni_ic->ic_dev->priv; 4846 4851 4847 sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni));4848 4852 sc->sc_node_free(ni); 4849 4853 #ifdef ATH_SUPERG_XR 4850 4854 ath_grppoll_period_update(sc); … … 5727 5731 ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi); 5728 5732 type = ieee80211_input(ni, skb, 5729 5733 ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp); 5730 ieee80211_ free_node(ni);5734 ieee80211_unref_node(&ni); 5731 5735 } else { 5732 5736 /* 5733 5737 * No key index or no entry, do a lookup and … … 5752 5756 if (keyix != IEEE80211_KEYIX_NONE && 5753 5757 sc->sc_keyixmap[keyix] == NULL) 5754 5758 sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni); 5755 ieee80211_ free_node(ni);5759 ieee80211_unref_node(&ni); 5756 5760 } else 5757 5761 type = ieee80211_input_all(ic, skb, 5758 5762 ds->ds_rxstat.rs_rssi, … … 6552 6556 STAILQ_REMOVE_HEAD(&an->an_uapsd_q, bf_list); 6553 6557 dev_kfree_skb(lastbuf->bf_skb); 6554 6558 lastbuf->bf_skb = NULL; 6555 ieee80211_free_node(lastbuf->bf_node); 6556 lastbuf->bf_node = NULL; 6559 ieee80211_unref_node(&lastbuf->bf_node); 6557 6560 ATH_TXBUF_LOCK_IRQ(sc); 6558 6561 STAILQ_INSERT_TAIL(&sc->sc_txbuf, lastbuf, bf_list); 6559 6562 ATH_TXBUF_UNLOCK_IRQ(sc); … … 7304 7307 * this is a DEAUTH message that was sent and the 7305 7308 * node was timed out due to inactivity. 7306 7309 */ 7307 ieee80211_ free_node(ni);7310 ieee80211_unref_node(&ni); 7308 7311 } 7309 7312 7310 7313 bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr, … … 7552 7555 } 7553 7556 #endif /* ATH_SUPERG_FF */ 7554 7557 if (bf->bf_node) 7555 ieee80211_ free_node(bf->bf_node);7558 ieee80211_unref_node(&bf->bf_node); 7556 7559 7557 7560 bf->bf_skb = NULL; 7558 7561 bf->bf_node = NULL;
