ieee80211_scan_sta.c (193655) | ieee80211_scan_sta.c (195618) |
---|---|
1/*- 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> |
27__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_scan_sta.c 193655 2009-06-07 22:00:22Z sam $"); | 27__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_scan_sta.c 195618 2009-07-11 15:02:45Z rpaulo $"); |
28 29/* 30 * IEEE 802.11 station scanning support. 31 */ 32#include "opt_wlan.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> --- 7 unchanged lines hidden (view full) --- 43#include <net/ethernet.h> 44 45#include <net80211/ieee80211_var.h> 46#include <net80211/ieee80211_input.h> 47#include <net80211/ieee80211_regdomain.h> 48#ifdef IEEE80211_SUPPORT_TDMA 49#include <net80211/ieee80211_tdma.h> 50#endif | 28 29/* 30 * IEEE 802.11 station scanning support. 31 */ 32#include "opt_wlan.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> --- 7 unchanged lines hidden (view full) --- 43#include <net/ethernet.h> 44 45#include <net80211/ieee80211_var.h> 46#include <net80211/ieee80211_input.h> 47#include <net80211/ieee80211_regdomain.h> 48#ifdef IEEE80211_SUPPORT_TDMA 49#include <net80211/ieee80211_tdma.h> 50#endif |
51#ifdef IEEE80211_SUPPORT_MESH 52#include <net80211/ieee80211_mesh.h> 53#endif |
|
51 52#include <net/bpf.h> 53 54/* 55 * Parameters for managing cache entries: 56 * 57 * o a station with STA_FAILS_MAX failures is not considered 58 * when picking a candidate --- 48 unchanged lines hidden (view full) --- 107 108static void sta_flush_table(struct sta_table *); 109/* 110 * match_bss returns a bitmask describing if an entry is suitable 111 * for use. If non-zero the entry was deemed not suitable and it's 112 * contents explains why. The following flags are or'd to to this 113 * mask and can be used to figure out why the entry was rejected. 114 */ | 54 55#include <net/bpf.h> 56 57/* 58 * Parameters for managing cache entries: 59 * 60 * o a station with STA_FAILS_MAX failures is not considered 61 * when picking a candidate --- 48 unchanged lines hidden (view full) --- 110 111static void sta_flush_table(struct sta_table *); 112/* 113 * match_bss returns a bitmask describing if an entry is suitable 114 * for use. If non-zero the entry was deemed not suitable and it's 115 * contents explains why. The following flags are or'd to to this 116 * mask and can be used to figure out why the entry was rejected. 117 */ |
115#define MATCH_CHANNEL 0x0001 /* channel mismatch */ 116#define MATCH_CAPINFO 0x0002 /* capabilities mismatch, e.g. no ess */ 117#define MATCH_PRIVACY 0x0004 /* privacy mismatch */ 118#define MATCH_RATE 0x0008 /* rate set mismatch */ 119#define MATCH_SSID 0x0010 /* ssid mismatch */ 120#define MATCH_BSSID 0x0020 /* bssid mismatch */ 121#define MATCH_FAILS 0x0040 /* too many failed auth attempts */ 122#define MATCH_NOTSEEN 0x0080 /* not seen in recent scans */ 123#define MATCH_RSSI 0x0100 /* rssi deemed too low to use */ 124#define MATCH_CC 0x0200 /* country code mismatch */ 125#define MATCH_TDMA_NOIE 0x0400 /* no TDMA ie */ 126#define MATCH_TDMA_NOTMASTER 0x0800 /* not TDMA master */ 127#define MATCH_TDMA_NOSLOT 0x1000 /* all TDMA slots occupied */ 128#define MATCH_TDMA_LOCAL 0x2000 /* local address */ 129#define MATCH_TDMA_VERSION 0x4000 /* protocol version mismatch */ | 118#define MATCH_CHANNEL 0x00001 /* channel mismatch */ 119#define MATCH_CAPINFO 0x00002 /* capabilities mismatch, e.g. no ess */ 120#define MATCH_PRIVACY 0x00004 /* privacy mismatch */ 121#define MATCH_RATE 0x00008 /* rate set mismatch */ 122#define MATCH_SSID 0x00010 /* ssid mismatch */ 123#define MATCH_BSSID 0x00020 /* bssid mismatch */ 124#define MATCH_FAILS 0x00040 /* too many failed auth attempts */ 125#define MATCH_NOTSEEN 0x00080 /* not seen in recent scans */ 126#define MATCH_RSSI 0x00100 /* rssi deemed too low to use */ 127#define MATCH_CC 0x00200 /* country code mismatch */ 128#define MATCH_TDMA_NOIE 0x00400 /* no TDMA ie */ 129#define MATCH_TDMA_NOTMASTER 0x00800 /* not TDMA master */ 130#define MATCH_TDMA_NOSLOT 0x01000 /* all TDMA slots occupied */ 131#define MATCH_TDMA_LOCAL 0x02000 /* local address */ 132#define MATCH_TDMA_VERSION 0x04000 /* protocol version mismatch */ 133#define MATCH_MESH_NOID 0x10000 /* no MESHID ie */ 134#define MATCH_MESHID 0x20000 /* meshid mismatch */ |
130static int match_bss(struct ieee80211vap *, 131 const struct ieee80211_scan_state *, struct sta_entry *, int); 132static void adhoc_age(struct ieee80211_scan_state *); 133 134static __inline int 135isocmp(const uint8_t cc1[], const uint8_t cc2[]) 136{ 137 return (cc1[0] == cc2[0] && cc1[1] == cc2[1]); 138} 139 140/* number of references from net80211 layer */ 141static int nrefs = 0; | 135static int match_bss(struct ieee80211vap *, 136 const struct ieee80211_scan_state *, struct sta_entry *, int); 137static void adhoc_age(struct ieee80211_scan_state *); 138 139static __inline int 140isocmp(const uint8_t cc1[], const uint8_t cc2[]) 141{ 142 return (cc1[0] == cc2[0] && cc1[1] == cc2[1]); 143} 144 145/* number of references from net80211 layer */ 146static int nrefs = 0; |
147/* 148 * Module glue. 149 */ 150IEEE80211_SCANNER_MODULE(sta, 1); |
|
142 143/* 144 * Attach prior to any scanning work. 145 */ 146static int 147sta_attach(struct ieee80211_scan_state *ss) 148{ 149 struct sta_table *st; --- 126 unchanged lines hidden (view full) --- 276 */ 277 IEEE80211_RSSI_LPF(se->se_avgrssi, rssi); 278 ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi); 279 ise->se_noise = noise; 280 } 281 memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); 282 ise->se_intval = sp->bintval; 283 ise->se_capinfo = sp->capinfo; | 151 152/* 153 * Attach prior to any scanning work. 154 */ 155static int 156sta_attach(struct ieee80211_scan_state *ss) 157{ 158 struct sta_table *st; --- 126 unchanged lines hidden (view full) --- 285 */ 286 IEEE80211_RSSI_LPF(se->se_avgrssi, rssi); 287 ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi); 288 ise->se_noise = noise; 289 } 290 memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); 291 ise->se_intval = sp->bintval; 292 ise->se_capinfo = sp->capinfo; |
293#ifdef IEEE80211_SUPPORT_MESH 294 if (sp->meshid != NULL && sp->meshid[1] != 0) 295 memcpy(ise->se_meshid, sp->meshid, 2+sp->meshid[1]); 296#endif |
|
284 /* 285 * Beware of overriding se_chan for frames seen 286 * off-channel; this can cause us to attempt an 287 * association on the wrong channel. 288 */ 289 if (sp->status & IEEE80211_BPARSE_OFFCHAN) { 290 struct ieee80211_channel *c; 291 /* --- 598 unchanged lines hidden (view full) --- 890back: 891 if (okrate == 0 || ucastrate != fixedrate) 892 return badrate | IEEE80211_RATE_BASIC; 893 else 894 return RV(okrate); 895#undef RV 896} 897 | 297 /* 298 * Beware of overriding se_chan for frames seen 299 * off-channel; this can cause us to attempt an 300 * association on the wrong channel. 301 */ 302 if (sp->status & IEEE80211_BPARSE_OFFCHAN) { 303 struct ieee80211_channel *c; 304 /* --- 598 unchanged lines hidden (view full) --- 903back: 904 if (okrate == 0 || ucastrate != fixedrate) 905 return badrate | IEEE80211_RATE_BASIC; 906 else 907 return RV(okrate); 908#undef RV 909} 910 |
911static __inline int 912match_id(const uint8_t *ie, const uint8_t *val, int len) 913{ 914 return (ie[1] == len && memcmp(ie+2, val, len) == 0); 915} 916 |
|
898static int 899match_ssid(const uint8_t *ie, 900 int nssid, const struct ieee80211_scan_ssid ssids[]) 901{ 902 int i; 903 904 for (i = 0; i < nssid; i++) { | 917static int 918match_ssid(const uint8_t *ie, 919 int nssid, const struct ieee80211_scan_ssid ssids[]) 920{ 921 int i; 922 923 for (i = 0; i < nssid; i++) { |
905 if (ie[1] == ssids[i].len && 906 memcmp(ie+2, ssids[i].ssid, ie[1]) == 0) | 924 if (match_id(ie, ssids[i].ssid, ssids[i].len)) |
907 return 1; 908 } 909 return 0; 910} 911 912#ifdef IEEE80211_SUPPORT_TDMA 913static int 914tdma_isfull(const struct ieee80211_tdma_param *tdma) --- 66 unchanged lines hidden (view full) --- 981 else if (tdma_isfull(tdma)) 982 fail |= MATCH_TDMA_NOSLOT; 983#if 0 984 else if (ieee80211_local_address(se->se_macaddr)) 985 fail |= MATCH_TDMA_LOCAL; 986#endif 987 } 988#endif /* IEEE80211_SUPPORT_TDMA */ | 925 return 1; 926 } 927 return 0; 928} 929 930#ifdef IEEE80211_SUPPORT_TDMA 931static int 932tdma_isfull(const struct ieee80211_tdma_param *tdma) --- 66 unchanged lines hidden (view full) --- 999 else if (tdma_isfull(tdma)) 1000 fail |= MATCH_TDMA_NOSLOT; 1001#if 0 1002 else if (ieee80211_local_address(se->se_macaddr)) 1003 fail |= MATCH_TDMA_LOCAL; 1004#endif 1005 } 1006#endif /* IEEE80211_SUPPORT_TDMA */ |
1007#ifdef IEEE80211_SUPPORT_MESH 1008 } else if (vap->iv_opmode == IEEE80211_M_MBSS) { 1009 const struct ieee80211_mesh_state *ms = vap->iv_mesh; 1010 /* 1011 * Mesh nodes have IBSS & ESS bits in capinfo turned off 1012 * and two special ie's that must be present. 1013 */ 1014 if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) 1015 fail |= MATCH_CAPINFO; 1016 else if (se->se_meshid == NULL) 1017 fail |= MATCH_MESH_NOID; 1018 else if (ms->ms_idlen != 0 && 1019 match_id(se->se_meshid, ms->ms_id, ms->ms_idlen)) 1020 fail |= MATCH_MESHID; |
|
989 } else { | 1021 } else { |
1022#endif |
|
990 if ((se->se_capinfo & IEEE80211_CAPINFO_ESS) == 0) 991 fail |= MATCH_CAPINFO; 992 /* 993 * If 11d is enabled and we're attempting to join a bss 994 * that advertises it's country code then compare our 995 * current settings to what we fetched from the country ie. 996 * If our country code is unspecified or different then do 997 * not attempt to join the bss. We should have already --- 67 unchanged lines hidden (view full) --- 1065 fail & MATCH_CC ? '$' : 1066#ifdef IEEE80211_SUPPORT_TDMA 1067 fail & MATCH_TDMA_NOIE ? '&' : 1068 fail & MATCH_TDMA_VERSION ? 'v' : 1069 fail & MATCH_TDMA_NOTMASTER ? 's' : 1070 fail & MATCH_TDMA_NOSLOT ? 'f' : 1071 fail & MATCH_TDMA_LOCAL ? 'l' : 1072#endif | 1023 if ((se->se_capinfo & IEEE80211_CAPINFO_ESS) == 0) 1024 fail |= MATCH_CAPINFO; 1025 /* 1026 * If 11d is enabled and we're attempting to join a bss 1027 * that advertises it's country code then compare our 1028 * current settings to what we fetched from the country ie. 1029 * If our country code is unspecified or different then do 1030 * not attempt to join the bss. We should have already --- 67 unchanged lines hidden (view full) --- 1098 fail & MATCH_CC ? '$' : 1099#ifdef IEEE80211_SUPPORT_TDMA 1100 fail & MATCH_TDMA_NOIE ? '&' : 1101 fail & MATCH_TDMA_VERSION ? 'v' : 1102 fail & MATCH_TDMA_NOTMASTER ? 's' : 1103 fail & MATCH_TDMA_NOSLOT ? 'f' : 1104 fail & MATCH_TDMA_LOCAL ? 'l' : 1105#endif |
1106 fail & MATCH_MESH_NOID ? 'm' : |
|
1073 fail ? '-' : '+', ether_sprintf(se->se_macaddr)); 1074 printf(" %s%c", ether_sprintf(se->se_bssid), 1075 fail & MATCH_BSSID ? '!' : ' '); 1076 printf(" %3d%c", ieee80211_chan2ieee(ic, se->se_chan), 1077 fail & MATCH_CHANNEL ? '!' : ' '); 1078 printf(" %+4d%c", se->se_rssi, fail & MATCH_RSSI ? '!' : ' '); 1079 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, 1080 fail & MATCH_RATE ? '!' : ' '); 1081 printf(" %4s%c", 1082 (se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : 1083 (se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : "", 1084 fail & MATCH_CAPINFO ? '!' : ' '); 1085 printf(" %3s%c ", 1086 (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ? 1087 "wep" : "no", 1088 fail & MATCH_PRIVACY ? '!' : ' '); 1089 ieee80211_print_essid(se->se_ssid+2, se->se_ssid[1]); | 1107 fail ? '-' : '+', ether_sprintf(se->se_macaddr)); 1108 printf(" %s%c", ether_sprintf(se->se_bssid), 1109 fail & MATCH_BSSID ? '!' : ' '); 1110 printf(" %3d%c", ieee80211_chan2ieee(ic, se->se_chan), 1111 fail & MATCH_CHANNEL ? '!' : ' '); 1112 printf(" %+4d%c", se->se_rssi, fail & MATCH_RSSI ? '!' : ' '); 1113 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, 1114 fail & MATCH_RATE ? '!' : ' '); 1115 printf(" %4s%c", 1116 (se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : 1117 (se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : "", 1118 fail & MATCH_CAPINFO ? '!' : ' '); 1119 printf(" %3s%c ", 1120 (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ? 1121 "wep" : "no", 1122 fail & MATCH_PRIVACY ? '!' : ' '); 1123 ieee80211_print_essid(se->se_ssid+2, se->se_ssid[1]); |
1090 printf("%s\n", fail & MATCH_SSID ? "!" : ""); | 1124 printf("%s\n", fail & (MATCH_SSID | MATCH_MESHID) ? "!" : ""); |
1091 } 1092#endif 1093 return fail; 1094} 1095 1096static void 1097sta_update_notseen(struct sta_table *st) 1098{ --- 311 unchanged lines hidden (view full) --- 1410 .scan_end = sta_pick_bss, 1411 .scan_flush = sta_flush, 1412 .scan_add = sta_add, 1413 .scan_age = sta_age, 1414 .scan_iterate = sta_iterate, 1415 .scan_assoc_fail = sta_assoc_fail, 1416 .scan_assoc_success = sta_assoc_success, 1417}; | 1125 } 1126#endif 1127 return fail; 1128} 1129 1130static void 1131sta_update_notseen(struct sta_table *st) 1132{ --- 311 unchanged lines hidden (view full) --- 1444 .scan_end = sta_pick_bss, 1445 .scan_flush = sta_flush, 1446 .scan_add = sta_add, 1447 .scan_age = sta_age, 1448 .scan_iterate = sta_iterate, 1449 .scan_assoc_fail = sta_assoc_fail, 1450 .scan_assoc_success = sta_assoc_success, 1451}; |
1452IEEE80211_SCANNER_ALG(sta, IEEE80211_M_STA, sta_default); |
|
1418 1419/* 1420 * Adhoc mode-specific support. 1421 */ 1422 1423static const uint16_t adhocWorld[] = /* 36, 40, 44, 48 */ 1424{ 5180, 5200, 5220, 5240 }; 1425static const uint16_t adhocFcc3[] = /* 36, 40, 44, 48 145, 149, 153, 157, 161, 165 */ --- 83 unchanged lines hidden (view full) --- 1509static int 1510adhoc_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) 1511{ 1512 struct sta_table *st = ss->ss_priv; 1513 struct sta_entry *selbs; 1514 struct ieee80211_channel *chan; 1515 1516 KASSERT(vap->iv_opmode == IEEE80211_M_IBSS || | 1453 1454/* 1455 * Adhoc mode-specific support. 1456 */ 1457 1458static const uint16_t adhocWorld[] = /* 36, 40, 44, 48 */ 1459{ 5180, 5200, 5220, 5240 }; 1460static const uint16_t adhocFcc3[] = /* 36, 40, 44, 48 145, 149, 153, 157, 161, 165 */ --- 83 unchanged lines hidden (view full) --- 1544static int 1545adhoc_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) 1546{ 1547 struct sta_table *st = ss->ss_priv; 1548 struct sta_entry *selbs; 1549 struct ieee80211_channel *chan; 1550 1551 KASSERT(vap->iv_opmode == IEEE80211_M_IBSS || |
1517 vap->iv_opmode == IEEE80211_M_AHDEMO, | 1552 vap->iv_opmode == IEEE80211_M_AHDEMO || 1553 vap->iv_opmode == IEEE80211_M_MBSS, |
1518 ("wrong opmode %u", vap->iv_opmode)); 1519 1520 if (st->st_newscan) { 1521 sta_update_notseen(st); 1522 st->st_newscan = 0; 1523 } 1524 if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { 1525 /* --- 99 unchanged lines hidden (view full) --- 1625 .scan_flush = sta_flush, 1626 .scan_pickchan = adhoc_pick_channel, 1627 .scan_add = sta_add, 1628 .scan_age = adhoc_age, 1629 .scan_iterate = sta_iterate, 1630 .scan_assoc_fail = sta_assoc_fail, 1631 .scan_assoc_success = sta_assoc_success, 1632}; | 1554 ("wrong opmode %u", vap->iv_opmode)); 1555 1556 if (st->st_newscan) { 1557 sta_update_notseen(st); 1558 st->st_newscan = 0; 1559 } 1560 if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { 1561 /* --- 99 unchanged lines hidden (view full) --- 1661 .scan_flush = sta_flush, 1662 .scan_pickchan = adhoc_pick_channel, 1663 .scan_add = sta_add, 1664 .scan_age = adhoc_age, 1665 .scan_iterate = sta_iterate, 1666 .scan_assoc_fail = sta_assoc_fail, 1667 .scan_assoc_success = sta_assoc_success, 1668}; |
1669IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default); 1670IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default); |
|
1633 1634static void 1635ap_force_promisc(struct ieee80211com *ic) 1636{ 1637 struct ifnet *ifp = ic->ic_ifp; 1638 1639 IEEE80211_LOCK(ic); 1640 /* set interface into promiscuous mode */ --- 135 unchanged lines hidden (view full) --- 1776 .scan_flush = sta_flush, 1777 .scan_pickchan = ap_pick_channel, 1778 .scan_add = sta_add, 1779 .scan_age = adhoc_age, 1780 .scan_iterate = sta_iterate, 1781 .scan_assoc_success = sta_assoc_success, 1782 .scan_assoc_fail = sta_assoc_fail, 1783}; | 1671 1672static void 1673ap_force_promisc(struct ieee80211com *ic) 1674{ 1675 struct ifnet *ifp = ic->ic_ifp; 1676 1677 IEEE80211_LOCK(ic); 1678 /* set interface into promiscuous mode */ --- 135 unchanged lines hidden (view full) --- 1814 .scan_flush = sta_flush, 1815 .scan_pickchan = ap_pick_channel, 1816 .scan_add = sta_add, 1817 .scan_age = adhoc_age, 1818 .scan_iterate = sta_iterate, 1819 .scan_assoc_success = sta_assoc_success, 1820 .scan_assoc_fail = sta_assoc_fail, 1821}; |
1822IEEE80211_SCANNER_ALG(ap, IEEE80211_M_HOSTAP, ap_default); |
|
1784 | 1823 |
1824#ifdef IEEE80211_SUPPORT_MESH |
|
1785/* | 1825/* |
1786 * Module glue. | 1826 * Pick an mbss network to join or find a channel 1827 * to use to start an mbss network. |
1787 */ | 1828 */ |
1788IEEE80211_SCANNER_MODULE(sta, 1); 1789IEEE80211_SCANNER_ALG(sta, IEEE80211_M_STA, sta_default); 1790IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default); 1791IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default); 1792IEEE80211_SCANNER_ALG(ap, IEEE80211_M_HOSTAP, ap_default); | 1829static int 1830mesh_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) 1831{ 1832 struct sta_table *st = ss->ss_priv; 1833 struct ieee80211_mesh_state *ms = vap->iv_mesh; 1834 struct sta_entry *selbs; 1835 struct ieee80211_channel *chan; 1836 1837 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, 1838 ("wrong opmode %u", vap->iv_opmode)); 1839 1840 if (st->st_newscan) { 1841 sta_update_notseen(st); 1842 st->st_newscan = 0; 1843 } 1844 if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { 1845 /* 1846 * Manual/background scan, don't select+join the 1847 * bss, just return. The scanning framework will 1848 * handle notification that this has completed. 1849 */ 1850 ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; 1851 return 1; 1852 } 1853 /* 1854 * Automatic sequencing; look for a candidate and 1855 * if found join the network. 1856 */ 1857 /* NB: unlocked read should be ok */ 1858 if (TAILQ_FIRST(&st->st_entry) == NULL) { 1859 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 1860 "%s: no scan candidate\n", __func__); 1861 if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) 1862 return 0; 1863notfound: 1864 if (ms->ms_idlen != 0) { 1865 /* 1866 * No existing mbss network to join and we have 1867 * a meshid; start one up. If no channel was 1868 * specified, try to select a channel. 1869 */ 1870 if (vap->iv_des_chan == IEEE80211_CHAN_ANYC || 1871 IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { 1872 struct ieee80211com *ic = vap->iv_ic; 1873 1874 chan = adhoc_pick_channel(ss, 0); 1875 if (chan != NULL) 1876 chan = ieee80211_ht_adjust_channel(ic, 1877 chan, vap->iv_flags_ht); 1878 } else 1879 chan = vap->iv_des_chan; 1880 if (chan != NULL) { 1881 ieee80211_create_ibss(vap, chan); 1882 return 1; 1883 } 1884 } 1885 /* 1886 * If nothing suitable was found decrement 1887 * the failure counts so entries will be 1888 * reconsidered the next time around. We 1889 * really want to do this only for sta's 1890 * where we've previously had some success. 1891 */ 1892 sta_dec_fails(st); 1893 st->st_newscan = 1; 1894 return 0; /* restart scan */ 1895 } 1896 selbs = select_bss(ss, vap, IEEE80211_MSG_SCAN); 1897 if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) 1898 return (selbs != NULL); 1899 if (selbs == NULL) 1900 goto notfound; 1901 chan = selbs->base.se_chan; 1902 if (selbs->se_flags & STA_DEMOTE11B) 1903 chan = demote11b(vap, chan); 1904 if (!ieee80211_sta_join(vap, chan, &selbs->base)) 1905 goto notfound; 1906 return 1; /* terminate scan */ 1907} 1908 1909static const struct ieee80211_scanner mesh_default = { 1910 .scan_name = "default", 1911 .scan_attach = sta_attach, 1912 .scan_detach = sta_detach, 1913 .scan_start = adhoc_start, 1914 .scan_restart = sta_restart, 1915 .scan_cancel = sta_cancel, 1916 .scan_end = mesh_pick_bss, 1917 .scan_flush = sta_flush, 1918 .scan_pickchan = adhoc_pick_channel, 1919 .scan_add = sta_add, 1920 .scan_age = adhoc_age, 1921 .scan_iterate = sta_iterate, 1922 .scan_assoc_fail = sta_assoc_fail, 1923 .scan_assoc_success = sta_assoc_success, 1924}; 1925IEEE80211_SCANNER_ALG(mesh, IEEE80211_M_MBSS, mesh_default); 1926#endif /* IEEE80211_SUPPORT_MESH */ |