@@ -1169,6 +1169,8 @@ struct mesh_config {
* @dtim_period: DTIM period to use
* @beacon_interval: beacon interval to use
* @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
+ * @shared: MBSS sharing and intra-vif data forwarding may take place for
+ * this mesh setup.
*
* These parameters are fixed when the mesh is created.
*/
@@ -1187,6 +1189,7 @@ struct mesh_setup {
u8 dtim_period;
u16 beacon_interval;
int mcast_rate[IEEE80211_NUM_BANDS];
+ bool shared;
};
/**
@@ -2645,6 +2645,10 @@ enum nl80211_meshconf_params {
* @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will
* implement an MPM which handles peer allocation and state.
*
+ * @NL80211_MESH_SETUP_CAN_SHARE: Enable this option to allow sharing an MBSS
+ * profile and frame forwarding across multiple virtual interfaces with the
+ * same profile. Defaults to off.
+ *
* @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
*
* @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
@@ -2658,6 +2662,7 @@ enum nl80211_mesh_setup_params {
NL80211_MESH_SETUP_USERSPACE_AMPE,
NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
NL80211_MESH_SETUP_USERSPACE_MPM,
+ NL80211_MESH_SETUP_CAN_SHARE,
/* keep last */
__NL80211_MESH_SETUP_ATTR_AFTER_LAST,
@@ -1742,6 +1742,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
/* now copy the rest of the setup parameters */
ifmsh->mesh_id_len = setup->mesh_id_len;
memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
+ ifmsh->share_mbss = setup->shared;
ifmsh->mesh_sp_id = setup->sync_method;
ifmsh->mesh_pp_id = setup->path_sel_proto;
ifmsh->mesh_pm_id = setup->path_metric;
@@ -632,6 +632,7 @@ struct ieee80211_if_mesh {
struct ps_data ps;
/* mbss sharing */
+ bool share_mbss;
struct mesh_local_bss *mesh_bss;
struct list_head if_list;
};
@@ -60,6 +60,7 @@ mesh_bss_matches(struct ieee80211_sub_if_data *sdata,
struct mesh_local_bss *mbss)
{
return mbss->can_share &&
+ setup->shared &&
mbss->mesh_id_len == setup->mesh_id_len &&
memcmp(mbss->mesh_id, setup->mesh_id, mbss->mesh_id_len) == 0 &&
mbss->path_sel_proto == setup->path_sel_proto &&
@@ -109,7 +110,7 @@ mesh_bss_create(struct ieee80211_sub_if_data *sdata, struct mesh_setup *setup)
mbss->mesh_id_len = setup->mesh_id_len;
memcpy(mbss->mesh_id, setup->mesh_id, setup->mesh_id_len);
- mbss->can_share = false;
+ mbss->can_share = setup->shared;
mbss->path_metric = setup->path_metric;
mbss->path_sel_proto = setup->path_sel_proto;
mbss->sync_method = setup->sync_method;
@@ -994,6 +995,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
setup.sync_method = ifmsh->mesh_pm_id;
setup.path_metric = ifmsh->mesh_cc_id;
setup.is_secure = ifmsh->security & IEEE80211_MESH_SEC_SECURED;
+ setup.shared = ifmsh->share_mbss;
ret = mesh_bss_add(sdata, &setup);
if (ret) {
@@ -88,6 +88,7 @@ const struct mesh_setup default_mesh_setup = {
.user_mpm = false,
.beacon_interval = MESH_DEFAULT_BEACON_INTERVAL,
.dtim_period = MESH_DEFAULT_DTIM_PERIOD,
+ .shared = false,
};
int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
@@ -4857,6 +4857,9 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
if (setup->is_secure)
setup->user_mpm = true;
+ if (tb[NL80211_MESH_SETUP_CAN_SHARE])
+ setup->shared = nla_get_u8(tb[NL80211_MESH_SETUP_CAN_SHARE]);
+
return 0;
}
Signed-off-by: Thomas Pedersen <thomas@cozybit.com> --- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 5 +++++ net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 1 + net/mac80211/mesh.c | 4 +++- net/wireless/mesh.c | 1 + net/wireless/nl80211.c | 3 +++ 7 files changed, 17 insertions(+), 1 deletion(-)