Commit c7108a71 authored by Javier Cardona's avatar Javier Cardona Committed by John W. Linville

mac80211: Send mesh non-HWMP path selection frames to userspace

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: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c80d545d
...@@ -1670,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, ...@@ -1670,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_MESH_POINT:
if (!ieee80211_is_action(mgmt->frame_control) || if (!ieee80211_is_action(mgmt->frame_control) ||
mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
break; break;
......
...@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { ...@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4) |
BIT(IEEE80211_STYPE_ACTION >> 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, struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
......
...@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) ...@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
ieee80211_mesh_housekeeping_timer((unsigned long) 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 mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
{ {
int i; int i;
...@@ -525,6 +516,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) ...@@ -525,6 +516,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
atomic_inc(&local->iff_allmultis); atomic_inc(&local->iff_allmultis);
ieee80211_configure_filter(local); 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); set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
ieee80211_mesh_root_setup(ifmsh); ieee80211_mesh_root_setup(ifmsh);
ieee80211_queue_work(&local->hw, &sdata->work); ieee80211_queue_work(&local->hw, &sdata->work);
...@@ -695,7 +689,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ...@@ -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. */ /* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated) if (!mesh_allocated)
ieee80211s_init(); ieee80211s_init();
mesh_ids_set_default(ifmsh);
setup_timer(&ifmsh->mesh_path_timer, setup_timer(&ifmsh->mesh_path_timer,
ieee80211_mesh_path_timer, ieee80211_mesh_path_timer,
(unsigned long) sdata); (unsigned long) sdata);
......
...@@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath) ...@@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED; 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) \ #define for_each_mesh_entry(x, p, node, i) \
for (i = 0; i <= x->hash_mask; i++) \ for (i = 0; i <= x->hash_mask; i++) \
hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) 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) ...@@ -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_quiesce(struct sta_info *sta) {}
static inline void mesh_plink_restart(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
#endif /* IEEE80211S_H */ #endif /* IEEE80211S_H */
...@@ -2161,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2161,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
} }
break; break;
case WLAN_CATEGORY_MESH_PLINK: case WLAN_CATEGORY_MESH_PLINK:
case WLAN_CATEGORY_MESH_PATH_SEL:
if (!ieee80211_vif_is_mesh(&sdata->vif)) if (!ieee80211_vif_is_mesh(&sdata->vif))
break; break;
goto queue; goto queue;
case WLAN_CATEGORY_MESH_PATH_SEL:
if (!mesh_path_sel_is_hwmp(sdata))
break;
goto queue;
} }
return RX_CONTINUE; return RX_CONTINUE;
......
...@@ -4445,6 +4445,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -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_P2P_CLIENT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -4485,6 +4486,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -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_P2P_CLIENT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment