Search Linux Wireless

[PATCH] allow wiphy renaming

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch enables userspace to rename 802.11 PHYs via nl80211. It adds
the first multicast group and notifies it of these renames as well.

Also, it changes the default wiphy name to just "phy%d in anticipation
of Greg KH's sysfs change that will add the class name in front of the
name.

Signed-off-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>

---
If cfg80211 is built as a module then this patch requires device_rename
to be exported as per the patch I sent previously. I think this
functionality is quite important so userspace can get stable wiphy
names, but this patch will be blocked on the previous one. Up to you
(Greg, John) how you want to handle that.

Oh I made it impossible to rename a wiphy to phyN where N is not its own
index. Not sure if that is a good thing, but as long as debugfs can't
follow renames it's required. I couldn't easily figure out how to make
debugfs_rename() yet, I'm not into filesystems.

Tested and works :)

 include/linux/nl80211.h |   16 +++++++++++++++
 net/wireless/core.c     |   28 +++++++++++++++++++++++++-
 net/wireless/core.h     |    3 ++
 net/wireless/nl80211.c  |   50 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/nl80211.h  |    7 ++++++
 5 files changed, 103 insertions(+), 1 deletion(-)

--- wireless-dev.orig/include/linux/nl80211.h	2007-02-28 14:55:22.346381760 +0100
+++ wireless-dev/include/linux/nl80211.h	2007-02-28 14:55:34.406381760 +0100
@@ -118,6 +118,12 @@ enum {
 	 * ATTR_DEAUTHENTICATED */
 	NL80211_CMD_AUTHENTICATION_CHANGED,
 
+	/* rename a wiphy, takes a wiphy index and name */
+	NL80211_CMD_RENAME_WIPHY,
+
+	/* notification about rename */
+	NL80211_CMD_WIPHY_NEWNAME,
+
 	/* add commands here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -197,6 +203,8 @@ enum {
 
 	NL80211_ATTR_SCAN_TYPE,
 
+	NL80211_ATTR_WIPHY_NAME,
+
 	/* add attributes here */
 
 	/* used to define NL80211_ATTR_MAX below */
@@ -204,6 +212,14 @@ enum {
 };
 #define NL80211_ATTR_MAX (__NL80211_ATTR_AFTER_LAST - 1)
 
+/* multicast groups */
+enum {
+	/* be notified of configuration changes like wiphy renames */
+	NL80211_GROUP_CONFIG,
+
+	/* add groups here */
+};
+
 /**
  * NL80211_FLAG_TXSTATUS - send transmit status indication
  */
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-28 14:55:28.646381760 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-28 14:55:34.826381760 +0100
@@ -85,6 +85,8 @@ static struct nla_policy nl80211_policy[
 					       .len = NL80211_MAX_IE_LEN },
 	[NL80211_ATTR_ROAMING_CONTROL] = { .type = NLA_U32 },
 	[NL80211_ATTR_SCAN_TYPE] = { .type = NLA_U32 },
+	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
+				      .len = BUS_ID_SIZE-1 },
 };
 
 /* netlink command implementations */
@@ -123,6 +125,7 @@ static int nl80211_get_cmdlist(struct sk
 	NLA_PUT_FLAG(msg, NL80211_CMD_GET_CMDLIST);
 	NLA_PUT_FLAG(msg, NL80211_CMD_GET_WIPHYS);
 	NLA_PUT_FLAG(msg, NL80211_CMD_GET_INTERFACES);
+	NLA_PUT_FLAG(msg, NL80211_CMD_RENAME_WIPHY);
 
 	CHECK_CMD(inject_packet, INJECT);
 	CHECK_CMD(add_virtual_intf, ADD_VIRTUAL_INTERFACE);
@@ -879,6 +882,24 @@ static int nl80211_initiate_scan(struct 
 	return err;
 }
 
+static int nl80211_rename_wiphy(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	int result;
+
+	if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
+		return -EINVAL;
+
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev))
+		return PTR_ERR(rdev);
+
+	result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
+
+	cfg80211_put_dev(rdev);
+	return result;
+}
+
 static struct genl_ops nl80211_ops[] = {
 	{
 		.cmd = NL80211_CMD_GET_CMDLIST,
@@ -994,6 +1015,12 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 	},
+	{
+		.cmd = NL80211_CMD_RENAME_WIPHY,
+		.doit = nl80211_rename_wiphy,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
 };
 
 
@@ -1024,6 +1051,29 @@ void *nl80211msg_new(struct sk_buff **sk
 }
 EXPORT_SYMBOL_GPL(nl80211msg_new);
 
+/* notification functions */
+
+void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	hdr = nl80211msg_new(&msg, 0, 0, 0, NL80211_CMD_WIPHY_NEWNAME);
+	if (IS_ERR(hdr))
+		return;
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->idx);
+	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&rdev->wiphy));
+
+	genlmsg_end(msg, hdr);
+	genlmsg_multicast(msg, 0, NL80211_GROUP_CONFIG, GFP_KERNEL);
+
+	return;
+
+ nla_put_failure:
+	nlmsg_free(msg);
+}
+
 /* initialisation/exit functions */
 
 int nl80211_init(void)
