@@ -94,7 +94,6 @@ static int validate_nla(struct nlattr *nla, int maxtype,
minlen = pt->len;
else if (pt->type != NLA_UNSPEC)
minlen = nla_attr_minlen[pt->type];
-
if (attrlen < minlen)
return -ERANGE;
}
@@ -1673,6 +1673,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;
@@ -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,
@@ -126,13 +126,21 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *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_pp_id = MESH_PATH_PROTOCOL_HWMP;
+ sta->mesh_pm_id = MESH_PATH_PROTOCOL_VENDOR;
sta->mesh_cc_id = 0; /* Disabled */
sta->mesh_sp_id = 0; /* Neighbor Offset */
sta->mesh_auth_id = 0; /* Disabled */
}
+
+bool mesh_path_sel_match(struct ieee80211_sub_if_data *sdata, enum
+ mesh_path_sel_id psid)
+{
+ return (sdata->u.mesh.mesh_pp_id == psid);
+
+}
+
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
{
int i;
@@ -50,7 +50,7 @@ enum mesh_path_flags {
* @MESH_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will be
* specified in a vendor specific information element
*/
-enum {
+enum mesh_path_sel_id {
MESH_PATH_PROTOCOL_HWMP = 0,
MESH_PATH_PROTOCOL_VENDOR = 255,
};
@@ -229,6 +229,8 @@ int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
bool mesh_matches_local(struct ieee802_11_elems *ie,
struct ieee80211_sub_if_data *sdata);
void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
+bool mesh_path_sel_match(struct ieee80211_sub_if_data *sdata, enum
+ mesh_path_sel_id psid);
void mesh_mgmt_ies_add(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
@@ -2124,10 +2124,15 @@ 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 (!ieee80211_vif_is_mesh(&sdata->vif) ||
+ !mesh_path_sel_match(sdata,
+ MESH_PATH_PROTOCOL_HWMP))
+ break;
+ goto queue;
}
return RX_CONTINUE;
@@ -4315,6 +4315,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;