Skip to content

Commit 29cbe68

Browse files
jmberg-intellinvjw
authored andcommitted
cfg80211/mac80211: add mesh join/leave commands
Instead of tying mesh activity to interface up, add join and leave commands for mesh. Since we must be backward compatible, let cfg80211 handle joining a mesh if a mesh ID was pre-configured when the device goes up. Note that this therefore must modify mac80211 as well since mac80211 needs to lose the logic to start the mesh on interface up. We now allow querying mesh parameters before the mesh is connected, which simply returns defaults. Setting them (internally renamed to "update") is only allowed while connected. Specify them with the new mesh join command instead where needed. In mac80211, beaconing must now also follow the mesh enabled/not enabled state, which is done by testing the mesh ID. Signed-off-by: Javier Cardona <[email protected]> Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent bd90fdc commit 29cbe68

File tree

14 files changed

+359
-115
lines changed

14 files changed

+359
-115
lines changed

include/linux/nl80211.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@
394394
*
395395
* @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
396396
*
397+
* @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial
398+
* mesh config parameters may be given.
399+
* @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
400+
* network is determined by the network interface.
401+
*
397402
* @NL80211_CMD_MAX: highest used command number
398403
* @__NL80211_CMD_AFTER_LAST: internal use
399404
*/
@@ -500,6 +505,9 @@ enum nl80211_commands {
500505

501506
NL80211_CMD_FRAME_WAIT_CANCEL,
502507

508+
NL80211_CMD_JOIN_MESH,
509+
NL80211_CMD_LEAVE_MESH,
510+
503511
/* add new commands above here */
504512

505513
/* used to define NL80211_CMD_MAX below */

include/net/cfg80211.h

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,9 @@ struct ieee80211_supported_band {
258258

259259
/**
260260
* struct vif_params - describes virtual interface parameters
261-
* @mesh_id: mesh ID to use
262-
* @mesh_id_len: length of the mesh ID
263261
* @use_4addr: use 4-address frames
264262
*/
265263
struct vif_params {
266-
u8 *mesh_id;
267-
int mesh_id_len;
268264
int use_4addr;
269265
};
270266

@@ -615,6 +611,11 @@ struct bss_parameters {
615611
int ap_isolate;
616612
};
617613

614+
/*
615+
* struct mesh_config - 802.11s mesh configuration
616+
*
617+
* These parameters can be changed while the mesh is active.
618+
*/
618619
struct mesh_config {
619620
/* Timeouts in ms */
620621
/* Mesh plink management parameters */
@@ -637,6 +638,18 @@ struct mesh_config {
637638
u8 dot11MeshHWMPRootMode;
638639
};
639640

641+
/**
642+
* struct mesh_setup - 802.11s mesh setup configuration
643+
* @mesh_id: the mesh ID
644+
* @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
645+
*
646+
* These parameters are fixed when the mesh is created.
647+
*/
648+
struct mesh_setup {
649+
const u8 *mesh_id;
650+
u8 mesh_id_len;
651+
};
652+
640653
/**
641654
* struct ieee80211_txq_params - TX queue parameters
642655
* @queue: TX queue identifier (NL80211_TXQ_Q_*)
@@ -1078,7 +1091,7 @@ struct cfg80211_pmksa {
10781091
*
10791092
* @get_mesh_params: Put the current mesh parameters into *params
10801093
*
1081-
* @set_mesh_params: Set mesh parameters.
1094+
* @update_mesh_params: Update mesh parameters on a running mesh.
10821095
* The mask is a bitfield which tells us which parameters to
10831096
* set, and which to leave alone.
10841097
*
@@ -1229,9 +1242,14 @@ struct cfg80211_ops {
12291242
int (*get_mesh_params)(struct wiphy *wiphy,
12301243
struct net_device *dev,
12311244
struct mesh_config *conf);
1232-
int (*set_mesh_params)(struct wiphy *wiphy,
1233-
struct net_device *dev,
1234-
const struct mesh_config *nconf, u32 mask);
1245+
int (*update_mesh_params)(struct wiphy *wiphy,
1246+
struct net_device *dev, u32 mask,
1247+
const struct mesh_config *nconf);
1248+
int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
1249+
const struct mesh_config *conf,
1250+
const struct mesh_setup *setup);
1251+
int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev);
1252+
12351253
int (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
12361254
struct bss_parameters *params);
12371255

@@ -1647,6 +1665,8 @@ struct cfg80211_cached_keys;
16471665
* @bssid: (private) Used by the internal configuration code
16481666
* @ssid: (private) Used by the internal configuration code
16491667
* @ssid_len: (private) Used by the internal configuration code
1668+
* @mesh_id_len: (private) Used by the internal configuration code
1669+
* @mesh_id_up_len: (private) Used by the internal configuration code
16501670
* @wext: (private) Used by the internal wireless extensions compat code
16511671
* @use_4addr: indicates 4addr mode is used on this interface, must be
16521672
* set by driver (if supported) on add_interface BEFORE registering the
@@ -1676,7 +1696,7 @@ struct wireless_dev {
16761696

16771697
/* currently used for IBSS and SME - might be rearranged later */
16781698
u8 ssid[IEEE80211_MAX_SSID_LEN];
1679-
u8 ssid_len;
1699+
u8 ssid_len, mesh_id_len, mesh_id_up_len;
16801700
enum {
16811701
CFG80211_SME_IDLE,
16821702
CFG80211_SME_CONNECTING,

net/mac80211/cfg.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
6060
if (ret)
6161
return ret;
6262

63-
if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
64-
ieee80211_sdata_set_mesh_id(sdata,
65-
params->mesh_id_len,
66-
params->mesh_id);
67-
6863
if (type == NL80211_IFTYPE_AP_VLAN &&
6964
params && params->use_4addr == 0)
7065
rcu_assign_pointer(sdata->u.vlan.sta, NULL);
@@ -1003,9 +998,9 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
1003998
return (mask >> (parm-1)) & 0x1;
1004999
}
10051000

1006-
static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1007-
struct net_device *dev,
1008-
const struct mesh_config *nconf, u32 mask)
1001+
static int ieee80211_update_mesh_params(struct wiphy *wiphy,
1002+
struct net_device *dev, u32 mask,
1003+
const struct mesh_config *nconf)
10091004
{
10101005
struct mesh_config *conf;
10111006
struct ieee80211_sub_if_data *sdata;
@@ -1056,6 +1051,30 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
10561051
return 0;
10571052
}
10581053

1054+
static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1055+
const struct mesh_config *conf,
1056+
const struct mesh_setup *setup)
1057+
{
1058+
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1059+
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1060+
1061+
memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config));
1062+
ifmsh->mesh_id_len = setup->mesh_id_len;
1063+
memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1064+
1065+
ieee80211_start_mesh(sdata);
1066+
1067+
return 0;
1068+
}
1069+
1070+
static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
1071+
{
1072+
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1073+
1074+
ieee80211_stop_mesh(sdata);
1075+
1076+
return 0;
1077+
}
10591078
#endif
10601079