--- wireless-dev.orig/net/wireless/core.c	2007-02-28 14:55:28.646381760 +0100
+++ wireless-dev/net/wireless/core.c	2007-02-28 14:55:34.826381760 +0100
@@ -12,6 +12,7 @@
 #include <linux/nl80211.h>
 #include <linux/debugfs.h>
 #include <linux/notifier.h>
+#include <linux/device.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
 #include <net/wireless.h>
@@ -20,6 +21,9 @@
 #include "wext.h"
 #include "sysfs.h"
 
+/* name for sysfs, must contain a single %d */
+#define PHY_NAME "phy%d"
+
 MODULE_AUTHOR("Johannes Berg");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("wireless configuration support");
@@ -137,6 +141,28 @@ void cfg80211_put_dev(struct cfg80211_re
 	mutex_unlock(&drv->mtx);
 }
 
+int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
+			char *newname)
+{
+	int idx, taken = -1, result;
+
+	/* prohibit calling the thing phy%d when %d is not its number */
+	sscanf(newname, PHY_NAME "%n", &idx, &taken);
+	if (taken == strlen(newname) && idx != rdev->idx)
+		return -EINVAL;
+
+	/* this will check for collisions */
+	result = device_rename(&rdev->wiphy.dev, newname);
+	if (!result)
+		return result;
+
+	/* TODO: do debugfs rename! */
+
+	nl80211_notify_dev_rename(rdev);
+
+	return 0;
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
@@ -163,7 +189,7 @@ struct wiphy *wiphy_new(struct cfg80211_
 
 	/* give it a proper name */
 	snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE,
-		 "wiphy%d", drv->idx);
+		 PHY_NAME, drv->idx);
 
 	/* now increase counter for the next time */
 	wiphy_counter++;
--- wireless-dev.orig/net/wireless/core.h	2007-02-28 14:55:28.646381760 +0100
+++ wireless-dev/net/wireless/core.h	2007-02-28 14:55:34.826381760 +0100
@@ -74,4 +74,7 @@ extern void cfg80211_put_dev(struct cfg8
 /* free object */
 extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
 
+extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
+			       char *newname);
+
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-dev.orig/net/wireless/nl80211.h	2007-02-28 14:55:22.526381760 +0100
+++ wireless-dev/net/wireless/nl80211.h	2007-02-28 14:55:34.826381760 +0100
@@ -1,9 +1,12 @@
 #ifndef __NET_WIRELESS_NL80211_H
 #define __NET_WIRELESS_NL80211_H
 
+#include "core.h"
+
 #ifdef CONFIG_NL80211
 extern int nl80211_init(void);
 extern void nl80211_exit(void);
+extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
 #else
 static inline int nl80211_init(void)
 {
@@ -12,6 +15,10 @@ static inline int nl80211_init(void)
 static inline void nl80211_exit(void)
 {
 }
+static inline void nl80211_notify_dev_rename(
+	struct cfg80211_registered_device *rdev)
+{
+}
 #endif /* CONFIG_NL80211 */
 
 #endif /* __NET_WIRELESS_NL80211_H */


-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux