diff options
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index a7078fdba8ca..c707c8bf6d2c 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -76,6 +76,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) | 76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) |
77 | { | 77 | { |
78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
79 | struct ieee80211_local *local = sdata->local; | ||
79 | 80 | ||
80 | /* | 81 | /* |
81 | * As support for each feature is added, check for matching | 82 | * As support for each feature is added, check for matching |
@@ -87,15 +88,23 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat | |||
87 | * - MDA enabled | 88 | * - MDA enabled |
88 | * - Power management control on fc | 89 | * - Power management control on fc |
89 | */ | 90 | */ |
90 | if (ifmsh->mesh_id_len == ie->mesh_id_len && | 91 | if (!(ifmsh->mesh_id_len == ie->mesh_id_len && |
91 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && | 92 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && |
92 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && | 93 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && |
93 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && | 94 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && |
94 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && | 95 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && |
95 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && | 96 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && |
96 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)) | 97 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) |
97 | return true; | 98 | goto mismatch; |
98 | 99 | ||
100 | /* disallow peering with mismatched channel types for now */ | ||
101 | if (ie->ht_info_elem && | ||
102 | (local->_oper_channel_type != | ||
103 | ieee80211_ht_info_to_channel_type(ie->ht_info_elem))) | ||
104 | goto mismatch; | ||
105 | |||
106 | return true; | ||
107 | mismatch: | ||
99 | return false; | 108 | return false; |
100 | } | 109 | } |
101 | 110 | ||
@@ -341,6 +350,49 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, | |||
341 | return 0; | 350 | return 0; |
342 | } | 351 | } |
343 | 352 | ||
353 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
354 | struct ieee80211_sub_if_data *sdata) | ||
355 | { | ||
356 | struct ieee80211_local *local = sdata->local; | ||
357 | struct ieee80211_supported_band *sband; | ||
358 | u8 *pos; | ||
359 | |||
360 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
361 | if (!sband->ht_cap.ht_supported || | ||
362 | local->_oper_channel_type == NL80211_CHAN_NO_HT) | ||
363 | return 0; | ||
364 | |||
365 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) | ||
366 | return -ENOMEM; | ||
367 | |||
368 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap)); | ||
369 | ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, sband->ht_cap.cap); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | int mesh_add_ht_info_ie(struct sk_buff *skb, | ||
375 | struct ieee80211_sub_if_data *sdata) | ||
376 | { | ||
377 | struct ieee80211_local *local = sdata->local; | ||
378 | struct ieee80211_channel *channel = local->oper_channel; | ||
379 | enum nl80211_channel_type channel_type = local->_oper_channel_type; | ||
380 | struct ieee80211_supported_band *sband = | ||
381 | local->hw.wiphy->bands[channel->band]; | ||
382 | struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; | ||
383 | u8 *pos; | ||
384 | |||
385 | if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) | ||
386 | return 0; | ||
387 | |||
388 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_info)) | ||
389 | return -ENOMEM; | ||
390 | |||
391 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_info)); | ||
392 | ieee80211_ie_build_ht_info(pos, ht_cap, channel, channel_type); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
344 | static void ieee80211_mesh_path_timer(unsigned long data) | 396 | static void ieee80211_mesh_path_timer(unsigned long data) |
345 | { | 397 | { |
346 | struct ieee80211_sub_if_data *sdata = | 398 | struct ieee80211_sub_if_data *sdata = |
@@ -697,6 +749,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
697 | atomic_set(&ifmsh->mpaths, 0); | 749 | atomic_set(&ifmsh->mpaths, 0); |
698 | mesh_rmc_init(sdata); | 750 | mesh_rmc_init(sdata); |
699 | ifmsh->last_preq = jiffies; | 751 | ifmsh->last_preq = jiffies; |
752 | ifmsh->next_perr = jiffies; | ||
700 | /* Allocate all mesh structures when creating the first mesh interface. */ | 753 | /* Allocate all mesh structures when creating the first mesh interface. */ |
701 | if (!mesh_allocated) | 754 | if (!mesh_allocated) |
702 | ieee80211s_init(); | 755 | ieee80211s_init(); |