10611080
static int ieee80211_change_bss(struct wiphy *wiphy,
@@ -1760,8 +1779,10 @@ struct cfg80211_ops mac80211_config_ops = {
17601779
.change_mpath = ieee80211_change_mpath,
17611780
.get_mpath = ieee80211_get_mpath,
17621781
.dump_mpath = ieee80211_dump_mpath,
1763-
.set_mesh_params = ieee80211_set_mesh_params,
1782+
.update_mesh_params = ieee80211_update_mesh_params,
17641783
.get_mesh_params = ieee80211_get_mesh_params,
1784+
.join_mesh = ieee80211_join_mesh,
1785+
.leave_mesh = ieee80211_leave_mesh,
17651786
#endif
17661787
.change_bss = ieee80211_change_bss,
17671788
.set_txq_params = ieee80211_set_txq_params,

net/mac80211/ieee80211_i.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -609,19 +609,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
609609
return container_of(p, struct ieee80211_sub_if_data, vif);
610610
}
611611

612-
static inline void
613-
ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata,
614-
u8 mesh_id_len, u8 *mesh_id)
615-
{
616-
#ifdef CONFIG_MAC80211_MESH
617-
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
618-
ifmsh->mesh_id_len = mesh_id_len;
619-
memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len);
620-
#else
621-
WARN_ON(1);
622-
#endif
623-
}
624-
625612
enum sdata_queue_type {
626613
IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0,
627614
IEEE80211_SDATA_QUEUE_AGG_START = 1,

net/mac80211/iface.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
268268
goto err_stop;
269269
}
270270

