1 #include <linux/ieee80211.h> 2 #include <linux/export.h> 3 #include <net/cfg80211.h> 4 #include "nl80211.h" 5 #include "core.h" 6 7 /* Default values, timeouts in ms */ 8 #define MESH_TTL 31 9 #define MESH_DEFAULT_ELEMENT_TTL 31 10 #define MESH_MAX_RETR 3 11 #define MESH_RET_T 100 12 #define MESH_CONF_T 100 13 #define MESH_HOLD_T 100 14 15 #define MESH_PATH_TIMEOUT 5000 16 #define MESH_RANN_INTERVAL 5000 17 #define MESH_PATH_TO_ROOT_TIMEOUT 6000 18 #define MESH_ROOT_INTERVAL 5000 19 #define MESH_ROOT_CONFIRMATION_INTERVAL 2000 20 21 /* 22 * Minimum interval between two consecutive PREQs originated by the same 23 * interface 24 */ 25 #define MESH_PREQ_MIN_INT 10 26 #define MESH_PERR_MIN_INT 100 27 #define MESH_DIAM_TRAVERSAL_TIME 50 28 29 #define MESH_RSSI_THRESHOLD 0 30 31 /* 32 * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds 33 * before timing out. This way it will remain ACTIVE and no data frames 34 * will be unnecessarily held in the pending queue. 35 */ 36 #define MESH_PATH_REFRESH_TIME 1000 37 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) 38 39 /* Default maximum number of established plinks per interface */ 40 #define MESH_MAX_ESTAB_PLINKS 32 41 42 #define MESH_MAX_PREQ_RETRIES 4 43 44 #define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50 45 46 const struct mesh_config default_mesh_config = { 47 .dot11MeshRetryTimeout = MESH_RET_T, 48 .dot11MeshConfirmTimeout = MESH_CONF_T, 49 .dot11MeshHoldingTimeout = MESH_HOLD_T, 50 .dot11MeshMaxRetries = MESH_MAX_RETR, 51 .dot11MeshTTL = MESH_TTL, 52 .element_ttl = MESH_DEFAULT_ELEMENT_TTL, 53 .auto_open_plinks = true, 54 .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, 55 .dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX, 56 .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, 57 .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, 58 .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT, 59 .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, 60 .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, 61 .path_refresh_time = MESH_PATH_REFRESH_TIME, 62 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 63 .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, 64 .dot11MeshGateAnnouncementProtocol = false, 65 .dot11MeshForwarding = true, 66 .rssi_threshold = MESH_RSSI_THRESHOLD, 67 .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, 68 .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, 69 .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, 70 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, 71 }; 72 73 const struct mesh_setup default_mesh_setup = { 74 /* cfg80211_join_mesh() will pick a channel if needed */ 75 .channel = NULL, 76 .channel_type = NL80211_CHAN_NO_HT, 77 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 78 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 79 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 80 .ie = NULL, 81 .ie_len = 0, 82 .is_secure = false, 83 }; 84 85 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 86 struct net_device *dev, 87 struct mesh_setup *setup, 88 const struct mesh_config *conf) 89 { 90 struct wireless_dev *wdev = dev->ieee80211_ptr; 91 int err; 92 93 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); 94 95 ASSERT_WDEV_LOCK(wdev); 96 97 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) 98 return -EOPNOTSUPP; 99 100 if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && 101 setup->is_secure) 102 return -EOPNOTSUPP; 103 104 if (wdev->mesh_id_len) 105 return -EALREADY; 106 107 if (!setup->mesh_id_len) 108 return -EINVAL; 109 110 if (!rdev->ops->join_mesh) 111 return -EOPNOTSUPP; 112 113 if (!setup->channel) { 114 /* if no channel explicitly given, use preset channel */ 115 setup->channel = wdev->preset_chan; 116 setup->channel_type = wdev->preset_chantype; 117 } 118 119 if (!setup->channel) { 120 /* if we don't have that either, use the first usable channel */ 121 enum ieee80211_band band; 122 123 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 124 struct ieee80211_supported_band *sband; 125 struct ieee80211_channel *chan; 126 int i; 127 128 sband = rdev->wiphy.bands[band]; 129 if (!sband) 130 continue; 131 132 for (i = 0; i < sband->n_channels; i++) { 133 chan = &sband->channels[i]; 134 if (chan->flags & (IEEE80211_CHAN_NO_IBSS | 135 IEEE80211_CHAN_PASSIVE_SCAN | 136 IEEE80211_CHAN_DISABLED | 137 IEEE80211_CHAN_RADAR)) 138 continue; 139 setup->channel = chan; 140 break; 141 } 142 143 if (setup->channel) 144 break; 145 } 146 147 /* no usable channel ... */ 148 if (!setup->channel) 149 return -EINVAL; 150 151 setup->channel_type = NL80211_CHAN_NO_HT; 152 } 153 154 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, 155 setup->channel_type)) 156 return -EINVAL; 157 158 err = cfg80211_can_use_chan(rdev, wdev, setup->channel, 159 CHAN_MODE_SHARED); 160 if (err) 161 return err; 162 163 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); 164 if (!err) { 165 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); 166 wdev->mesh_id_len = setup->mesh_id_len; 167 wdev->channel = setup->channel; 168 } 169 170 return err; 171 } 172 173 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 174 struct net_device *dev, 175 struct mesh_setup *setup, 176 const struct mesh_config *conf) 177 { 178 struct wireless_dev *wdev = dev->ieee80211_ptr; 179 int err; 180 181 mutex_lock(&rdev->devlist_mtx); 182 wdev_lock(wdev); 183 err = __cfg80211_join_mesh(rdev, dev, setup, conf); 184 wdev_unlock(wdev); 185 mutex_unlock(&rdev->devlist_mtx); 186 187 return err; 188 } 189 190 int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 191 struct wireless_dev *wdev, int freq, 192 enum nl80211_channel_type channel_type) 193 { 194 struct ieee80211_channel *channel; 195 int err; 196 197 channel = rdev_freq_to_chan(rdev, freq, channel_type); 198 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, 199 channel, 200 channel_type)) { 201 return -EINVAL; 202 } 203 204 /* 205 * Workaround for libertas (only!), it puts the interface 206 * into mesh mode but doesn't implement join_mesh. Instead, 207 * it is configured via sysfs and then joins the mesh when 208 * you set the channel. Note that the libertas mesh isn't 209 * compatible with 802.11 mesh. 210 */ 211 if (rdev->ops->libertas_set_mesh_channel) { 212 if (channel_type != NL80211_CHAN_NO_HT) 213 return -EINVAL; 214 215 if (!netif_running(wdev->netdev)) 216 return -ENETDOWN; 217 218 err = cfg80211_can_use_chan(rdev, wdev, channel, 219 CHAN_MODE_SHARED); 220 if (err) 221 return err; 222 223 err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, 224 wdev->netdev, 225 channel); 226 if (!err) 227 wdev->channel = channel; 228 229 return err; 230 } 231 232 if (wdev->mesh_id_len) 233 return -EBUSY; 234 235 wdev->preset_chan = channel; 236 wdev->preset_chantype = channel_type; 237 return 0; 238 } 239 240 void cfg80211_notify_new_peer_candidate(struct net_device *dev, 241 const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) 242 { 243 struct wireless_dev *wdev = dev->ieee80211_ptr; 244 245 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) 246 return; 247 248 nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, 249 macaddr, ie, ie_len, gfp); 250 } 251 EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); 252 253 static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 254 struct net_device *dev) 255 { 256 struct wireless_dev *wdev = dev->ieee80211_ptr; 257 int err; 258 259 ASSERT_WDEV_LOCK(wdev); 260 261 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) 262 return -EOPNOTSUPP; 263 264 if (!rdev->ops->leave_mesh) 265 return -EOPNOTSUPP; 266 267 if (!wdev->mesh_id_len) 268 return -ENOTCONN; 269 270 err = rdev->ops->leave_mesh(&rdev->wiphy, dev); 271 if (!err) { 272 wdev->mesh_id_len = 0; 273 wdev->channel = NULL; 274 } 275 276 return err; 277 } 278 279 int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 280 struct net_device *dev) 281 { 282 struct wireless_dev *wdev = dev->ieee80211_ptr; 283 int err; 284 285 wdev_lock(wdev); 286 err = __cfg80211_leave_mesh(rdev, dev); 287 wdev_unlock(wdev); 288 289 return err; 290 } 291