mac80211: support userspace MPM
authorThomas Pedersen <thomas@cozybit.com>
Mon, 4 Mar 2013 21:06:12 +0000 (13:06 -0800)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 Mar 2013 15:36:12 +0000 (16:36 +0100)
Earlier mac80211 would check whether some kind of mesh
security was enabled, when the real question was "is the
MPM in userspace"?

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh_plink.c
net/mac80211/rx.c

index 6ac89e5..c6c7f6e 100644 (file)
@@ -1435,7 +1435,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MESH_POINT:
-               if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
+               if (sdata->u.mesh.user_mpm)
                        statype = CFG80211_STA_MESH_PEER_USER;
                else
                        statype = CFG80211_STA_MESH_PEER_KERNEL;
@@ -1729,6 +1729,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
        ifmsh->mesh_sp_id = setup->sync_method;
        ifmsh->mesh_pp_id = setup->path_sel_proto;
        ifmsh->mesh_pm_id = setup->path_metric;
+       ifmsh->user_mpm = setup->user_mpm;
        ifmsh->security = IEEE80211_MESH_SEC_NONE;
        if (setup->is_authenticated)
                ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
index 54d09ec..f4433f0 100644 (file)
@@ -588,6 +588,7 @@ struct ieee80211_if_mesh {
                IEEE80211_MESH_SEC_AUTHED = 0x1,
                IEEE80211_MESH_SEC_SECURED = 0x2,
        } security;
+       bool user_mpm;
        /* Extensible Synchronization Framework */
        const struct ieee80211_mesh_sync_ops *sync_ops;
        s64 sync_offset_clockdrift_max;
index a55a707..5a53aa5 100644 (file)
@@ -569,7 +569,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
                           NL80211_FEATURE_SAE |
                           NL80211_FEATURE_HT_IBSS |
-                          NL80211_FEATURE_VIF_TXPOWER;
+                          NL80211_FEATURE_VIF_TXPOWER |
+                          NL80211_FEATURE_USERSPACE_MPM;
 
        if (!ops->hw_scan)
                wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
index f5d1afa..5ac017f 100644 (file)
@@ -156,7 +156,7 @@ void mesh_sta_cleanup(struct sta_info *sta)
         * an update.
         */
        changed = mesh_accept_plinks_update(sdata);
-       if (sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
+       if (!sdata->u.mesh.user_mpm) {
                changed |= mesh_plink_deactivate(sta);
                del_timer_sync(&sta->plink_timer);
        }
index 08df966..e259951 100644 (file)
@@ -437,8 +437,9 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
 {
        struct sta_info *sta = NULL;
 
-       /* Userspace handles peer allocation when security is enabled */
-       if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
+       /* Userspace handles station allocation */
+       if (sdata->u.mesh.user_mpm ||
+           sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
                cfg80211_notify_new_peer_candidate(sdata->dev, addr,
                                                   elems->ie_start,
                                                   elems->total_len,
@@ -670,6 +671,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
        if (len < IEEE80211_MIN_ACTION_SIZE + 3)
                return;
 
+       if (sdata->u.mesh.user_mpm)
+               /* userspace must register for these */
+               return;
+
        if (is_multicast_ether_addr(mgmt->da)) {
                mpl_dbg(sdata,
                        "Mesh plink: ignore frame from multicast address\n");
index 1f940e2..5b4492a 100644 (file)
@@ -2543,7 +2543,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                case WLAN_SP_MESH_PEERING_CONFIRM:
                        if (!ieee80211_vif_is_mesh(&sdata->vif))
                                goto invalid;
-                       if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
+                       if (sdata->u.mesh.user_mpm)
                                /* userspace handles this frame */
                                break;
                        goto queue;