cfg80211/nl80211: introduce p2p device types
authorJohannes Berg <johannes.berg@intel.com>
Thu, 16 Sep 2010 12:58:22 +0000 (14:58 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 16 Sep 2010 19:46:06 +0000 (15:46 -0400)
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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/nl80211.h
net/wireless/core.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/sme.c
net/wireless/util.c

index 31603e8b558132818f37936ae0a99113bf43a54f..f0518b0278a927b0998659daf1aed1c5e7793bc6 100644 (file)
@@ -1020,6 +1020,8 @@ enum nl80211_attrs {
  * @NL80211_IFTYPE_WDS: wireless distribution interface
  * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
  * @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
  * @NUM_NL80211_IFTYPES: number of defined interface types
  *
@@ -1036,6 +1038,8 @@ enum nl80211_iftype {
        NL80211_IFTYPE_WDS,
        NL80211_IFTYPE_MONITOR,
        NL80211_IFTYPE_MESH_POINT,
+       NL80211_IFTYPE_P2P_CLIENT,
+       NL80211_IFTYPE_P2P_GO,
 
        /* keep last */
        NUM_NL80211_IFTYPES,
index b8191cf86226ec50f88a3ed7701bb8bce758426d..ff9615a7ee7a4da78fdf38f41b8334af841104ee 100644 (file)
@@ -726,6 +726,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                        dev->ethtool_ops = &cfg80211_ethtool_ops;
 
                if ((wdev->iftype == NL80211_IFTYPE_STATION ||
+                    wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
                     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
                        dev->priv_flags |= IFF_DONT_BRIDGE;
                break;
@@ -734,6 +735,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                case NL80211_IFTYPE_ADHOC:
                        cfg80211_leave_ibss(rdev, dev, true);
                        break;
+               case NL80211_IFTYPE_P2P_CLIENT:
                case NL80211_IFTYPE_STATION:
                        wdev_lock(wdev);
 #ifdef CONFIG_CFG80211_WEXT
index 8515b1e5c5781075897a769b46608f2fe89f4cd7..46f3711608960b7ba42d6675219530b2c9886e2d 100644 (file)
@@ -882,7 +882,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                if (!wdev->current_bss ||
                    memcmp(wdev->current_bss->pub.bssid, mgmt->bssid,
                           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,
                            ETH_ALEN) != 0)) {
                        wdev_unlock(wdev);
index 1d6ef24254fee94dfd3f89cd3c595c6474de808d..f15b1af2c768ca8007902b045e998456d38d595a 100644 (file)
@@ -410,12 +410,14 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
        switch (wdev->iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_P2P_GO:
                break;
        case NL80211_IFTYPE_ADHOC:
                if (!wdev->current_bss)
                        return -ENOLINK;
                break;
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
                if (wdev->sme_state != CFG80211_SME_CONNECTED)
                        return -ENOLINK;
                break;
@@ -766,7 +768,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
                wdev->iftype == NL80211_IFTYPE_AP ||
                wdev->iftype == NL80211_IFTYPE_WDS ||
                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,
@@ -1693,7 +1696,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
        if (err)
                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;
                goto out;
        }
@@ -1785,7 +1789,8 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -2128,10 +2133,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
        switch (dev->ieee80211_ptr->iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_P2P_GO:
                /* disallow mesh-specific things */
                if (params.plink_action)
                        err = -EINVAL;
                break;
+       case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_STATION:
                /* disallow everything but AUTHORIZED flag */
                if (params.plink_action)
@@ -2233,7 +2240,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
                goto out_rtnl;
 
        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;
                goto out;
        }
@@ -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 &&
            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;
                goto out;
        }
@@ -2660,7 +2669,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -3363,6 +3373,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
        }
 
        switch (wdev->iftype) {
+       case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_STATION:
                if (intbss == wdev->current_bss)
                        NLA_PUT_U32(msg, NL80211_BSS_STATUS,
@@ -3649,7 +3660,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -3804,7 +3816,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -3888,7 +3901,8 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -3954,7 +3968,8 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
                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;
                goto out;
        }
@@ -4332,7 +4347,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
        if (err)
                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;
                goto out;
        }
@@ -4408,7 +4424,8 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
        if (err)
                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;
                goto out;
        }
@@ -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.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;
                goto out;
        }
@@ -4541,7 +4559,8 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
        if (err)
                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;
                goto out;
        }
@@ -4823,7 +4842,8 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
                goto unlock_rtnl;
 
        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;
                goto out;
        }
@@ -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 &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) {
                err = -EOPNOTSUPP;
                goto out;
        }
@@ -5093,7 +5114,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
                goto unlock_rdev;
        }
 
-       if (wdev->iftype != NL80211_IFTYPE_STATION) {
+       if (wdev->iftype != NL80211_IFTYPE_STATION &&
+           wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
                err = -EOPNOTSUPP;
                goto unlock_rdev;
        }
index a8c2d6b877aeda894cb80328d015bc3494e000c9..f161b9844542a2adcfa82dfc83fcd23068a4ee46 100644 (file)
@@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 
        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;
 
        if (wdev->sme_state != CFG80211_SME_CONNECTING)
@@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
 
        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;
 
        if (wdev->sme_state != CFG80211_SME_CONNECTED)
@@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 
        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;
 
        if (wdev->sme_state != CFG80211_SME_CONNECTED)
index bca32eb8f446a90161c314e55042627953e84328..fb5448f7d55af55b8ee8220ef813880993d0b069 100644 (file)
@@ -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)) {
        case cpu_to_le16(IEEE80211_FCTL_TODS):
                if (unlikely(iftype != NL80211_IFTYPE_AP &&
-                            iftype != NL80211_IFTYPE_AP_VLAN))
+                            iftype != NL80211_IFTYPE_AP_VLAN &&
+                            iftype != NL80211_IFTYPE_P2P_GO))
                        return -1;
                break;
        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,
                break;
        case cpu_to_le16(IEEE80211_FCTL_FROMDS):
                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) &&
                     !compare_ether_addr(src, addr)))
                        return -1;
@@ -431,6 +433,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
        switch (iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_P2P_GO:
                fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
                /* DA BSSID SA */
                memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -439,6 +442,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
                hdrlen = 24;
                break;
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
                fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
                /* BSSID SA DA */
                memcpy(hdr.addr1, bssid, ETH_ALEN);
@@ -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 ((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;
 
        if (ntype != otype) {
@@ -789,6 +795,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                        cfg80211_leave_ibss(rdev, dev, false);
                        break;
                case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_P2P_CLIENT:
                        cfg80211_disconnect(rdev, dev,
                                            WLAN_REASON_DEAUTH_LEAVING, true);
                        break;
@@ -817,9 +824,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                        if (dev->ieee80211_ptr->use_4addr)
                                break;
                        /* fall through */
+               case NL80211_IFTYPE_P2P_CLIENT:
                case NL80211_IFTYPE_ADHOC:
                        dev->priv_flags |= IFF_DONT_BRIDGE;
                        break;
+               case NL80211_IFTYPE_P2P_GO:
                case NL80211_IFTYPE_AP:
                case NL80211_IFTYPE_AP_VLAN:
                case NL80211_IFTYPE_WDS: