This adds IBSS API along with (preliminary) wext handlers.
The wext handlers can only do IBSS so you need to call them
from your own wext handlers if the mode is IBSS.
Signed-off-by: Johannes Berg <[email protected]>
---
No need to test with iw -- I will push branch anyway though.
include/linux/nl80211.h | 11 +
include/net/cfg80211.h | 68 +++++++++
include/net/wireless.h | 14 ++
net/wireless/Makefile | 2
net/wireless/core.c | 16 ++
net/wireless/core.h | 8 +
net/wireless/ibss.c | 308 +++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.c | 180 ++++++++++++++++++++++++--
net/wireless/nl80211.h | 4
net/wireless/wext-compat.c | 30 ++++
10 files changed, 628 insertions(+), 13 deletions(-)
--- wireless-testing.orig/include/linux/nl80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h 2009-04-18 23:50:47.000000000 +0200
@@ -223,6 +223,14 @@
* %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
* event matches with MLME-MICHAELMICFAILURE.indication() primitive
*
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID, and
+ * optionally a MAC (as BSSID) and FREQ attribute if those should be
+ * fixed rather than automatically determined. Can only be executed
+ * on a network interface that is UP, and fixed BSSID/FREQ may be
+ * rejected.
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ * determined by the network interface.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -288,6 +296,9 @@ enum nl80211_commands {
NL80211_CMD_REG_BEACON_HINT,
+ NL80211_CMD_JOIN_IBSS,
+ NL80211_CMD_LEAVE_IBSS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- wireless-testing.orig/include/net/cfg80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h 2009-04-18 23:50:47.000000000 +0200
@@ -658,6 +658,27 @@ struct cfg80211_disassoc_request {
};
/**
+ * struct cfg80211_ibss_params - IBSS parameters
+ *
+ * This structure defines the IBSS parameters for the join_ibss()
+ * method.
+ *
+ * @ssid: The SSID, will always be non-null.
+ * @ssid_len: The length of the SSID, will always be non-zero.
+ * @bssid: Fixed BSSID requested, may be %NULL.
+ * @channel: Fixed channel requested, may be %NULL.
+ * @ie: information element(s) to include in the beacon
+ * @ie_len: length of that
+ */
+struct cfg80211_ibss_params {
+ u8 *ssid;
+ u8 *bssid;
+ struct ieee80211_channel *channel;
+ u8 *ie;
+ u8 ssid_len, ie_len;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -732,6 +753,11 @@ struct cfg80211_disassoc_request {
* @assoc: Request to (re)associate with the specified peer
* @deauth: Request to deauthenticate from the specified peer
* @disassoc: Request to disassociate from the specified peer
+ *
+ * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
+ * cfg80211_ibss_joined(), also call that function when changing BSSID due
+ * to a merge.
+ * @leave_ibss: Leave the IBSS.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
@@ -817,6 +843,10 @@ struct cfg80211_ops {
struct cfg80211_deauth_request *req);
int (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_disassoc_request *req);
+
+ int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+ int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
};
/* temporary wext handlers */
@@ -836,6 +866,28 @@ int cfg80211_wext_giwscan(struct net_dev
int cfg80211_wext_giwrange(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra);
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+
+/* wext helper for now (to be removed) */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq);
/**
* cfg80211_scan_done - notify that scan finished
@@ -981,4 +1033,20 @@ void cfg80211_michael_mic_failure(struct
enum nl80211_key_type key_type, int key_id,
const u8 *tsc);
+/**
+ * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the IBSS joined
+ * @gfp: allocation flags
+ *
+ * This function notifies cfg80211 that the device joined an IBSS or
+ * switched to a different BSSID. Before this function can be called,
+ * either a beacon has to have been received from the IBSS, or one of
+ * the cfg80211_inform_bss{,_frame} functions must have been called
+ * with the locally generated beacon -- this guarantees that there is
+ * always a scan result for this IBSS. cfg80211 will handle the rest.
+ */
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
+
#endif /* __NET_CFG80211_H */
--- wireless-testing.orig/net/wireless/nl80211.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c 2009-04-18 23:50:47.000000000 +0200
@@ -322,6 +322,7 @@ static int nl80211_send_wiphy(struct sk_
CMD(assoc, ASSOCIATE);
CMD(deauth, DEAUTHENTICATE);
CMD(disassoc, DISASSOCIATE);
+ CMD(join_ibss, JOIN_IBSS);
#undef CMD
nla_nest_end(msg, nl_cmds);
@@ -665,7 +666,7 @@ static int nl80211_set_interface(struct
struct cfg80211_registered_device *drv;
struct vif_params params;
int err, ifindex;
- enum nl80211_iftype type;
+ enum nl80211_iftype otype, ntype;
struct net_device *dev;
u32 _flags, *flags = NULL;
bool change = false;
@@ -679,30 +680,27 @@ static int nl80211_set_interface(struct
goto unlock_rtnl;
ifindex = dev->ifindex;
- type = dev->ieee80211_ptr->iftype;
+ otype = ntype = dev->ieee80211_ptr->iftype;
dev_put(dev);
if (info->attrs[NL80211_ATTR_IFTYPE]) {
- enum nl80211_iftype ntype;
-
ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
- if (type != ntype)
+ if (otype != ntype)
change = true;
- type = ntype;
- if (type > NL80211_IFTYPE_MAX) {
+ if (ntype > NL80211_IFTYPE_MAX) {
err = -EINVAL;
goto unlock;
}
}
if (!drv->ops->change_virtual_intf ||
- !(drv->wiphy.interface_modes & (1 << type))) {
+ !(drv->wiphy.interface_modes & (1 << ntype))) {
err = -EOPNOTSUPP;
goto unlock;
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- if (type != NL80211_IFTYPE_MESH_POINT) {
+ if (ntype != NL80211_IFTYPE_MESH_POINT) {
err = -EINVAL;
goto unlock;
}
@@ -712,7 +710,7 @@ static int nl80211_set_interface(struct
}
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
- if (type != NL80211_IFTYPE_MONITOR) {
+ if (ntype != NL80211_IFTYPE_MONITOR) {
err = -EINVAL;
goto unlock;
}
@@ -727,12 +725,17 @@ static int nl80211_set_interface(struct
if (change)
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
- type, flags, ¶ms);
+ ntype, flags, ¶ms);
else
err = 0;
dev = __dev_get_by_index(&init_net, ifindex);
- WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
+ WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
+
+ if (dev && !err && (ntype != otype)) {
+ if (otype == NL80211_IFTYPE_ADHOC)
+ cfg80211_clear_ibss(dev);
+ }
unlock:
cfg80211_put_dev(drv);
@@ -3049,6 +3052,113 @@ unlock_rtnl:
return err;
}
+static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ struct cfg80211_ibss_params params;
+ struct wiphy *wiphy;
+ int err;
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_SSID] ||
+ !nla_len(info->attrs[NL80211_ATTR_SSID]))
+ return -EINVAL;
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->join_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ wiphy = &drv->wiphy;
+ memset(¶ms, 0, sizeof(params));
+
+ if (info->attrs[NL80211_ATTR_MAC])
+ params.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ params.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+ params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
+ params.channel = ieee80211_get_channel(
+ wiphy,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (!params.channel ||
+ params.channel->flags & IEEE80211_CHAN_NO_IBSS) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+ err = cfg80211_join_ibss(drv, dev, ¶ms);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
+static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ int err;
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->leave_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ err = cfg80211_leave_ibss(drv, dev);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -3250,6 +3360,18 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = NL80211_CMD_JOIN_IBSS,
+ .doit = nl80211_join_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = NL80211_CMD_LEAVE_IBSS,
+ .doit = nl80211_leave_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
.name = "mlme",
@@ -3463,6 +3585,40 @@ void nl80211_send_disassoc(struct cfg802
NL80211_CMD_DISASSOCIATE);
}
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
enum nl80211_key_type key_type, int key_id,
--- wireless-testing.orig/net/wireless/core.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/core.c 2009-04-19 00:23:33.000000000 +0200
@@ -450,6 +450,22 @@ static int cfg80211_netdev_notifier_call
dev->ieee80211_ptr->netdev = dev;
mutex_unlock(&rdev->devlist_mtx);
break;
+ case NETDEV_GOING_DOWN:
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->ssid_len)
+ break;
+ cfg80211_leave_ibss(rdev, dev);
+ break;
+ case NETDEV_UP:
+#ifdef CONFIG_WIRELESS_EXT
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->ssid_len)
+ break;
+ cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext);
+ break;
+#endif
case NETDEV_UNREGISTER:
mutex_lock(&rdev->devlist_mtx);
if (!list_empty(&dev->ieee80211_ptr->list)) {
--- wireless-testing.orig/net/wireless/Makefile 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/Makefile 2009-04-18 23:50:47.000000000 +0200
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib8
obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
ccflags-y += -D__CHECK_ENDIAN__
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/wireless/ibss.c 2009-04-19 00:34:16.000000000 +0200
@@ -0,0 +1,308 @@
+/*
+ * Some IBSS support code for cfg80211.
+ *
+ * Copyright 2009 Johannes Berg <[email protected]>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include <net/wireless.h>
+#include "nl80211.h"
+
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+ union iwreq_data wrqu;
+#endif
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return;
+
+ if (WARN_ON(!wdev->ssid_len))
+ return;
+
+ if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
+ return;
+
+ bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+ wdev->ssid, wdev->ssid_len,
+ WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+
+ if (WARN_ON(!bss))
+ return;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ cfg80211_hold_bss(bss);
+ wdev->current_bss = bss;
+ memcpy(wdev->bssid, bssid, ETH_ALEN);
+
+ nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
+#ifdef CONFIG_WIRELESS_EXT
+ memset(&wrqu, 0, sizeof(wrqu));
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+EXPORT_SYMBOL(cfg80211_ibss_joined);
+
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
+
+ if (err)
+ return err;
+
+ memcpy(wdev->ssid, params->ssid, params->ssid_len);
+ wdev->ssid_len = params->ssid_len;
+
+ return 0;
+}
+
+void cfg80211_clear_ibss(struct net_device *dev)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ wdev->current_bss = NULL;
+ wdev->ssid_len = 0;
+ memset(wdev->bssid, 0, ETH_ALEN);
+}
+
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
+{
+ int err;
+
+ err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
+
+ if (err)
+ return err;
+
+ cfg80211_clear_ibss(dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_WIRELESS_EXT
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ chan = cfg80211_wext_freq(wdev->wiphy, freq);
+ if (chan && IS_ERR(chan))
+ return PTR_ERR(chan);
+
+ if (wdev->wext.channel == chan)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ wdev->wext.channel = chan;
+
+ if (!netif_running(dev))
+ return 0;
+
+ err = 0;
+ if (wdev->wext.ssid_len)
+ err = cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev,
+ &wdev->wext);
+ return err;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
+
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan = NULL;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ chan = wdev->wext.channel;
+ if (chan)
+ goto ok;
+
+ if (wdev->current_bss) {
+ chan = wdev->current_bss->channel;
+ goto ok;
+ }
+
+ return -EINVAL;
+ ok:
+ freq->m = chan->center_freq;
+ freq->e = 6;
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
+
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ size_t len = data->length;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ /* iwconfig uses nul termination in SSID.. */
+ if (len > 0 && ssid[len - 1] == '\0')
+ len--;
+
+ wdev->wext.ssid = wdev->ssid;
+ memcpy(wdev->wext.ssid, ssid, len);
+ wdev->wext.ssid_len = len;
+
+ if (!netif_running(dev))
+ return 0;
+
+ if (!len)
+ return 0;
+
+ return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev,
+ &wdev->wext);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
+
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ data->flags = 1;
+ data->length = wdev->wext.ssid_len;
+ memcpy(ssid, wdev->wext.ssid, data->length);
+
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
+
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u8 *bssid = ap_addr->sa_data;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (ap_addr->sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* automatic mode */
+ if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+ bssid = NULL;
+
+ /* both automatic */
+ if (!bssid && !wdev->wext.bssid)
+ return 0;
+
+ /* fixed already - and no change */
+ if (wdev->wext.bssid && bssid &&
+ compare_ether_addr(bssid, wdev->wext.bssid) == 0)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ if (bssid) {
+ memcpy(wdev->wext_bssid, bssid, ETH_ALEN);
+ wdev->wext.bssid = wdev->wext_bssid;
+ } else
+ wdev->wext.bssid = NULL;
+
+ if (!netif_running(dev))
+ return 0;
+
+ return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev, &wdev->wext);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
+
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+
+ if (wdev->wext.bssid) {
+ memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN);
+ return 0;
+ }
+
+ memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
+#endif
--- wireless-testing.orig/net/wireless/nl80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.h 2009-04-18 23:50:47.000000000 +0200
@@ -34,4 +34,8 @@ nl80211_send_beacon_hint_event(struct wi
struct ieee80211_channel *channel_before,
struct ieee80211_channel *channel_after);
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp);
+
#endif /* __NET_WIRELESS_NL80211_H */
--- wireless-testing.orig/include/net/wireless.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/net/wireless.h 2009-04-19 00:33:15.000000000 +0200
@@ -265,6 +265,8 @@ struct wiphy {
*
* @wiphy: pointer to hardware description
* @iftype: interface type
+ * @list: (private)
+ * @netdev (private)
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -273,6 +275,18 @@ struct wireless_dev {
/* private to the generic wireless code */
struct list_head list;
struct net_device *netdev;
+
+ /* currently used for IBSS - might be rearranged in the future */
+ struct cfg80211_bss *current_bss;
+ u8 bssid[ETH_ALEN];
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 ssid_len;
+
+#ifdef CONFIG_WIRELESS_EXT
+ /* wext data */
+ struct cfg80211_ibss_params wext;
+ u8 wext_bssid[ETH_ALEN];
+#endif
};
/**
--- wireless-testing.orig/net/wireless/core.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/core.h 2009-04-18 23:50:47.000000000 +0200
@@ -144,4 +144,12 @@ void cfg80211_bss_expire(struct cfg80211
void cfg80211_bss_age(struct cfg80211_registered_device *dev,
unsigned long age_secs);
+/* IBSS */
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+void cfg80211_clear_ibss(struct net_device *dev);
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev);
+
#endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/wext-compat.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c 2009-04-18 23:50:47.000000000 +0200
@@ -241,3 +241,33 @@ int cfg80211_wext_giwrange(struct net_de
return 0;
}
EXPORT_SYMBOL(cfg80211_wext_giwrange);
+
+
+/**
+ * cfg80211_wext_freq - get wext frequency for non-"auto"
+ * @wiphy: the wiphy
+ * @freq: the wext freq encoding
+ *
+ * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
+ */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq)
+{
+ if (freq->e == 0) {
+ if (freq->m < 0)
+ return NULL;
+ else
+ return ieee80211_get_channel(wiphy,
+ ieee80211_channel_to_frequency(freq->m));
+ } else {
+ int i, div = 1000000;
+ for (i = 0; i < freq->e; i++)
+ div /= 10;
+ if (div > 0)
+ return ieee80211_get_channel(wiphy, freq->m / div);
+ else
+ return ERR_PTR(-EINVAL);
+ }
+
+}
+EXPORT_SYMBOL(cfg80211_wext_freq);
On Sun, 2009-04-19 at 18:54 +0200, Alina Friedrichsen wrote:
> > We might actually do that -- as part of the commands "connect" and
> > "disconnect" that do not exist yet and subsume auth and assoc into one
> > for hardware that doesn't support it.
>
> Why not use these commands as a high-level and mode independent
> version of assoc/join_ibss? And then simply call it from the wext
> handlers?
>
> "Zwei Fliegen mit einer Klappe"?!
> (Translation: "Kill two birds with one stone".)
>
> So you have a equivalent for:
> iwconfig wlan0 essid test
> iw dev wlan0 connect test
I still haven't understood why those extra commands are bothering you so
much. Anyhow, you don't _connect_ to an IBSS so that would simply be
_wrong_.
johannes
This adds IBSS API along with (preliminary) wext handlers.
The wext handlers can only do IBSS so you need to call them
from your own wext handlers if the mode is IBSS.
Signed-off-by: Johannes Berg <[email protected]>
---
include/linux/nl80211.h | 11 +
include/net/cfg80211.h | 68 +++++++++
include/net/wireless.h | 14 ++
net/wireless/Makefile | 2
net/wireless/core.c | 16 ++
net/wireless/core.h | 8 +
net/wireless/ibss.c | 308 +++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.c | 180 ++++++++++++++++++++++++--
net/wireless/nl80211.h | 4
net/wireless/wext-compat.c | 30 ++++
10 files changed, 628 insertions(+), 13 deletions(-)
--- wireless-testing.orig/include/linux/nl80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h 2009-04-19 00:35:58.000000000 +0200
@@ -223,6 +223,14 @@
* %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
* event matches with MLME-MICHAELMICFAILURE.indication() primitive
*
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID, and
+ * optionally a MAC (as BSSID) and FREQ attribute if those should be
+ * fixed rather than automatically determined. Can only be executed
+ * on a network interface that is UP, and fixed BSSID/FREQ may be
+ * rejected.
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ * determined by the network interface.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -288,6 +296,9 @@ enum nl80211_commands {
NL80211_CMD_REG_BEACON_HINT,
+ NL80211_CMD_JOIN_IBSS,
+ NL80211_CMD_LEAVE_IBSS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- wireless-testing.orig/include/net/cfg80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h 2009-04-19 00:35:58.000000000 +0200
@@ -658,6 +658,27 @@ struct cfg80211_disassoc_request {
};
/**
+ * struct cfg80211_ibss_params - IBSS parameters
+ *
+ * This structure defines the IBSS parameters for the join_ibss()
+ * method.
+ *
+ * @ssid: The SSID, will always be non-null.
+ * @ssid_len: The length of the SSID, will always be non-zero.
+ * @bssid: Fixed BSSID requested, may be %NULL.
+ * @channel: Fixed channel requested, may be %NULL.
+ * @ie: information element(s) to include in the beacon
+ * @ie_len: length of that
+ */
+struct cfg80211_ibss_params {
+ u8 *ssid;
+ u8 *bssid;
+ struct ieee80211_channel *channel;
+ u8 *ie;
+ u8 ssid_len, ie_len;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -732,6 +753,11 @@ struct cfg80211_disassoc_request {
* @assoc: Request to (re)associate with the specified peer
* @deauth: Request to deauthenticate from the specified peer
* @disassoc: Request to disassociate from the specified peer
+ *
+ * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
+ * cfg80211_ibss_joined(), also call that function when changing BSSID due
+ * to a merge.
+ * @leave_ibss: Leave the IBSS.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
@@ -817,6 +843,10 @@ struct cfg80211_ops {
struct cfg80211_deauth_request *req);
int (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_disassoc_request *req);
+
+ int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+ int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
};
/* temporary wext handlers */
@@ -836,6 +866,28 @@ int cfg80211_wext_giwscan(struct net_dev
int cfg80211_wext_giwrange(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra);
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+
+/* wext helper for now (to be removed) */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq);
/**
* cfg80211_scan_done - notify that scan finished
@@ -981,4 +1033,20 @@ void cfg80211_michael_mic_failure(struct
enum nl80211_key_type key_type, int key_id,
const u8 *tsc);
+/**
+ * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the IBSS joined
+ * @gfp: allocation flags
+ *
+ * This function notifies cfg80211 that the device joined an IBSS or
+ * switched to a different BSSID. Before this function can be called,
+ * either a beacon has to have been received from the IBSS, or one of
+ * the cfg80211_inform_bss{,_frame} functions must have been called
+ * with the locally generated beacon -- this guarantees that there is
+ * always a scan result for this IBSS. cfg80211 will handle the rest.
+ */
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
+
#endif /* __NET_CFG80211_H */
--- wireless-testing.orig/net/wireless/nl80211.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c 2009-04-19 00:35:58.000000000 +0200
@@ -322,6 +322,7 @@ static int nl80211_send_wiphy(struct sk_
CMD(assoc, ASSOCIATE);
CMD(deauth, DEAUTHENTICATE);
CMD(disassoc, DISASSOCIATE);
+ CMD(join_ibss, JOIN_IBSS);
#undef CMD
nla_nest_end(msg, nl_cmds);
@@ -665,7 +666,7 @@ static int nl80211_set_interface(struct
struct cfg80211_registered_device *drv;
struct vif_params params;
int err, ifindex;
- enum nl80211_iftype type;
+ enum nl80211_iftype otype, ntype;
struct net_device *dev;
u32 _flags, *flags = NULL;
bool change = false;
@@ -679,30 +680,27 @@ static int nl80211_set_interface(struct
goto unlock_rtnl;
ifindex = dev->ifindex;
- type = dev->ieee80211_ptr->iftype;
+ otype = ntype = dev->ieee80211_ptr->iftype;
dev_put(dev);
if (info->attrs[NL80211_ATTR_IFTYPE]) {
- enum nl80211_iftype ntype;
-
ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
- if (type != ntype)
+ if (otype != ntype)
change = true;
- type = ntype;
- if (type > NL80211_IFTYPE_MAX) {
+ if (ntype > NL80211_IFTYPE_MAX) {
err = -EINVAL;
goto unlock;
}
}
if (!drv->ops->change_virtual_intf ||
- !(drv->wiphy.interface_modes & (1 << type))) {
+ !(drv->wiphy.interface_modes & (1 << ntype))) {
err = -EOPNOTSUPP;
goto unlock;
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- if (type != NL80211_IFTYPE_MESH_POINT) {
+ if (ntype != NL80211_IFTYPE_MESH_POINT) {
err = -EINVAL;
goto unlock;
}
@@ -712,7 +710,7 @@ static int nl80211_set_interface(struct
}
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
- if (type != NL80211_IFTYPE_MONITOR) {
+ if (ntype != NL80211_IFTYPE_MONITOR) {
err = -EINVAL;
goto unlock;
}
@@ -727,12 +725,17 @@ static int nl80211_set_interface(struct
if (change)
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
- type, flags, ¶ms);
+ ntype, flags, ¶ms);
else
err = 0;
dev = __dev_get_by_index(&init_net, ifindex);
- WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
+ WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
+
+ if (dev && !err && (ntype != otype)) {
+ if (otype == NL80211_IFTYPE_ADHOC)
+ cfg80211_clear_ibss(dev);
+ }
unlock:
cfg80211_put_dev(drv);
@@ -3049,6 +3052,113 @@ unlock_rtnl:
return err;
}
+static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ struct cfg80211_ibss_params params;
+ struct wiphy *wiphy;
+ int err;
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_SSID] ||
+ !nla_len(info->attrs[NL80211_ATTR_SSID]))
+ return -EINVAL;
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->join_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ wiphy = &drv->wiphy;
+ memset(¶ms, 0, sizeof(params));
+
+ if (info->attrs[NL80211_ATTR_MAC])
+ params.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ params.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+ params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
+ params.channel = ieee80211_get_channel(
+ wiphy,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (!params.channel ||
+ params.channel->flags & IEEE80211_CHAN_NO_IBSS) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+ err = cfg80211_join_ibss(drv, dev, ¶ms);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
+static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ int err;
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->leave_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ err = cfg80211_leave_ibss(drv, dev);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -3250,6 +3360,18 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = NL80211_CMD_JOIN_IBSS,
+ .doit = nl80211_join_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = NL80211_CMD_LEAVE_IBSS,
+ .doit = nl80211_leave_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
.name = "mlme",
@@ -3463,6 +3585,40 @@ void nl80211_send_disassoc(struct cfg802
NL80211_CMD_DISASSOCIATE);
}
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
enum nl80211_key_type key_type, int key_id,
--- wireless-testing.orig/net/wireless/core.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/core.c 2009-04-19 01:13:45.000000000 +0200
@@ -450,6 +450,22 @@ static int cfg80211_netdev_notifier_call
dev->ieee80211_ptr->netdev = dev;
mutex_unlock(&rdev->devlist_mtx);
break;
+ case NETDEV_GOING_DOWN:
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->ssid_len)
+ break;
+ cfg80211_leave_ibss(rdev, dev);
+ break;
+ case NETDEV_UP:
+#ifdef CONFIG_WIRELESS_EXT
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->wext.ssid_len)
+ break;
+ cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext);
+ break;
+#endif
case NETDEV_UNREGISTER:
mutex_lock(&rdev->devlist_mtx);
if (!list_empty(&dev->ieee80211_ptr->list)) {
--- wireless-testing.orig/net/wireless/Makefile 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/Makefile 2009-04-18 23:50:47.000000000 +0200
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib8
obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
ccflags-y += -D__CHECK_ENDIAN__
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/wireless/ibss.c 2009-04-19 00:34:16.000000000 +0200
@@ -0,0 +1,308 @@
+/*
+ * Some IBSS support code for cfg80211.
+ *
+ * Copyright 2009 Johannes Berg <[email protected]>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include <net/wireless.h>
+#include "nl80211.h"
+
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+ union iwreq_data wrqu;
+#endif
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return;
+
+ if (WARN_ON(!wdev->ssid_len))
+ return;
+
+ if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
+ return;
+
+ bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+ wdev->ssid, wdev->ssid_len,
+ WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+
+ if (WARN_ON(!bss))
+ return;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ cfg80211_hold_bss(bss);
+ wdev->current_bss = bss;
+ memcpy(wdev->bssid, bssid, ETH_ALEN);
+
+ nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
+#ifdef CONFIG_WIRELESS_EXT
+ memset(&wrqu, 0, sizeof(wrqu));
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+EXPORT_SYMBOL(cfg80211_ibss_joined);
+
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
+
+ if (err)
+ return err;
+
+ memcpy(wdev->ssid, params->ssid, params->ssid_len);
+ wdev->ssid_len = params->ssid_len;
+
+ return 0;
+}
+
+void cfg80211_clear_ibss(struct net_device *dev)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ wdev->current_bss = NULL;
+ wdev->ssid_len = 0;
+ memset(wdev->bssid, 0, ETH_ALEN);
+}
+
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
+{
+ int err;
+
+ err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
+
+ if (err)
+ return err;
+
+ cfg80211_clear_ibss(dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_WIRELESS_EXT
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ chan = cfg80211_wext_freq(wdev->wiphy, freq);
+ if (chan && IS_ERR(chan))
+ return PTR_ERR(chan);
+
+ if (wdev->wext.channel == chan)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ wdev->wext.channel = chan;
+
+ if (!netif_running(dev))
+ return 0;
+
+ err = 0;
+ if (wdev->wext.ssid_len)
+ err = cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev,
+ &wdev->wext);
+ return err;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
+
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan = NULL;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ chan = wdev->wext.channel;
+ if (chan)
+ goto ok;
+
+ if (wdev->current_bss) {
+ chan = wdev->current_bss->channel;
+ goto ok;
+ }
+
+ return -EINVAL;
+ ok:
+ freq->m = chan->center_freq;
+ freq->e = 6;
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
+
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ size_t len = data->length;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ /* iwconfig uses nul termination in SSID.. */
+ if (len > 0 && ssid[len - 1] == '\0')
+ len--;
+
+ wdev->wext.ssid = wdev->ssid;
+ memcpy(wdev->wext.ssid, ssid, len);
+ wdev->wext.ssid_len = len;
+
+ if (!netif_running(dev))
+ return 0;
+
+ if (!len)
+ return 0;
+
+ return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev,
+ &wdev->wext);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
+
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ data->flags = 1;
+ data->length = wdev->wext.ssid_len;
+ memcpy(ssid, wdev->wext.ssid, data->length);
+
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
+
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u8 *bssid = ap_addr->sa_data;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (ap_addr->sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* automatic mode */
+ if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+ bssid = NULL;
+
+ /* both automatic */
+ if (!bssid && !wdev->wext.bssid)
+ return 0;
+
+ /* fixed already - and no change */
+ if (wdev->wext.bssid && bssid &&
+ compare_ether_addr(bssid, wdev->wext.bssid) == 0)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev);
+ if (err)
+ return err;
+ }
+
+ if (bssid) {
+ memcpy(wdev->wext_bssid, bssid, ETH_ALEN);
+ wdev->wext.bssid = wdev->wext_bssid;
+ } else
+ wdev->wext.bssid = NULL;
+
+ if (!netif_running(dev))
+ return 0;
+
+ return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), dev, &wdev->wext);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
+
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+
+ if (wdev->wext.bssid) {
+ memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN);
+ return 0;
+ }
+
+ memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
+#endif
--- wireless-testing.orig/net/wireless/nl80211.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.h 2009-04-18 23:50:47.000000000 +0200
@@ -34,4 +34,8 @@ nl80211_send_beacon_hint_event(struct wi
struct ieee80211_channel *channel_before,
struct ieee80211_channel *channel_after);
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp);
+
#endif /* __NET_WIRELESS_NL80211_H */
--- wireless-testing.orig/include/net/wireless.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/include/net/wireless.h 2009-04-19 00:33:15.000000000 +0200
@@ -265,6 +265,8 @@ struct wiphy {
*
* @wiphy: pointer to hardware description
* @iftype: interface type
+ * @list: (private)
+ * @netdev (private)
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -273,6 +275,18 @@ struct wireless_dev {
/* private to the generic wireless code */
struct list_head list;
struct net_device *netdev;
+
+ /* currently used for IBSS - might be rearranged in the future */
+ struct cfg80211_bss *current_bss;
+ u8 bssid[ETH_ALEN];
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 ssid_len;
+
+#ifdef CONFIG_WIRELESS_EXT
+ /* wext data */
+ struct cfg80211_ibss_params wext;
+ u8 wext_bssid[ETH_ALEN];
+#endif
};
/**
--- wireless-testing.orig/net/wireless/core.h 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/core.h 2009-04-18 23:50:47.000000000 +0200
@@ -144,4 +144,12 @@ void cfg80211_bss_expire(struct cfg80211
void cfg80211_bss_age(struct cfg80211_registered_device *dev,
unsigned long age_secs);
+/* IBSS */
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+void cfg80211_clear_ibss(struct net_device *dev);
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev);
+
#endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/wext-compat.c 2009-04-18 23:50:46.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c 2009-04-18 23:50:47.000000000 +0200
@@ -241,3 +241,33 @@ int cfg80211_wext_giwrange(struct net_de
return 0;
}
EXPORT_SYMBOL(cfg80211_wext_giwrange);
+
+
+/**
+ * cfg80211_wext_freq - get wext frequency for non-"auto"
+ * @wiphy: the wiphy
+ * @freq: the wext freq encoding
+ *
+ * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
+ */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq)
+{
+ if (freq->e == 0) {
+ if (freq->m < 0)
+ return NULL;
+ else
+ return ieee80211_get_channel(wiphy,
+ ieee80211_channel_to_frequency(freq->m));
+ } else {
+ int i, div = 1000000;
+ for (i = 0; i < freq->e; i++)
+ div /= 10;
+ if (div > 0)
+ return ieee80211_get_channel(wiphy, freq->m / div);
+ else
+ return ERR_PTR(-EINVAL);
+ }
+
+}
+EXPORT_SYMBOL(cfg80211_wext_freq);
Hello Johannes!
> Because you don't associate with an IBSS?
This is only a name, but the call does mostly the same. I think having =
one generic API goes more along with the UNIX philosophy, than having f=
or each mode a defend API, on which almost only the names of the calls =
are deferent.
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
> In cfg80211 an indication for channel auto select is needed for IBSS =
and
> _STA_ mode, to implement with it the old wext interface. If not set t=
he
> channel shouldn't be changed. If you not want store this flag in cfg8=
0211, you
> must store it in the channel functions of wext to have the same behav=
ior
> like now.
I looked in the Source:
> @chan: The channel to use or %NULL if not specified
> (auto-select based on scan results)
I think this is enough for this purpose.
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
> Actually, I'm arguing in another email that the channel_auto should b=
e
> removed in assoc... And IMHO fixed is much clearer for what we (well =
you
> mostly actually!) want.
But normally you say with a NULL-Pointer, that it should be auto-detect=
ed and if it's set, that you want set it manually. This calls how it is=
now breaks with this concept.
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
Hello Marcel!
> and that is just plain wrong to begin with. If you want a one command=
do
> everything, then do that in userspace and not inside a kernel API.
Then why not implement deferent syscalls for floppy disks, hard disk dr=
ives, solid state disks and normal files? If you want one generic API t=
han write an users-space library.
Thought-out APIs sucks, MS-DOS rules!
> >>From my point of view, WEXT can die right now. Just doing something=
to
> make WEXT happy is wrong. If you want something like that then do it =
in
> userspace. I just don't see the need here for an extra kernel API.
There is no concept, what should be in user-space and what not. It's al=
l mixed together. Not a microkernel, no a monolithic kernel, awful.
I'm not needed any more, so I can switching off myself. Bye.
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 21:31 +0200, Marcel Holtmann wrote:
> Hi Alina,
>
> let me repeat what Johannes mentioned earlier, please don't send emails
> twice. Just use a proper working MUA and do Reply-All.
>
> > > and that is just plain wrong to begin with. If you want a one command do
> > > everything, then do that in userspace and not inside a kernel API.
> >
> > Then why not implement deferent syscalls for floppy disks, hard disk
> drives, solid state disks and normal files? If you want one generic
> API than write an users-space library.
> >
> > Thought-out APIs sucks, MS-DOS rules!
>
> you are seriously comparing block devices to network device now? They
> are different, go figure. You better bring technical arguments that
> matter and not something far fetched from a total different technology.
Well you could make that comparison, if you do it correctly... I guess
the proposed mashed-up calls would be very much like configuring a
remote raid storage by writing to the block device it exports. Needless
(hopefully!!) to say, that is not a good idea.
johannes
> You don't need wpa_supplicant, you just need an SME for that. Eventua=
lly
> we'll implement one in iw.
You need one simple SME for compatibility with wext in the kernel-space=
=2E Why not allow to access it with nl80211?
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
On Sun, 2009-04-19 at 20:43 +0200, Alina Friedrichsen wrote:
> Hello Marcel!
>
> > and that is just plain wrong to begin with. If you want a one command do
> > everything, then do that in userspace and not inside a kernel API.
>
> Then why not implement deferent syscalls for floppy disks, hard disk
> drives, solid state disks and normal files? If you want one generic
> API than write an users-space library.
>
> Thought-out APIs sucks, MS-DOS rules!
>
> > >>From my point of view, WEXT can die right now. Just doing something to
> > make WEXT happy is wrong. If you want something like that then do it in
> > userspace. I just don't see the need here for an extra kernel API.
>
> There is no concept, what should be in user-space and what not. It's
> all mixed together. Not a microkernel, no a monolithic kernel, awful.
>
> I'm not needed any more, so I can switching off myself. Bye.
ROFL.
Your credibility has just gone below zero.
johannes
> you know what, the next time I run into him, I ask his opinion about
> this ;)
Implement as few (sys)calls as possible, only as much as needed. Genera=
lize as much as you can.
He has compared operating systems as less syscalls they have:
MS-DOS > UNIX > Mach > Amoeba
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 18:13 +0200, Alina Friedrichsen wrote:
> > You don't need wpa_supplicant, you just need an SME for that. Eventually
> > we'll implement one in iw.
>
> You need one simple SME for compatibility with wext in the
> kernel-space. Why not allow to access it with nl80211?
We might actually do that -- as part of the commands "connect" and
"disconnect" that do not exist yet and subsume auth and assoc into one
for hardware that doesn't support it.
johannes
Hello Johannes!
> Hmm, I forgot one thing -- you may want to create an IBSS on a specif=
ic
> channel, but still allow it scan for other IBSSes. I guess we need a
> flag for that and not make "channel set" imply fixed channel.
In cfg80211 an indication for channel auto select is needed for IBSS an=
d _STA_ mode, to implement with it the old wext interface. If not set t=
he channel shouldn't be changed. If you not want store this flag in cfg=
80211, you must store it in the channel functions of wext to have the s=
ame behavior like now.
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
Hi!
Can you please spell "different" and "difference" correctly? I keep
getting confused! "deference" is an English word too :)
Anyway, I think you're confused because cfg80211_assoc_request looks
like cfg80211_ibss_params. Trust me -- that will change.
Either way I'm not going to argue this with you anyway, I've already
decided to do it this way. You'd have to find many many people who agree
with you to convince me otherwise.
johannes
> Ahrg, can you stop sending mail to me and the list as two mails? If i=
t's
> a problem then just reply to the list -- although I prefer to be CC'e=
d.
Sorry, mannerism.
> It's not about optimisations, it's about correctness. If you don't se=
t
> all things at once you don't know what will happen since something el=
se
> might send commands too.
In the praxis you only don't need it, unlike the automatic and fixed ch=
annel config.
If you set a channel you want the IBSS on this this channel regardless =
if one already exist or not. If you don't, you never mind on the channe=
l, even if the IBSS don't exist.
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
Hello!
> It will pass in a cfg80211_bss structure instead of all those paramet=
ers
> once we move all the stuff into cfg80211.
This is not mode specific.
All members of cfg80211_bss are not known by the user-space without sca=
nning. I don't like the idea of needing the wpa_supplicant for joining =
an unencrypted network.
I want even with nl80211 able to simply call:
iw dev wlan0 assoc test_ssid
like I now call:
iwconfig wlan0 essid test_ssid
> True. But I'm not much interested in technical arguments about this
> point since I and others are convinced that this way is better.
Maybe it's easier to design and implement but not necessarily the clean=
er and more thought-out API, I think.
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
On Sun, 2009-04-19 at 17:53 +0200, Alina Friedrichsen wrote:
> Hello!
>
> > It will pass in a cfg80211_bss structure instead of all those parameters
> > once we move all the stuff into cfg80211.
>
> This is not mode specific.
Well, the struct isn't but ibss cannot use a bss structure because then
we'd have to fake one without knowing what is around us.
> All members of cfg80211_bss are not known by the user-space without
> scanning.
Nope. Not the IEs for the locally created IBSS for example.
> I don't like the idea of needing the wpa_supplicant for joining an
> unencrypted network.
You don't need wpa_supplicant, you just need an SME for that. Eventually
we'll implement one in iw.
johannes
Ahrg, can you stop sending mail to me and the list as two mails? If it's
a problem then just reply to the list -- although I prefer to be CC'ed.
On Sun, 2009-04-19 at 19:15 +0200, Alina Friedrichsen wrote:
> > I don't think so -- how would I express "use channel 5 if you can't find
> > anything" in a single nl80211 command?
>
> In the normal usage, you don't need it. Either you want make all
> settings fixed if you build a stationary node, or you set only the
> SSID if you join the IBSS temporary with your notebook. I don't see a
> real reason to have an optimized one command solution for that. And on
> multi interface wifis it's better set the channel and join the IBSS in
> two different steps. The channel setting has site-effects on the other
> interfaces, the IBSS joining mostly don't. (except TSF and so)
It's not about optimisations, it's about correctness. If you don't set
all things at once you don't know what will happen since something else
might send commands too.
johannes
Hello Marcel!
> you argue command line tools against kernel exposed API.
I use the command line syntax to explain the kernel API.
> Both have
> nothing to do with each other on that level.
Most commands are mapped 1:1. And the API easier to understand if it is=
so.
> If you don't like the iw
> syntax then fix it and provide a command that does all three task for
> you. No need to mess with the kernel interface for that.
I think now, provide a high-level command besides the low-level command=
s is a good idea. We need it for the old wext interface anyway. Then we=
xt can only call this command and don't need own intelligence. So than =
it's only a foolish wrapper, like it should.
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
Hello Johannes!
> This adds IBSS API along with (preliminary) wext handlers.
> The wext handlers can only do IBSS so you need to call them
> from your own wext handlers if the mode is IBSS.
Why make not assoc() and disassoc() to a generic mode independent call?=
Only the handling is deferent on each mode.
Regards
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
Hallo Johannes!
> Huh? No, it does not mostly do the same. Quite not so. Managed and IB=
SS
> modes are _really_ different. Almost the only thing they have in comm=
on
> is that they use an SSID and a BSSID.
A character device is not the same as a block device too but it uses th=
e same API like normal files. Thats the deference to DOS. And assoc() i=
s the equivalent for join_ibss(), like read() or write() it can impleme=
nted with the same interface. In WEXT it's implemented with the same in=
terface.
> And an airy concept of "UNIX philosophy" really has nothing whatsoeve=
r
> to do with it.
Unfortunately I don't have the book "Modern Operating Systems" here so =
I can't quote it.
Regards
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 20:18 +0200, Alina Friedrichsen wrote:
> > No, that's not true, you could well want to create your network on a
> > channel that isn't used that much or whatever.
>
> Okay that's is an argument. But then I would implement it more closer
> to the the handling of the assoc() call.
>
> * @channel: The channel to use or %NULL if not specified
> * (auto-select based on scan results)
> * @channel_auto: Auto-select channel based on scan results,
> * only use the specified channel for creating a new IBSS.
Actually, I'm arguing in another email that the channel_auto should be
removed in assoc... And IMHO fixed is much clearer for what we (well you
mostly actually!) want.
johannes
Hello Johannes!
> That's not what I was referring to -- and wext doesn't actually allow
> what I'm referring to afaik.
You must budget it, when you want implement the old wext code clean wit=
h cfg80211.
> When you want to create an IBSS on channel 5, what do you do?
>=20
> I think you have to
> iwconfig wlan0 essid test
> iwconfig wlan0 channel 5
> iwconfig wlan0 ap off # clear fixed channel bit
>=20
> which is ... weird.
Why not make simply the following?
iwconfig wlan0 channel 5
iwconfig wlan0 essid test
Regards
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 17:16 +0200, Alina Friedrichsen wrote:
> Hello!
>
> > Anyway, I think you're confused because cfg80211_assoc_request looks
> > like cfg80211_ibss_params. Trust me -- that will change.
>
> How much?
It will pass in a cfg80211_bss structure instead of all those parameters
once we move all the stuff into cfg80211.
> > Either way I'm not going to argue this with you anyway, I've already
> > decided to do it this way. You'd have to find many many people who agree
> > with you to convince me otherwise.
>
> That is not an technical argumentation. That is only plead on human hierarchy. :/
True. But I'm not much interested in technical arguments about this
point since I and others are convinced that this way is better.
johannes
On Sun, 2009-04-19 at 16:41 +0200, Alina Friedrichsen wrote:
> Hello Johannes!
>
> > That's not what I was referring to -- and wext doesn't actually allow
> > what I'm referring to afaik.
>
> You must budget it, when you want implement the old wext code clean with cfg80211.
>
> > When you want to create an IBSS on channel 5, what do you do?
> >
> > I think you have to
> > iwconfig wlan0 essid test
> > iwconfig wlan0 channel 5
> > iwconfig wlan0 ap off # clear fixed channel bit
> >
> > which is ... weird.
>
> Why not make simply the following?
>
> iwconfig wlan0 channel 5
> iwconfig wlan0 essid test
That fixes the channel to 5.
johannes
Hi Alina,
> > I still haven't understood why those extra commands are bothering you so
> > much.
>
> I want a simple generic API. I don't want to need the old wext for it.
>
> This would be stupid for me:
> iwconfig wlan0 essid test_essid
> vs.
> iw dev wlan0 assoc test_essid
> iw dev wlan0 join_ibss test_essid
> iw dev wlan0 set meshid test_essid
>
> On the last I get MS-DOS feeling.
you argue command line tools against kernel exposed API. Both have
nothing to do with each other on that level. If you don't like the iw
syntax then fix it and provide a command that does all three task for
you. No need to mess with the kernel interface for that.
Also the argument that WEXT does it doesn't fly with anybody here since
WEXT are clearly broken and not something we wanna ever copy again. If
cfg80211/nl80211 has to use a different API, then it will do that.
Regards
Marcel
On Sun, 2009-04-19 at 14:52 +0200, Alina Friedrichsen wrote:
> Hello Johannes!
>
> > This adds IBSS API along with (preliminary) wext handlers.
> > The wext handlers can only do IBSS so you need to call them
> > from your own wext handlers if the mode is IBSS.
>
> Why make not assoc() and disassoc() to a generic mode independent
> call? Only the handling is deferent on each mode.
Because you don't associate with an IBSS? Trying to shoehorn that into
the same would be ....?
johannes
> No, that's not true, you could well want to create your network on a
> channel that isn't used that much or whatever.
Okay that's is an argument. But then I would implement it more closer t=
o the the handling of the assoc() call.
* @channel: The channel to use or %NULL if not specified
* (auto-select based on scan results)
* @channel_auto: Auto-select channel based on scan results,
* only use the specified channel for creating a new IBSS.
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 19:45 +0200, Alina Friedrichsen wrote:
> If you set a channel you want the IBSS on this this channel regardless
> if one already exist or not. If you don't, you never mind on the
> channel, even if the IBSS don't exist.
No, that's not true, you could well want to create your network on a
channel that isn't used that much or whatever.
I'm going to stop reading this thread now -- there's no value in it
unless you can actually come up with new arguments.
johannes
On Sun, 2009-04-19 at 15:35 +0200, Alina Friedrichsen wrote:
> Hello Johannes!
>
> > Because you don't associate with an IBSS?
>
> This is only a name, but the call does mostly the same. I think having
> one generic API goes more along with the UNIX philosophy, than having
> for each mode a defend API, on which almost only the names of the
> calls are deferent.
Huh? No, it does not mostly do the same. Quite not so. Managed and IBSS
modes are _really_ different. Almost the only thing they have in common
is that they use an SSID and a BSSID.
And an airy concept of "UNIX philosophy" really has nothing whatsoever
to do with it.
johannes
Hi Alina,
> > you argue command line tools against kernel exposed API.
>
> I use the command line syntax to explain the kernel API.
and that is just plain wrong to begin with. If you want a one command do
everything, then do that in userspace and not inside a kernel API.
> > Both have
> > nothing to do with each other on that level.
>
> Most commands are mapped 1:1. And the API easier to understand if it is so.
That just happen to be this way right now. It doesn't have to stay that
way and if it would, that would be actually be stupid.
> > If you don't like the iw
> > syntax then fix it and provide a command that does all three task for
> > you. No need to mess with the kernel interface for that.
>
> I think now, provide a high-level command besides the low-level commands is a good idea. We need it for the old wext interface anyway. Then wext can only call this command and don't need own intelligence. So than it's only a foolish wrapper, like it should.
>From my point of view, WEXT can die right now. Just doing something to
make WEXT happy is wrong. If you want something like that then do it in
userspace. I just don't see the need here for an extra kernel API.
Regards
Marcel
> We might actually do that -- as part of the commands "connect" and
> "disconnect" that do not exist yet and subsume auth and assoc into on=
e
> for hardware that doesn't support it.
Why not use these commands as a high-level and mode independent version=
of assoc/join_ibss? And then simply call it from the wext handlers?
"Zwei Fliegen mit einer Klappe"?!
(Translation: "Kill two birds with one stone".)
So you have a equivalent for:
iwconfig wlan0 essid test
iw dev wlan0 connect test
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
> I don't think so -- how would I express "use channel 5 if you can't f=
ind
> anything" in a single nl80211 command?
In the normal usage, you don't need it. Either you want make all settin=
gs fixed if you build a stationary node, or you set only the SSID if yo=
u join the IBSS temporary with your notebook. I don't see a real reason=
to have an optimized one command solution for that. And on multi inter=
face wifis it's better set the channel and join the IBSS in two differe=
nt steps. The channel setting has site-effects on the other interfaces,=
the IBSS joining mostly don't. (except TSF and so)
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
Hi Alina,
let me repeat what Johannes mentioned earlier, please don't send emails
twice. Just use a proper working MUA and do Reply-All.
> > and that is just plain wrong to begin with. If you want a one command do
> > everything, then do that in userspace and not inside a kernel API.
>
> Then why not implement deferent syscalls for floppy disks, hard disk drives, solid state disks and normal files? If you want one generic API than write an users-space library.
>
> Thought-out APIs sucks, MS-DOS rules!
you are seriously comparing block devices to network device now? They
are different, go figure. You better bring technical arguments that
matter and not something far fetched from a total different technology.
> > >>From my point of view, WEXT can die right now. Just doing something to
> > make WEXT happy is wrong. If you want something like that then do it in
> > userspace. I just don't see the need here for an extra kernel API.
>
> There is no concept, what should be in user-space and what not. It's all mixed together. Not a microkernel, no a monolithic kernel, awful.
Actually there is a clear thing here. No policy inside the kernel. So no
stupid magic between ad-hoc and managed mode. The userspace has to make
the decision what it wants to do. The kernel just executes it.
Regards
Marcel
Hello!
> Anyway, I think you're confused because cfg80211_assoc_request looks
> like cfg80211_ibss_params. Trust me -- that will change.
How much?
> Either way I'm not going to argue this with you anyway, I've already
> decided to do it this way. You'd have to find many many people who ag=
ree
> with you to convince me otherwise.
That is not an technical argumentation. That is only plead on human hie=
rarchy. :/
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
On Sun, 2009-04-19 at 00:49 +0200, Johannes Berg wrote:
> This adds IBSS API along with (preliminary) wext handlers.
> The wext handlers can only do IBSS so you need to call them
> from your own wext handlers if the mode is IBSS.
Hmm, I forgot one thing -- you may want to create an IBSS on a specific
channel, but still allow it scan for other IBSSes. I guess we need a
flag for that and not make "channel set" imply fixed channel.
johannes
> Go ahead. But consider reading 802.11 first.
Read first Andrew Tanenbaum.
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
> ROFL.
>=20
> Your credibility has just gone below zero.
Tell me when nl80211v2 will be developed to solve the design errors of =
the first version.
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a
On Sun, 2009-04-19 at 18:32 +0200, Alina Friedrichsen wrote:
> > In cfg80211 an indication for channel auto select is needed for IBSS and
> > _STA_ mode, to implement with it the old wext interface. If not set the
> > channel shouldn't be changed. If you not want store this flag in cfg80211, you
> > must store it in the channel functions of wext to have the same behavior
> > like now.
>
> I looked in the Source:
>
> > @chan: The channel to use or %NULL if not specified
> > (auto-select based on scan results)
>
> I think this is enough for this purpose.
I don't think so -- how would I express "use channel 5 if you can't find
anything" in a single nl80211 command?
johannes
On Sun, 2009-04-19 at 21:01 +0200, Alina Friedrichsen wrote:
> > ROFL.
> >
> > Your credibility has just gone below zero.
>
> Tell me when nl80211v2 will be developed to solve the design errors of
> the first version.
Go ahead. But consider reading 802.11 first.
johannes
Hi Alina,
> > Go ahead. But consider reading 802.11 first.
>
> Read first Andrew Tanenbaum.
you know what, the next time I run into him, I ask his opinion about
this ;)
Regards
Marcel
> I still haven't understood why those extra commands are bothering you=
so
> much.
I want a simple generic API. I don't want to need the old wext for it.
This would be stupid for me:
iwconfig wlan0 essid test_essid
vs.
iw dev wlan0 assoc test_essid
iw dev wlan0 join_ibss test_essid
iw dev wlan0 set meshid test_essid
On the last I get MS-DOS feeling.
> Anyhow, you don't _connect_ to an IBSS so that would simply be
> _wrong_.
Then call it join or whatever you want.
"to join: [Ad-Hoc oder Managed Netzwerk] beitreten, trat bei, beigetret=
en" --- leo.org
Alina
--=20
Neu: GMX FreeDSL Komplettanschluss mit DSL 6.000 Flatrate + Telefonansc=
hluss f=FCr nur 17,95 Euro/mtl.!* http://dslspecial.gmx.de/freedsl-surf=
flat/?ac=3DOM.AD.PD003K11308T4569a