271-
if (ieee80211_vif_is_mesh(&sdata->vif)) {
272-
ieee80211_start_mesh(sdata);
273-
} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
271+
if (sdata->vif.type == NL80211_IFTYPE_AP) {
274272
local->fif_pspoll++;
275273
local->fif_probe_req++;
276274

@@ -495,10 +493,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
495493
ieee80211_adjust_monitor_flags(sdata, -1);
496494
ieee80211_configure_filter(local);
497495
break;
498-
case NL80211_IFTYPE_MESH_POINT:
499-
if (ieee80211_vif_is_mesh(&sdata->vif))
500-
ieee80211_stop_mesh(sdata);
501-
/* fall through */
502496
default:
503497
flush_work(&sdata->work);
504498
/*
@@ -1188,12 +1182,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
11881182
if (ret)
11891183
goto fail;
11901184

1191-
if (ieee80211_vif_is_mesh(&sdata->vif) &&
1192-
params && params->mesh_id_len)
1193-
ieee80211_sdata_set_mesh_id(sdata,
1194-
params->mesh_id_len,
1195-
params->mesh_id);
1196-
11971185
mutex_lock(&local->iflist_mtx);
11981186
list_add_tail_rcu(&sdata->list, &local->interfaces);
11991187
mutex_unlock(&local->iflist_mtx);

net/mac80211/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
246246
!!sdata->u.ibss.presp;
247247
break;
248248
case NL80211_IFTYPE_MESH_POINT:
249-
sdata->vif.bss_conf.enable_beacon = true;
249+
sdata->vif.bss_conf.enable_beacon =
250+
!!sdata->u.mesh.mesh_id_len;
250251
break;
251252
default:
252253
/* not reached */

net/mac80211/mesh.c

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
530530
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
531531
{
532532
struct ieee80211_local *local = sdata->local;
533+
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
534+
535+
ifmsh->mesh_id_len = 0;
536+
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
537+
sta_info_flush(local, NULL);
533538

534539
del_timer_sync(&sdata->u.mesh.housekeeping_timer);
535540
del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
@@ -674,27 +679,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
674679
ieee80211_mesh_housekeeping_timer,
675680
(unsigned long) sdata);
676681

677-
ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T;
678-
ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T;
679-
ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T;
680-
ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR;
681-
ifmsh->mshcfg.dot11MeshTTL = MESH_TTL;
682-
ifmsh->mshcfg.element_ttl = MESH_DEFAULT_ELEMENT_TTL;
683-
ifmsh->mshcfg.auto_open_plinks = true;
684-
ifmsh->mshcfg.dot11MeshMaxPeerLinks =
685-
MESH_MAX_ESTAB_PLINKS;
686-
ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout =
687-
MESH_PATH_TIMEOUT;
688-
ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval =
689-
MESH_PREQ_MIN_INT;
690-
ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime =
691-
MESH_DIAM_TRAVERSAL_TIME;
692-
ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries =
693-
MESH_MAX_PREQ_RETRIES;
694-
ifmsh->mshcfg.path_refresh_time =
695-
MESH_PATH_REFRESH_TIME;
696-
ifmsh->mshcfg.min_discovery_timeout =
697-
MESH_MIN_DISCOVERY_TIMEOUT;
698682
ifmsh->accepting_plinks = true;
699683
ifmsh->preq_id = 0;
700684
ifmsh->sn = 0;

net/mac80211/mesh.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -175,33 +175,10 @@ struct mesh_rmc {
175175
*/
176176
#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2)
177177

178-
/* Default values, timeouts in ms */
179-
#define MESH_TTL 31
180-
#define MESH_MAX_RETR 3
181-
#define MESH_RET_T 100
182-
#define MESH_CONF_T 100
183-
#define MESH_HOLD_T 100
184-
185-
#define MESH_PATH_TIMEOUT 5000
186-
/* Minimum interval between two consecutive PREQs originated by the same
187-
* interface
188-
*/
189-
#define MESH_PREQ_MIN_INT 10
190-
#define MESH_DIAM_TRAVERSAL_TIME 50
191-
/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before
192-
* timing out. This way it will remain ACTIVE and no data frames will be
193-
* unnecesarily held in the pending queue.
194-
*/
195-
#define MESH_PATH_REFRESH_TIME 1000
196-
#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
197178
#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
198179

199-
#define MESH_MAX_PREQ_RETRIES 4
200180
#define MESH_PATH_EXPIRE (600 * HZ)
201181

202-
/* Default maximum number of established plinks per interface */
203-
#define MESH_MAX_ESTAB_PLINKS 32
204-
205182
/* Default maximum number of plinks per interface */
206183
#define MESH_MAX_PLINKS 256
207184

@@ -216,8 +193,6 @@ struct mesh_rmc {
216193
#define PERR_RCODE_NO_ROUTE 12
217194
#define PERR_RCODE_DEST_UNREACH 13
218195

219-
#define MESH_DEFAULT_ELEMENT_TTL 31
220-
221196
/* Public interfaces */
222197
/* Various */
223198
int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,

net/wireless/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o
1010
obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
1111

1212
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
13-
cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o
13+
cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o
1414
cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
1515
cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
1616
cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o

net/wireless/core.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
332332
WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
333333
WARN_ON(ops->add_station && !ops->del_station);
334334
WARN_ON(ops->add_mpath && !ops->del_mpath);
335+
WARN_ON(ops->join_mesh && !ops->leave_mesh);
335336

336337
alloc_size = sizeof(*rdev) + sizeof_priv;
337338

@@ -752,6 +753,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
752753
cfg80211_mlme_down(rdev, dev);
753754
wdev_unlock(wdev);
754755
break;
756+
case NL80211_IFTYPE_MESH_POINT:
757+
cfg80211_leave_mesh(rdev, dev);
758+
break;
755759
default:
756760
break;
757761
}
@@ -775,20 +779,27 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
775779
}
776780
cfg80211_lock_rdev(rdev);
777781
mutex_lock(&rdev->devlist_mtx);
778-
#ifdef CONFIG_CFG80211_WEXT
779782
wdev_lock(wdev);
780783
switch (wdev->iftype) {
784+
#ifdef CONFIG_CFG80211_WEXT
781785
case NL80211_IFTYPE_ADHOC:
782786
cfg80211_ibss_wext_join(rdev, wdev);
783787
break;
784788
case NL80211_IFTYPE_STATION:
785789
cfg80211_mgd_wext_connect(rdev, wdev);
786790
break;
791+
#endif
792+
case NL80211_IFTYPE_MESH_POINT:
793+
/* backward compat code ... */
794+
if (wdev->mesh_id_up_len)
795+
__cfg80211_join_mesh(rdev, dev, wdev->ssid,
796+
wdev->mesh_id_up_len,
797+
&default_mesh_config);
798+
break;
787799
default:
788800
break;
789801
}
790802
wdev_unlock(wdev);
791-
#endif
792803
rdev->opencount++;
793804
mutex_unlock(&rdev->devlist_mtx);
794805
cfg80211_unlock_rdev(rdev);

0 commit comments

Comments
 (0)