summary refs log tree commit diff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/nm-linux-platform.c10
-rw-r--r--src/platform/wifi/nm-wifi-utils-nl80211.c67
2 files changed, 68 insertions, 9 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index e2e1e581..d222527d 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -2879,19 +2879,11 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
 	    && obj->_link.ext_data == NULL) {
 		switch (obj->link.type) {
 		case NM_LINK_TYPE_WIFI:
+		case NM_LINK_TYPE_OLPC_MESH:
 			obj->_link.ext_data = (GObject *) nm_wifi_utils_new (ifi->ifi_index,
 			                                                     _genl_sock (NM_LINUX_PLATFORM (platform)),
 			                                                     TRUE);
 			break;
-		case NM_LINK_TYPE_OLPC_MESH:
-#if HAVE_WEXT
-			/* The kernel driver now uses nl80211, but we force use of WEXT because
-			 * the cfg80211 interactions are not quite ready to support access to
-			 * mesh control through nl80211 just yet.
-			 */
-			obj->_link.ext_data = (GObject *) nm_wifi_utils_wext_new (ifi->ifi_index, FALSE);
-#endif
-			break;
 		case NM_LINK_TYPE_WPAN:
 			obj->_link.ext_data = (GObject *) nm_wpan_utils_new (ifi->ifi_index,
 			                                                     _genl_sock (NM_LINUX_PLATFORM (platform)),
diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/nm-wifi-utils-nl80211.c
index 84a93f4f..36901f83 100644
--- a/src/platform/wifi/nm-wifi-utils-nl80211.c
+++ b/src/platform/wifi/nm-wifi-utils-nl80211.c
@@ -706,6 +706,7 @@ struct nl80211_device_info {
 	int phy;
 	guint32 *freqs;
 	int num_freqs;
+	guint32 freq;
 	guint32 caps;
 	gboolean can_scan;
 	gboolean can_scan_ssid;
@@ -767,6 +768,11 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 
 	info->phy = nla_get_u32 (tb[NL80211_ATTR_WIPHY]);
 
+	if (tb[NL80211_ATTR_WIPHY_FREQ])
+		info->freq = nla_get_u32 (tb[NL80211_ATTR_WIPHY_FREQ]);
+	else
+		info->freq = 0;
+
 	if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) {
 		info->can_scan_ssid =
 			nla_get_u8 (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0;
@@ -912,6 +918,64 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 	return NL_SKIP;
 }
 
+static guint32
+wifi_nl80211_get_mesh_channel (NMWifiUtils *data)
+{
+	NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
+	nm_auto_nlmsg struct nl_msg *msg = NULL;
+	struct nl80211_device_info device_info = { .self = self };
+	int i;
+
+	msg = nl80211_alloc_msg (self, NL80211_CMD_GET_WIPHY, 0);
+
+	if (nl80211_send_and_recv (self, msg, nl80211_wiphy_info_handler,
+	                           &device_info) < 0) {
+		_LOGW ("NL80211_CMD_GET_WIPHY request failed");
+		return 0;
+	}
+
+	for (i = 0; i < self->num_freqs; i++) {
+		if (device_info.freq == self->freqs[i])
+			return i + 1;
+	}
+	return 0;
+}
+
+static gboolean
+wifi_nl80211_set_mesh_channel (NMWifiUtils *data, guint32 channel)
+{
+	NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
+	nm_auto_nlmsg struct nl_msg *msg = NULL;
+	int err;
+
+	if (channel > self->num_freqs)
+		return FALSE;
+
+	msg = nl80211_alloc_msg (self, NL80211_CMD_SET_WIPHY, 0);
+	NLA_PUT_U32 (msg, NL80211_ATTR_WIPHY_FREQ, self->freqs[channel - 1]);
+	err = nl80211_send_and_recv (self, msg, NULL, NULL);
+	return err >= 0;
+
+nla_put_failure:
+	g_return_val_if_reached (FALSE);
+}
+
+static gboolean
+wifi_nl80211_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len)
+{
+	NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
+	nm_auto_nlmsg struct nl_msg *msg = NULL;
+	int err;
+
+	msg = nl80211_alloc_msg (self, NL80211_CMD_SET_INTERFACE, 0);
+	NLA_PUT (msg, NL80211_ATTR_MESH_ID, len, ssid);
+	err = nl80211_send_and_recv (self, msg, NULL, NULL);
+	return err >= 0;
+
+nla_put_failure:
+	g_return_val_if_reached (FALSE);
+}
+
 static void
 nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self)
 {
@@ -936,6 +1000,9 @@ nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass)
 	wifi_utils_class->get_rate = wifi_nl80211_get_rate;
 	wifi_utils_class->get_qual = wifi_nl80211_get_qual;
 	wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running;
+	wifi_utils_class->get_mesh_channel = wifi_nl80211_get_mesh_channel;
+	wifi_utils_class->set_mesh_channel = wifi_nl80211_set_mesh_channel;
+	wifi_utils_class->set_mesh_ssid = wifi_nl80211_set_mesh_ssid;
 }
 
 NMWifiUtils *