mac80211: Send mesh non-HWMP path selection frames to userspace
authorJavier Cardona <javier@cozybit.com>
Fri, 17 Dec 2010 01:37:50 +0000 (17:37 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 20 Dec 2010 19:46:58 +0000 (14:46 -0500)
Let path selection frames for protocols other than HWMP be sent to
userspace via NL80211_CMD_REGISTER_FRAME.  Also allow userspace to send
and receive mesh path selection frames.

Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/cfg.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/rx.c
net/wireless/nl80211.c

index ae2c712..5892b03 100644 (file)
@@ -1670,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
        case NL80211_IFTYPE_P2P_GO:
+       case NL80211_IFTYPE_MESH_POINT:
                if (!ieee80211_is_action(mgmt->frame_control) ||
                    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
                        break;
index d87eb00..a21d049 100644 (file)
@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
                        BIT(IEEE80211_STYPE_DEAUTH >> 4) |
                        BIT(IEEE80211_STYPE_ACTION >> 4),
        },
+       [NL80211_IFTYPE_MESH_POINT] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+       },
 };
 
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
index c326e00..8b5906c 100644 (file)
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
                ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
 }
 
-void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
-{
-       sta->mesh_pp_id = 0;    /* HWMP */
-       sta->mesh_pm_id = 0;    /* Airtime */
-       sta->mesh_cc_id = 0;    /* Disabled */
-       sta->mesh_sp_id = 0;    /* Neighbor Offset */
-       sta->mesh_auth_id = 0;  /* Disabled */
-}
-
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
 {
        int i;
@@ -525,6 +516,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
        atomic_inc(&local->iff_allmultis);
        ieee80211_configure_filter(local);
 
+       ifmsh->mesh_cc_id = 0;  /* Disabled */
+       ifmsh->mesh_sp_id = 0;  /* Neighbor Offset */
+       ifmsh->mesh_auth_id = 0;        /* Disabled */
        set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
        ieee80211_mesh_root_setup(ifmsh);
        ieee80211_queue_work(&local->hw, &sdata->work);
@@ -695,7 +689,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
        /* Allocate all mesh structures when creating the first mesh interface. */
        if (!mesh_allocated)
                ieee80211s_init();
-       mesh_ids_set_default(ifmsh);
        setup_timer(&ifmsh->mesh_path_timer,
                    ieee80211_mesh_path_timer,
                    (unsigned long) sdata);
index 5b828fa..890dd19 100644 (file)
@@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
        mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
 }
 
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{
+       return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+}
+
 #define for_each_mesh_entry(x, p, node, i) \
        for (i = 0; i <= x->hash_mask; i++) \
                hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -304,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
 {}
 static inline void mesh_plink_quiesce(struct sta_info *sta) {}
 static inline void mesh_plink_restart(struct sta_info *sta) {}
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{ return false; }
 #endif
 
 #endif /* IEEE80211S_H */
index 4573ce1..7c5d1b2 100644 (file)
@@ -2161,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                }
                break;
        case WLAN_CATEGORY_MESH_PLINK:
-       case WLAN_CATEGORY_MESH_PATH_SEL:
                if (!ieee80211_vif_is_mesh(&sdata->vif))
                        break;
                goto queue;
+       case WLAN_CATEGORY_MESH_PATH_SEL:
+               if (!mesh_path_sel_is_hwmp(sdata))
+                       break;
+               goto queue;
        }
 
        return RX_CONTINUE;
index eef89d0..6a5d6fa 100644 (file)
@@ -4445,6 +4445,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
                return -EOPNOTSUPP;
 
@@ -4485,6 +4486,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
                return -EOPNOTSUPP;