All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org, Luis Carlos Cobo <luisca@cozybit.com>
Subject: [PATCH 14/18] mac80211: mesh path and mesh peer configuration
Date: Sat, 23 Feb 2008 15:17:17 +0100	[thread overview]
Message-ID: <20080223142016.018195000@sipsolutions.net> (raw)
In-Reply-To: 20080223141703.194775000@sipsolutions.net

From: Luis Carlos Cobo <luisca@cozybit.com>

This adds code to allow adding mesh interfaces and configuring
mesh peers etc. Also, it adds code for station dumping.

Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/cfg.c |  269 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 259 insertions(+), 10 deletions(-)

--- everything.orig/net/mac80211/cfg.c	2008-02-23 14:42:23.000000000 +0100
+++ everything/net/mac80211/cfg.c	2008-02-23 14:42:40.000000000 +0100
@@ -15,6 +15,11 @@
 #include "ieee80211_i.h"
 #include "cfg.h"
 #include "ieee80211_rate.h"
+#ifdef CONFIG_MAC80211_MESH
+#include "mesh.h"
+#endif
+
+#define DEFAULT_RATES 0
 
 static enum ieee80211_if_types
 nl80211_type_to_mac80211_type(enum nl80211_iftype type)
@@ -28,6 +33,10 @@ nl80211_type_to_mac80211_type(enum nl802
 		return IEEE80211_IF_TYPE_STA;
 	case NL80211_IFTYPE_MONITOR:
 		return IEEE80211_IF_TYPE_MNTR;
+#ifdef CONFIG_MAC80211_MESH
+	case NL80211_IFTYPE_MESH_POINT:
+		return IEEE80211_IF_TYPE_MESH_POINT;
+#endif
 	default:
 		return IEEE80211_IF_TYPE_INVALID;
 	}
@@ -110,6 +119,15 @@ static int ieee80211_change_iface(struct
 	ieee80211_if_reinit(dev);
 	ieee80211_if_set_type(dev, itype);
 
+#ifdef CONFIG_MAC80211_MESH
+	if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
+	    params->mesh_id_len) {
+		sdata->u.sta.mesh_id_len = params->mesh_id_len;
+		memcpy(sdata->u.sta.mesh_id, params->mesh_id,
+		       params->mesh_id_len);
+	}
+#endif
+
 	if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags)
 		return 0;
 
@@ -286,6 +304,51 @@ static int ieee80211_config_default_key(
 	return 0;
 }
 
+static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
+{
+#ifdef CONFIG_MAC80211_MESH
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+#endif
+
+	sinfo->filled = STATION_INFO_INACTIVE_TIME |
+			STATION_INFO_RX_BYTES |
+			STATION_INFO_TX_BYTES;
+
+	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
+	sinfo->rx_bytes = sta->rx_bytes;
+	sinfo->tx_bytes = sta->tx_bytes;
+
+#ifdef CONFIG_MAC80211_MESH
+	if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) {
+		sinfo->filled |= STATION_INFO_LLID |
+				 STATION_INFO_PLID |
+				 STATION_INFO_PLINK_STATE;
+
+		sinfo->llid = le16_to_cpu(sta->llid);
+		sinfo->plid = le16_to_cpu(sta->plid);
+		sinfo->plink_state = sta->plink_state;
+	}
+#endif
+}
+
+
+static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
+				 int idx, u8 *mac, struct station_info *sinfo)
+{
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct sta_info *sta;
+
+	sta = sta_info_get_by_idx(local, idx, dev);
+	if (!sta)
+		return -ENOENT;
+
+	memcpy(mac, sta->addr, ETH_ALEN);
+	sta_set_sinfo(sta, sinfo);
+	sta_info_put(sta);
+
+	return 0;
+}
+
 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 				 u8 *mac, struct station_info *sinfo)
 {
@@ -297,15 +360,7 @@ static int ieee80211_get_station(struct 
 		return -ENOENT;
 
 	/* XXX: verify sta->dev == dev */
-
-	sinfo->filled = STATION_INFO_INACTIVE_TIME |
-			STATION_INFO_RX_BYTES |
-			STATION_INFO_TX_BYTES;
-
-	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
-	sinfo->rx_bytes = sta->rx_bytes;
-	sinfo->tx_bytes = sta->tx_bytes;
-
+	sta_set_sinfo(sta, sinfo);
 	sta_info_put(sta);
 
 	return 0;
@@ -514,6 +569,9 @@ static void sta_apply_parameters(struct 
 	u32 rates;
 	int i, j;
 	struct ieee80211_supported_band *sband;
+#ifdef CONFIG_MAC80211_MESH
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+#endif
 
 	if (params->station_flags & STATION_FLAG_CHANGED) {
 		sta->flags &= ~WLAN_STA_AUTHORIZED;
@@ -551,6 +609,19 @@ static void sta_apply_parameters(struct 
 		}
 		sta->supp_rates[local->oper_channel->band] = rates;
 	}
+
+#ifdef CONFIG_MAC80211_MESH
+	if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
+	    params->plink_action)
+		switch (params->plink_action) {
+		case PLINK_ACTION_OPEN:
+			mesh_plink_open(sta);
+			break;
+		case PLINK_ACTION_BLOCK:
+			mesh_plink_block(sta);
+			break;
+		}
+#endif
 }
 
 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
@@ -573,7 +644,13 @@ static int ieee80211_add_station(struct 
 	} else
 		sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	sta = sta_info_add(local, dev, mac, GFP_KERNEL);
+#ifdef CONFIG_MAC80211_MESH
+	if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT)
+		sta = mesh_plink_add(mac, DEFAULT_RATES, dev);
+	else
+#endif
+		sta = sta_info_add(local, dev, mac, GFP_KERNEL);
+
 	if (IS_ERR(sta))
 		return PTR_ERR(sta);
 
