diff options
-rw-r--r-- | include/linux/nl80211.h | 8 | ||||
-rw-r--r-- | include/net/cfg80211.h | 38 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 39 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 13 | ||||
-rw-r--r-- | net/mac80211/iface.c | 14 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 26 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 25 | ||||
-rw-r--r-- | net/wireless/Makefile | 2 | ||||
-rw-r--r-- | net/wireless/core.c | 15 | ||||
-rw-r--r-- | net/wireless/core.h | 13 | ||||
-rw-r--r-- | net/wireless/mesh.c | 140 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 137 | ||||
-rw-r--r-- | net/wireless/util.c | 1 |
14 files changed, 115 insertions, 359 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 410a06ea551b..9e541452d805 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -394,11 +394,6 @@ * * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. * - * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial - * mesh config parameters may be given. - * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the - * network is determined by the network interface. - * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -505,9 +500,6 @@ enum nl80211_commands { NL80211_CMD_FRAME_WAIT_CANCEL, - NL80211_CMD_JOIN_MESH, - NL80211_CMD_LEAVE_MESH, - /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 788c3989a9e8..902895dfbd49 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -258,9 +258,13 @@ struct ieee80211_supported_band { /** * struct vif_params - describes virtual interface parameters + * @mesh_id: mesh ID to use + * @mesh_id_len: length of the mesh ID * @use_4addr: use 4-address frames */ struct vif_params { + u8 *mesh_id; + int mesh_id_len; int use_4addr; }; @@ -611,11 +615,6 @@ struct bss_parameters { int ap_isolate; }; -/* - * struct mesh_config - 802.11s mesh configuration - * - * These parameters can be changed while the mesh is active. - */ struct mesh_config { /* Timeouts in ms */ /* Mesh plink management parameters */ @@ -639,18 +638,6 @@ struct mesh_config { }; /** - * struct mesh_setup - 802.11s mesh setup configuration - * @mesh_id: the mesh ID - * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes - * - * These parameters are fixed when the mesh is created. - */ -struct mesh_setup { - const u8 *mesh_id; - u8 mesh_id_len; -}; - -/** * struct ieee80211_txq_params - TX queue parameters * @queue: TX queue identifier (NL80211_TXQ_Q_*) * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled @@ -1091,7 +1078,7 @@ struct cfg80211_pmksa { * * @get_mesh_params: Put the current mesh parameters into *params * - * @update_mesh_params: Update mesh parameters on a running mesh. + * @set_mesh_params: Set mesh parameters. * The mask is a bitfield which tells us which parameters to * set, and which to leave alone. * @@ -1242,14 +1229,9 @@ struct cfg80211_ops { int (*get_mesh_params)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); - int (*update_mesh_params)(struct wiphy *wiphy, - struct net_device *dev, u32 mask, - const struct mesh_config *nconf); - int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, - const struct mesh_config *conf, - const struct mesh_setup *setup); - int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); - + int (*set_mesh_params)(struct wiphy *wiphy, + struct net_device *dev, + const struct mesh_config *nconf, u32 mask); int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); @@ -1665,8 +1647,6 @@ struct cfg80211_cached_keys; * @bssid: (private) Used by the internal configuration code * @ssid: (private) Used by the internal configuration code * @ssid_len: (private) Used by the internal configuration code - * @mesh_id_len: (private) Used by the internal configuration code - * @mesh_id_up_len: (private) Used by the internal configuration code * @wext: (private) Used by the internal wireless extensions compat code * @use_4addr: indicates 4addr mode is used on this interface, must be * set by driver (if supported) on add_interface BEFORE registering the @@ -1696,7 +1676,7 @@ struct wireless_dev { /* currently used for IBSS and SME - might be rearranged later */ u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len, mesh_id_len, mesh_id_up_len; + u8 ssid_len; enum { CFG80211_SME_IDLE, CFG80211_SME_CONNECTING, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 68329d713c02..d34c7c3dd762 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -60,6 +60,11 @@ static int ieee80211_change_iface(struct wiphy *wiphy, if (ret) return ret; + if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) + ieee80211_sdata_set_mesh_id(sdata, + params->mesh_id_len, + params->mesh_id); + if (type == NL80211_IFTYPE_AP_VLAN && params && params->use_4addr == 0) rcu_assign_pointer(sdata->u.vlan.sta, NULL); @@ -998,9 +1003,9 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) return (mask >> (parm-1)) & 0x1; } -static int ieee80211_update_mesh_params(struct wiphy *wiphy, - struct net_device *dev, u32 mask, - const struct mesh_config *nconf) +static int ieee80211_set_mesh_params(struct wiphy *wiphy, + struct net_device *dev, + const struct mesh_config *nconf, u32 mask) { struct mesh_config *conf; struct ieee80211_sub_if_data *sdata; @@ -1051,30 +1056,6 @@ static int ieee80211_update_mesh_params(struct wiphy *wiphy, return 0; } -static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, - const struct mesh_config *conf, - const struct mesh_setup *setup) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - - memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); - ifmsh->mesh_id_len = setup->mesh_id_len; - memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); - - ieee80211_start_mesh(sdata); - - return 0; -} - -static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - ieee80211_stop_mesh(sdata); - - return 0; -} #endif static int ieee80211_change_bss(struct wiphy *wiphy, @@ -1779,10 +1760,8 @@ struct cfg80211_ops mac80211_config_ops = { .change_mpath = ieee80211_change_mpath, .get_mpath = ieee80211_get_mpath, .dump_mpath = ieee80211_dump_mpath, - .update_mesh_params = ieee80211_update_mesh_params, + .set_mesh_params = ieee80211_set_mesh_params, .get_mesh_params = ieee80211_get_mesh_params, - .join_mesh = ieee80211_join_mesh, - .leave_mesh = ieee80211_leave_mesh, #endif .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 72499fe5fc36..e7c880725639 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -609,6 +609,19 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) return container_of(p, struct ieee80211_sub_if_data, vif); } +static inline void +ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, + u8 mesh_id_len, u8 *mesh_id) +{ +#ifdef CONFIG_MAC80211_MESH + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + ifmsh->mesh_id_len = mesh_id_len; + memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); +#else + WARN_ON(1); +#endif +} + enum sdata_queue_type { IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, IEEE80211_SDATA_QUEUE_AGG_START = 1, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index f0f11bb794af..96e27f1e79fb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -268,7 +268,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) goto err_stop; } - if (sdata->vif.type == NL80211_IFTYPE_AP) { + if (ieee80211_vif_is_mesh(&sdata->vif)) { + ieee80211_start_mesh(sdata); + } else if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll++; local->fif_probe_req++; @@ -493,6 +495,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_adjust_monitor_flags(sdata, -1); ieee80211_configure_filter(local); break; + case NL80211_IFTYPE_MESH_POINT: + if (ieee80211_vif_is_mesh(&sdata->vif)) + ieee80211_stop_mesh(sdata); + /* fall through */ default: flush_work(&sdata->work); /* @@ -1182,6 +1188,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, if (ret) goto fail; + if (ieee80211_vif_is_mesh(&sdata->vif) && + params && params->mesh_id_len) + ieee80211_sdata_set_mesh_id(sdata, + params->mesh_id_len, + params->mesh_id); + mutex_lock(&local->iflist_mtx); list_add_tail_rcu(&sdata->list, &local->interfaces); mutex_unlock(&local->iflist_mtx); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2de69766c6aa..107a0cbe52ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -246,8 +246,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, !!sdata->u.ibss.presp; break; case NL80211_IFTYPE_MESH_POINT: - sdata->vif.bss_conf.enable_beacon = - !!sdata->u.mesh.mesh_id_len; + sdata->vif.bss_conf.enable_beacon = true; break; default: /* not reached */ diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 63e1188d5062..0d3234875ac5 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -530,11 +530,6 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; - struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - - ifmsh->mesh_id_len = 0; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - sta_info_flush(local, NULL); del_timer_sync(&sdata->u.mesh.housekeeping_timer); del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); @@ -679,6 +674,27 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ieee80211_mesh_housekeeping_timer, (unsigned long) sdata); + ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; + ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; + ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; + ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; + ifmsh->mshcfg.dot11MeshTTL = MESH_TTL; + ifmsh->mshcfg.element_ttl = MESH_DEFAULT_ELEMENT_TTL; + ifmsh->mshcfg.auto_open_plinks = true; + ifmsh->mshcfg.dot11MeshMaxPeerLinks = + MESH_MAX_ESTAB_PLINKS; + ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout = + MESH_PATH_TIMEOUT; + ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval = + MESH_PREQ_MIN_INT; + ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = + MESH_DIAM_TRAVERSAL_TIME; + ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries = + MESH_MAX_PREQ_RETRIES; + ifmsh->mshcfg.path_refresh_time = + MESH_PATH_REFRESH_TIME; + ifmsh->mshcfg.min_discovery_timeout = + MESH_MIN_DISCOVERY_TIMEOUT; ifmsh->accepting_plinks = true; ifmsh->preq_id = 0; ifmsh->sn = 0; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 039d7fa0af74..182942eeac4d 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -175,10 +175,33 @@ struct mesh_rmc { */ #define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2) +/* Default values, timeouts in ms */ +#define MESH_TTL 31 +#define MESH_MAX_RETR 3 +#define MESH_RET_T 100 +#define MESH_CONF_T 100 +#define MESH_HOLD_T 100 + +#define MESH_PATH_TIMEOUT 5000 +/* Minimum interval between two consecutive PREQs originated by the same + * interface + */ +#define MESH_PREQ_MIN_INT 10 +#define MESH_DIAM_TRAVERSAL_TIME 50 +/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before + * timing out. This way it will remain ACTIVE and no data frames will be + * unnecesarily held in the pending queue. + */ +#define MESH_PATH_REFRESH_TIME 1000 +#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ +#define MESH_MAX_PREQ_RETRIES 4 #define MESH_PATH_EXPIRE (600 * HZ) +/* Default maximum number of established plinks per interface */ +#define MESH_MAX_ESTAB_PLINKS 32 + /* Default maximum number of plinks per interface */ #define MESH_MAX_PLINKS 256 @@ -193,6 +216,8 @@ struct mesh_rmc { #define PERR_RCODE_NO_ROUTE 12 #define PERR_RCODE_DEST_UNREACH 13 +#define MESH_DEFAULT_ELEMENT_TTL 31 + /* Public interfaces */ /* Various */ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 55a28ab21db9..e77e508126fa 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/net/wireless/core.c b/net/wireless/core.c index 79772fcc37bc..630bcf0a2f04 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -332,7 +332,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf); WARN_ON(ops->add_station && !ops->del_station); WARN_ON(ops->add_mpath && !ops->del_mpath); - WARN_ON(ops->join_mesh && !ops->leave_mesh); alloc_size = sizeof(*rdev) + sizeof_priv; @@ -753,9 +752,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, cfg80211_mlme_down(rdev, dev); wdev_unlock(wdev); break; - case NL80211_IFTYPE_MESH_POINT: - cfg80211_leave_mesh(rdev, dev); - break; default: break; } @@ -779,27 +775,20 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, } cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); +#ifdef CONFIG_CFG80211_WEXT wdev_lock(wdev); switch (wdev->iftype) { -#ifdef CONFIG_CFG80211_WEXT case NL80211_IFTYPE_ADHOC: cfg80211_ibss_wext_join(rdev, wdev); break; case NL80211_IFTYPE_STATION: cfg80211_mgd_wext_connect(rdev, wdev); break; -#endif - case NL80211_IFTYPE_MESH_POINT: - /* backward compat code ... */ - if (wdev->mesh_id_up_len) - __cfg80211_join_mesh(rdev, dev, wdev->ssid, - wdev->mesh_id_up_len, - &default_mesh_config); - break; default: break; } wdev_unlock(wdev); +#endif rdev->opencount++; mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); diff --git a/net/wireless/core.h b/net/wireless/core.h index 743203bb61ac..ee80ad8dc655 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -285,19 +285,6 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); -/* mesh */ -extern const struct mesh_config default_mesh_config; -int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, - const struct mesh_config *conf); -int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, - const struct mesh_config *conf); -int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev); - /* MLME */ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, struct net_device *dev, diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c deleted file mode 100644 index e0b9747fe50a..000000000000 --- a/net/wireless/mesh.c +++ /dev/null @@ -1,140 +0,0 @@ -#include <linux/ieee80211.h> -#include <net/cfg80211.h> -#include "core.h" - -/* Default values, timeouts in ms */ -#define MESH_TTL 31 -#define MESH_DEFAULT_ELEMENT_TTL 31 -#define MESH_MAX_RETR 3 -#define MESH_RET_T 100 -#define MESH_CONF_T 100 -#define MESH_HOLD_T 100 - -#define MESH_PATH_TIMEOUT 5000 - -/* - * Minimum interval between two consecutive PREQs originated by the same - * interface - */ -#define MESH_PREQ_MIN_INT 10 -#define MESH_DIAM_TRAVERSAL_TIME 50 - -/* - * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds - * before timing out. This way it will remain ACTIVE and no data frames - * will be unnecessarily held in the pending queue. - */ -#define MESH_PATH_REFRESH_TIME 1000 -#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) - -/* Default maximum number of established plinks per interface */ -#define MESH_MAX_ESTAB_PLINKS 32 - -#define MESH_MAX_PREQ_RETRIES 4 - - -const struct mesh_config default_mesh_config = { - .dot11MeshRetryTimeout = MESH_RET_T, - .dot11MeshConfirmTimeout = MESH_CONF_T, - .dot11MeshHoldingTimeout = MESH_HOLD_T, - .dot11MeshMaxRetries = MESH_MAX_RETR, - .dot11MeshTTL = MESH_TTL, - .element_ttl = MESH_DEFAULT_ELEMENT_TTL, - .auto_open_plinks = true, - .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, - .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, - .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, - .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, - .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, - .path_refresh_time = MESH_PATH_REFRESH_TIME, - .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, -}; - - -int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, - const struct mesh_config *conf) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct mesh_setup setup = { - .mesh_id = mesh_id, - .mesh_id_len = mesh_id_len, - }; - int err; - - BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); - - ASSERT_WDEV_LOCK(wdev); - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) - return -EOPNOTSUPP; - - if (wdev->mesh_id_len) - return -EALREADY; - - if (!mesh_id_len) - return -EINVAL; - - if (!rdev->ops->join_mesh) - return -EOPNOTSUPP; - - err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); - if (!err) { - memcpy(wdev->ssid, mesh_id, mesh_id_len); - wdev->mesh_id_len = mesh_id_len; - } - - return err; -} - -int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev, - const u8 *mesh_id, u8 mesh_id_len, - const struct mesh_config *conf) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - wdev_lock(wdev); - err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); - wdev_unlock(wdev); - - return err; -} - -static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - ASSERT_WDEV_LOCK(wdev); - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) - return -EOPNOTSUPP; - - if (!rdev->ops->leave_mesh) - return -EOPNOTSUPP; - - if (!wdev->mesh_id_len) - return -ENOTCONN; - - err = rdev->ops->leave_mesh(&rdev->wiphy, dev); - if (!err) - wdev->mesh_id_len = 0; - return err; -} - -int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - wdev_lock(wdev); - err = __cfg80211_leave_mesh(rdev, dev); - wdev_unlock(wdev); - - return err; -} diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 56508d40c740..c8d4d53fc450 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -661,14 +661,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(add_beacon, NEW_BEACON); CMD(add_station, NEW_STATION); CMD(add_mpath, NEW_MPATH); - CMD(update_mesh_params, SET_MESH_PARAMS); + CMD(set_mesh_params, SET_MESH_PARAMS); CMD(change_bss, SET_BSS); CMD(auth, AUTHENTICATE); CMD(assoc, ASSOCIATE); CMD(deauth, DEAUTHENTICATE); CMD(disassoc, DISASSOCIATE); CMD(join_ibss, JOIN_IBSS); - CMD(join_mesh, JOIN_MESH); CMD(set_pmksa, SET_PMKSA); CMD(del_pmksa, DEL_PMKSA); CMD(flush_pmksa, FLUSH_PMKSA); @@ -1325,21 +1324,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_MESH_ID]) { - struct wireless_dev *wdev = dev->ieee80211_ptr; - if (ntype != NL80211_IFTYPE_MESH_POINT) return -EINVAL; - if (netif_running(dev)) - return -EBUSY; - - wdev_lock(wdev); - BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != - IEEE80211_MAX_MESH_ID_LEN); - wdev->mesh_id_up_len = - nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - wdev->mesh_id_up_len); - wdev_unlock(wdev); + params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); + params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); + change = true; } if (info->attrs[NL80211_ATTR_4ADDR]) { @@ -1399,6 +1388,12 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) !(rdev->wiphy.interface_modes & (1 << type))) return -EOPNOTSUPP; + if (type == NL80211_IFTYPE_MESH_POINT && + info->attrs[NL80211_ATTR_MESH_ID]) { + params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); + params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); + } + if (info->attrs[NL80211_ATTR_4ADDR]) { params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); @@ -1415,20 +1410,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(dev)) return PTR_ERR(dev); - if (type == NL80211_IFTYPE_MESH_POINT && - info->attrs[NL80211_ATTR_MESH_ID]) { - struct wireless_dev *wdev = dev->ieee80211_ptr; - - wdev_lock(wdev); - BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != - IEEE80211_MAX_MESH_ID_LEN); - wdev->mesh_id_up_len = - nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - wdev->mesh_id_up_len); - wdev_unlock(wdev); - } - return 0; } @@ -2562,32 +2543,21 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) } static int nl80211_get_mesh_params(struct sk_buff *skb, - struct genl_info *info) + struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; struct mesh_config cur_params; - int err = 0; + int err; + struct net_device *dev = info->user_ptr[1]; void *hdr; struct nlattr *pinfoattr; struct sk_buff *msg; - if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) - return -EOPNOTSUPP; - if (!rdev->ops->get_mesh_params) return -EOPNOTSUPP; - wdev_lock(wdev); - /* If not connected, get default parameters */ - if (!wdev->mesh_id_len) - memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); - else - err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, - &cur_params); - wdev_unlock(wdev); - + /* Get the mesh params */ + err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); if (err) return err; @@ -2735,37 +2705,23 @@ do {\ #undef FILL_IN_MESH_PARAM_IF_SET } -static int nl80211_update_mesh_params(struct sk_buff *skb, - struct genl_info *info) +static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; struct mesh_config cfg; u32 mask; int err; - if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) - return -EOPNOTSUPP; - - if (!rdev->ops->update_mesh_params) + if (!rdev->ops->set_mesh_params) return -EOPNOTSUPP; err = nl80211_parse_mesh_params(info, &cfg, &mask); if (err) return err; - wdev_lock(wdev); - if (!wdev->mesh_id_len) - err = -ENOLINK; - - if (!err) - err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, - mask, &cfg); - - wdev_unlock(wdev); - - return err; + /* Apply changes */ + return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); } static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) @@ -4549,41 +4505,6 @@ out: return err; } -static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - struct mesh_config cfg; - int err; - - /* start with default */ - memcpy(&cfg, &default_mesh_config, sizeof(cfg)); - - if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { - /* and parse parameters if given */ - err = nl80211_parse_mesh_params(info, &cfg, NULL); - if (err) - return err; - } - - if (!info->attrs[NL80211_ATTR_MESH_ID] || - !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) - return -EINVAL; - - return cfg80211_join_mesh(rdev, dev, - nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - nla_len(info->attrs[NL80211_ATTR_MESH_ID]), - &cfg); -} - -static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - - return cfg80211_leave_mesh(rdev, dev); -} - #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -4848,10 +4769,10 @@ static struct genl_ops nl80211_ops[] = { }, { .cmd = NL80211_CMD_SET_MESH_PARAMS, - .doit = nl80211_update_mesh_params, + .doit = nl80211_set_mesh_params, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -5066,22 +4987,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, - { - .cmd = NL80211_CMD_JOIN_MESH, - .doit = nl80211_join_mesh, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NEED_RTNL, - }, - { - .cmd = NL80211_CMD_LEAVE_MESH, - .doit = nl80211_leave_mesh, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NEED_RTNL, - }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { diff --git a/net/wireless/util.c b/net/wireless/util.c index 4de624ca4c63..fee020b15a4e 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -792,7 +792,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (ntype != otype) { dev->ieee80211_ptr->use_4addr = false; - dev->ieee80211_ptr->mesh_id_up_len = 0; switch (otype) { case NL80211_IFTYPE_ADHOC: |