Commit 074ac8df authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

cfg80211/nl80211: introduce p2p device types

This adds P2P-STA and P2P-GO as device types so
we can distinguish between those and normal STA
or AP (respectively) type interfaces.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f799a301
...@@ -1020,6 +1020,8 @@ enum nl80211_attrs { ...@@ -1020,6 +1020,8 @@ enum nl80211_attrs {
* @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_WDS: wireless distribution interface
* @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
* @NL80211_IFTYPE_MESH_POINT: mesh point * @NL80211_IFTYPE_MESH_POINT: mesh point
* @NL80211_IFTYPE_P2P_CLIENT: P2P client
* @NL80211_IFTYPE_P2P_GO: P2P group owner
* @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NL80211_IFTYPE_MAX: highest interface type number currently defined
* @NUM_NL80211_IFTYPES: number of defined interface types * @NUM_NL80211_IFTYPES: number of defined interface types
* *
...@@ -1036,6 +1038,8 @@ enum nl80211_iftype { ...@@ -1036,6 +1038,8 @@ enum nl80211_iftype {
NL80211_IFTYPE_WDS, NL80211_IFTYPE_WDS,
NL80211_IFTYPE_MONITOR, NL80211_IFTYPE_MONITOR,
NL80211_IFTYPE_MESH_POINT, NL80211_IFTYPE_MESH_POINT,
NL80211_IFTYPE_P2P_CLIENT,
NL80211_IFTYPE_P2P_GO,
/* keep last */ /* keep last */
NUM_NL80211_IFTYPES, NUM_NL80211_IFTYPES,
......
...@@ -726,6 +726,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, ...@@ -726,6 +726,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
dev->ethtool_ops = &cfg80211_ethtool_ops; dev->ethtool_ops = &cfg80211_ethtool_ops;
if ((wdev->iftype == NL80211_IFTYPE_STATION || if ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
dev->priv_flags |= IFF_DONT_BRIDGE; dev->priv_flags |= IFF_DONT_BRIDGE;
break; break;
...@@ -734,6 +735,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, ...@@ -734,6 +735,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
cfg80211_leave_ibss(rdev, dev, true); cfg80211_leave_ibss(rdev, dev, true);
break; break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
wdev_lock(wdev); wdev_lock(wdev);
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
......
...@@ -882,7 +882,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, ...@@ -882,7 +882,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (!wdev->current_bss || if (!wdev->current_bss ||
memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, memcmp(wdev->current_bss->pub.bssid, mgmt->bssid,
ETH_ALEN) != 0 || ETH_ALEN) != 0 ||
(wdev->iftype == NL80211_IFTYPE_STATION && ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
memcmp(wdev->current_bss->pub.bssid, mgmt->da, memcmp(wdev->current_bss->pub.bssid, mgmt->da,
ETH_ALEN) != 0)) { ETH_ALEN) != 0)) {
wdev_unlock(wdev); wdev_unlock(wdev);
......
...@@ -410,12 +410,14 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) ...@@ -410,12 +410,14 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
switch (wdev->iftype) { switch (wdev->iftype) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
if (!wdev->current_bss) if (!wdev->current_bss)
return -ENOLINK; return -ENOLINK;
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
if (wdev->sme_state != CFG80211_SME_CONNECTED) if (wdev->sme_state != CFG80211_SME_CONNECTED)
return -ENOLINK; return -ENOLINK;
break; break;
...@@ -766,7 +768,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) ...@@ -766,7 +768,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_AP ||
wdev->iftype == NL80211_IFTYPE_WDS || wdev->iftype == NL80211_IFTYPE_WDS ||
wdev->iftype == NL80211_IFTYPE_MESH_POINT || wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
wdev->iftype == NL80211_IFTYPE_MONITOR; wdev->iftype == NL80211_IFTYPE_MONITOR ||
wdev->iftype == NL80211_IFTYPE_P2P_GO;
} }
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
...@@ -1693,7 +1696,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) ...@@ -1693,7 +1696,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
goto unlock_rtnl; goto unlock_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -1785,7 +1789,8 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) ...@@ -1785,7 +1789,8 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -2128,10 +2133,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) ...@@ -2128,10 +2133,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
switch (dev->ieee80211_ptr->iftype) { switch (dev->ieee80211_ptr->iftype) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
/* disallow mesh-specific things */ /* disallow mesh-specific things */
if (params.plink_action) if (params.plink_action)
err = -EINVAL; err = -EINVAL;
break; break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
/* disallow everything but AUTHORIZED flag */ /* disallow everything but AUTHORIZED flag */
if (params.plink_action) if (params.plink_action)
...@@ -2233,7 +2240,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) ...@@ -2233,7 +2240,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
goto out_rtnl; goto out_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && if (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_P2P_GO) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -2286,7 +2294,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) ...@@ -2286,7 +2294,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && if (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_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -2660,7 +2669,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) ...@@ -2660,7 +2669,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -3363,6 +3373,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, ...@@ -3363,6 +3373,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
} }
switch (wdev->iftype) { switch (wdev->iftype) {
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
if (intbss == wdev->current_bss) if (intbss == wdev->current_bss)
NLA_PUT_U32(msg, NL80211_BSS_STATUS, NLA_PUT_U32(msg, NL80211_BSS_STATUS,
...@@ -3649,7 +3660,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) ...@@ -3649,7 +3660,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -3804,7 +3816,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) ...@@ -3804,7 +3816,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -3888,7 +3901,8 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) ...@@ -3888,7 +3901,8 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -3954,7 +3968,8 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) ...@@ -3954,7 +3968,8 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4332,7 +4347,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) ...@@ -4332,7 +4347,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
goto unlock_rtnl; goto unlock_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4408,7 +4424,8 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) ...@@ -4408,7 +4424,8 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
goto unlock_rtnl; goto unlock_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4496,7 +4513,8 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) ...@@ -4496,7 +4513,8 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4541,7 +4559,8 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) ...@@ -4541,7 +4559,8 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
goto out_rtnl; goto out_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4823,7 +4842,8 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -4823,7 +4842,8 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
goto unlock_rtnl; goto unlock_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -4875,7 +4895,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -4875,7 +4895,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
} }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -5093,7 +5114,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, ...@@ -5093,7 +5114,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
goto unlock_rdev; goto unlock_rdev;
} }
if (wdev->iftype != NL80211_IFTYPE_STATION) { if (wdev->iftype != NL80211_IFTYPE_STATION &&
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto unlock_rdev; goto unlock_rdev;
} }
......
...@@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ...@@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
ASSERT_WDEV_LOCK(wdev); ASSERT_WDEV_LOCK(wdev);
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return; return;
if (wdev->sme_state != CFG80211_SME_CONNECTING) if (wdev->sme_state != CFG80211_SME_CONNECTING)
...@@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, ...@@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
ASSERT_WDEV_LOCK(wdev); ASSERT_WDEV_LOCK(wdev);
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return; return;
if (wdev->sme_state != CFG80211_SME_CONNECTED) if (wdev->sme_state != CFG80211_SME_CONNECTED)
...@@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, ...@@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
ASSERT_WDEV_LOCK(wdev); ASSERT_WDEV_LOCK(wdev);
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return; return;
if (wdev->sme_state != CFG80211_SME_CONNECTED) if (wdev->sme_state != CFG80211_SME_CONNECTED)
......
...@@ -326,7 +326,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, ...@@ -326,7 +326,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case cpu_to_le16(IEEE80211_FCTL_TODS): case cpu_to_le16(IEEE80211_FCTL_TODS):
if (unlikely(iftype != NL80211_IFTYPE_AP && if (unlikely(iftype != NL80211_IFTYPE_AP &&
iftype != NL80211_IFTYPE_AP_VLAN)) iftype != NL80211_IFTYPE_AP_VLAN &&
iftype != NL80211_IFTYPE_P2P_GO))
return -1; return -1;
break; break;
case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
...@@ -354,7 +355,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, ...@@ -354,7 +355,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
break; break;
case cpu_to_le16(IEEE80211_FCTL_FROMDS): case cpu_to_le16(IEEE80211_FCTL_FROMDS):
if ((iftype != NL80211_IFTYPE_STATION && if ((iftype != NL80211_IFTYPE_STATION &&
iftype != NL80211_IFTYPE_MESH_POINT) || iftype != NL80211_IFTYPE_P2P_CLIENT &&
iftype != NL80211_IFTYPE_MESH_POINT) ||
(is_multicast_ether_addr(dst) && (is_multicast_ether_addr(dst) &&
!compare_ether_addr(src, addr))) !compare_ether_addr(src, addr)))
return -1; return -1;
...@@ -431,6 +433,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, ...@@ -431,6 +433,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
switch (iftype) { switch (iftype) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
/* DA BSSID SA */ /* DA BSSID SA */
memcpy(hdr.addr1, skb->data, ETH_ALEN); memcpy(hdr.addr1, skb->data, ETH_ALEN);
...@@ -439,6 +442,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, ...@@ -439,6 +442,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
hdrlen = 24; hdrlen = 24;
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
fc |= cpu_to_le16(IEEE80211_FCTL_TODS); fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* BSSID SA DA */ /* BSSID SA DA */
memcpy(hdr.addr1, bssid, ETH_ALEN); memcpy(hdr.addr1, bssid, ETH_ALEN);
...@@ -778,7 +782,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, ...@@ -778,7 +782,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
/* if it's part of a bridge, reject changing type to station/ibss */ /* if it's part of a bridge, reject changing type to station/ibss */
if ((dev->priv_flags & IFF_BRIDGE_PORT) && if ((dev->priv_flags & IFF_BRIDGE_PORT) &&
(ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) (ntype == NL80211_IFTYPE_ADHOC ||
ntype == NL80211_IFTYPE_STATION ||
ntype == NL80211_IFTYPE_P2P_CLIENT))
return -EBUSY; return -EBUSY;
if (ntype != otype) { if (ntype != otype) {
...@@ -789,6 +795,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, ...@@ -789,6 +795,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
cfg80211_leave_ibss(rdev, dev, false); cfg80211_leave_ibss(rdev, dev, false);
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
cfg80211_disconnect(rdev, dev, cfg80211_disconnect(rdev, dev,
WLAN_REASON_DEAUTH_LEAVING, true); WLAN_REASON_DEAUTH_LEAVING, true);
break; break;
...@@ -817,9 +824,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, ...@@ -817,9 +824,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
if (dev->ieee80211_ptr->use_4addr) if (dev->ieee80211_ptr->use_4addr)
break; break;
/* fall through */ /* fall through */
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
dev->priv_flags |= IFF_DONT_BRIDGE; dev->priv_flags |= IFF_DONT_BRIDGE;
break; break;
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_WDS:
......
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