@@ -645,6 +722,170 @@ static int ieee80211_change_station(stru
 	return 0;
 }
 
+#ifdef CONFIG_MAC80211_MESH
+static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
+				 u8 *dst, u8 *next_hop)
+{
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct mesh_path *mpath;
+	struct sta_info *sta;
+	int err;
+
+	if (!netif_running(dev))
+		return -ENETDOWN;
+
+	if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
+		return -ENOTSUPP;
+
+	sta = sta_info_get(local, next_hop);
+	if (!sta)
+		return -ENOENT;
+
+	err = mesh_path_add(dst, dev);
+	if (err)
+		return err;
+
+	rcu_read_lock();
+	mpath = mesh_path_lookup(dst, dev);
+	if (!mpath) {
+		rcu_read_unlock();
+		sta_info_put(sta);
+		return -ENXIO;
+	}
+	mesh_path_fix_nexthop(mpath, sta);
+	sta_info_put(sta);
+	rcu_read_unlock();
+	return 0;
+}
+
+static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
+				 u8 *dst)
+{
+	if (dst)
+		return mesh_path_del(dst, dev);
+
+	mesh_path_flush(dev);
+	return 0;
+}
+
+static int ieee80211_change_mpath(struct wiphy *wiphy,
+				    struct net_device *dev,
+				    u8 *dst, u8 *next_hop)
+{
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct mesh_path *mpath;
+	struct sta_info *sta;
+
+	if (!netif_running(dev))
+		return -ENETDOWN;
+
+	if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
+		return -ENOTSUPP;
+
+	sta = sta_info_get(local, next_hop);
+	if (!sta)
+		return -ENOENT;
+
+	rcu_read_lock();
+	mpath = mesh_path_lookup(dst, dev);
+	if (!mpath) {
+		rcu_read_unlock();
+		sta_info_put(sta);
+		return -ENOENT;
+	}
+
+	mesh_path_fix_nexthop(mpath, sta);
+	sta_info_put(sta);
+	rcu_read_unlock();
+	return 0;
+}
+
+static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
+			    struct mpath_info *pinfo)
+{
+	if (mpath->next_hop)
+		memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN);
+	else
+		memset(next_hop, 0, ETH_ALEN);
+
+	pinfo->filled = MPATH_INFO_FRAME_QLEN |
+			MPATH_INFO_DSN |
+			MPATH_INFO_METRIC |
+			MPATH_INFO_EXPTIME |
+			MPATH_INFO_DISCOVERY_TIMEOUT |
+			MPATH_INFO_DISCOVERY_RETRIES |
+			MPATH_INFO_FLAGS;
+
+	pinfo->frame_qlen = mpath->frame_queue.qlen;
+	pinfo->dsn = mpath->dsn;
+	pinfo->metric = mpath->metric;
+	if (time_before(jiffies, mpath->exp_time))
+		pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
+	pinfo->discovery_timeout =
+			jiffies_to_msecs(mpath->discovery_timeout);
+	pinfo->discovery_retries = mpath->discovery_retries;
+	pinfo->flags = 0;
+	if (mpath->flags & MESH_PATH_ACTIVE)
+		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
+	if (mpath->flags & MESH_PATH_RESOLVING)
+		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
+	if (mpath->flags & MESH_PATH_DSN_VALID)
+		pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID;
+	if (mpath->flags & MESH_PATH_FIXED)
+		pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
+	if (mpath->flags & MESH_PATH_RESOLVING)
+		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
+
+	pinfo->flags = mpath->flags;
+}
+
+static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
+			       u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
+
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct mesh_path *mpath;
+
+	if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
+		return -ENOTSUPP;
+
+	rcu_read_lock();
+	mpath = mesh_path_lookup(dst, dev);
+	if (!mpath) {
+		rcu_read_unlock();
+		return -ENOENT;
+	}
+	memcpy(dst, mpath->dst, ETH_ALEN);
+	mpath_set_pinfo(mpath, next_hop, pinfo);
+	rcu_read_unlock();
+	return 0;
+}
+
+static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
+				 int idx, u8 *dst, u8 *next_hop,
+				 struct mpath_info *pinfo)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct mesh_path *mpath;
+
+	if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
+		return -ENOTSUPP;
+
+	rcu_read_lock();
+	mpath = mesh_path_lookup_by_idx(idx, dev);
+	if (!mpath) {
+		rcu_read_unlock();
+		return -ENOENT;
+	}
+	memcpy(dst, mpath->dst, ETH_ALEN);
+	mpath_set_pinfo(mpath, next_hop, pinfo);
+	rcu_read_unlock();
+	return 0;
+}
+#endif
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -660,4 +901,12 @@ struct cfg80211_ops mac80211_config_ops 
 	.del_station = ieee80211_del_station,
 	.change_station = ieee80211_change_station,
 	.get_station = ieee80211_get_station,
