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
};
--
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).