+	.dump_station = ieee80211_dump_station,
+#ifdef CONFIG_MAC80211_MESH
+	.add_mpath = ieee80211_add_mpath,
+	.del_mpath = ieee80211_del_mpath,
+	.change_mpath = ieee80211_change_mpath,
+	.get_mpath = ieee80211_get_mpath,
+	.dump_mpath = ieee80211_dump_mpath,
+#endif
 };

-- 


  parent reply	other threads:[~2008-02-23 14:21 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-23 14:17 [PATCH 00/18] mac80211 802.11s networking code Johannes Berg
2008-02-23 14:17 ` [PATCH 01/18] wireless: various definitions for mesh networking Johannes Berg
2008-02-23 14:17 ` [PATCH 02/18] WEXT: add mesh interface type Johannes Berg
2008-02-23 14:17 ` [PATCH 03/18] nl80211/cfg80211: support for mesh, sta dumping Johannes Berg
2008-02-23 14:17 ` [PATCH 04/18] mac80211: add mesh interface type Johannes Berg
2008-02-23 14:17 ` [PATCH 05/18] mac80211: mesh function and data structures definitions Johannes Berg
2008-02-23 14:17 ` [PATCH 06/18] mac80211: support functions for mesh Johannes Berg
2008-02-23 14:17 ` [PATCH 07/18] mac80211: support for mesh interfaces in mac80211 data path Johannes Berg
2008-02-23 14:17 ` [PATCH 08/18] mac80211: mesh data structures and first mesh changes Johannes Berg
2008-02-23 14:17 ` [PATCH 09/18] mac80211: mesh changes to the MLME Johannes Berg
2008-02-23 14:17 ` [PATCH 10/18] mac80211: mesh peer link implementation Johannes Berg
2008-02-23 14:17 ` [PATCH 11/18] mac80211: mesh path table implementation Johannes Berg
2008-02-23 14:17 ` [PATCH 12/18] mac80211: code for on-demand Hybrid Wireless Mesh Protocol Johannes Berg
2008-02-23 14:17 ` [PATCH 13/18] mac80211: mesh statistics and config through debugfs Johannes Berg
2008-03-28  6:16   ` Andrew Morton
2008-03-31 21:55     ` Luis Carlos Cobo
2008-03-28  6:38   ` Andrew Morton
2008-03-31 21:48     ` Luis Carlos Cobo
2008-02-23 14:17 ` Johannes Berg [this message]
2008-02-23 14:17 ` [PATCH 15/18] mac80211: complete the mesh (interface handling) code Johannes Berg
2008-02-23 14:17 ` [PATCH 16/18] mac80211: clean up mesh code Johannes Berg
2008-02-23 14:17 ` [PATCH 17/18] mac80211: mesh hwmp locking fixes Johannes Berg
2008-02-25 19:09   ` Luis Carlos Cobo
2008-02-25 19:09     ` Johannes Berg
2008-02-25 19:41       ` Luis Carlos Cobo
2008-02-23 14:17 ` [PATCH 18/18] mac80211: enable mesh in Kconfig Johannes Berg
2008-02-25 20:58   ` Luis Carlos Cobo
2008-02-25 21:24     ` Johannes Berg
2008-02-25 23:27       ` Luis Carlos Cobo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080223142016.018195000@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=luisca@cozybit.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.