aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7b5131bd6fa1..93ee1fd5c08d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -36,6 +36,15 @@ static bool nl80211_type_check(enum nl80211_iftype type)
36 } 36 }
37} 37}
38 38
39static bool nl80211_params_check(enum nl80211_iftype type,
40 struct vif_params *params)
41{
42 if (!nl80211_type_check(type))
43 return false;
44
45 return true;
46}
47
39static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 48static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
40 enum nl80211_iftype type, u32 *flags, 49 enum nl80211_iftype type, u32 *flags,
41 struct vif_params *params) 50 struct vif_params *params)
@@ -45,7 +54,7 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
45 struct ieee80211_sub_if_data *sdata; 54 struct ieee80211_sub_if_data *sdata;
46 int err; 55 int err;
47 56
48 if (!nl80211_type_check(type)) 57 if (!nl80211_params_check(type, params))
49 return -EINVAL; 58 return -EINVAL;
50 59
51 err = ieee80211_if_add(local, name, &dev, type, params); 60 err = ieee80211_if_add(local, name, &dev, type, params);
@@ -75,7 +84,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
75 if (netif_running(dev)) 84 if (netif_running(dev))
76 return -EBUSY; 85 return -EBUSY;
77 86
78 if (!nl80211_type_check(type)) 87 if (!nl80211_params_check(type, params))
79 return -EINVAL; 88 return -EINVAL;
80 89
81 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 90 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -92,6 +101,13 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
92 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) 101 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
93 return 0; 102 return 0;
94 103
104 if (type == NL80211_IFTYPE_AP_VLAN &&
105 params && params->use_4addr == 0)
106 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
107 else if (type == NL80211_IFTYPE_STATION &&
108 params && params->use_4addr >= 0)
109 sdata->u.mgd.use_4addr = params->use_4addr;
110
95 sdata->u.mntr_flags = *flags; 111 sdata->u.mntr_flags = *flags;
96 return 0; 112 return 0;
97} 113}
@@ -377,13 +393,13 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
377static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, 393static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
378 int idx, u8 *mac, struct station_info *sinfo) 394 int idx, u8 *mac, struct station_info *sinfo)
379{ 395{
380 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 396 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
381 struct sta_info *sta; 397 struct sta_info *sta;
382 int ret = -ENOENT; 398 int ret = -ENOENT;
383 399
384 rcu_read_lock(); 400 rcu_read_lock();
385 401
386 sta = sta_info_get_by_idx(local, idx, dev); 402 sta = sta_info_get_by_idx(sdata, idx);
387 if (sta) { 403 if (sta) {
388 ret = 0; 404 ret = 0;
389 memcpy(mac, sta->sta.addr, ETH_ALEN); 405 memcpy(mac, sta->sta.addr, ETH_ALEN);
@@ -738,13 +754,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
738 754
739 err = sta_info_insert(sta); 755 err = sta_info_insert(sta);
740 if (err) { 756 if (err) {
741 /* STA has been freed */
742 if (err == -EEXIST && layer2_update) {
743 /* Need to update layer 2 devices on reassociation */
744 sta = sta_info_get(local, mac);
745 if (sta)
746 ieee80211_send_layer2_update(sta);
747 }
748 rcu_read_unlock(); 757 rcu_read_unlock();
749 return err; 758 return err;
750 } 759 }
@@ -813,6 +822,15 @@ static int ieee80211_change_station(struct wiphy *wiphy,
813 return -EINVAL; 822 return -EINVAL;
814 } 823 }
815 824
825 if (params->vlan->ieee80211_ptr->use_4addr) {
826 if (vlansdata->u.vlan.sta) {
827 rcu_read_unlock();
828 return -EBUSY;
829 }
830
831 rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
832 }
833
816 sta->sdata = vlansdata; 834 sta->sdata = vlansdata;
817 ieee80211_send_layer2_update(sta); 835 ieee80211_send_layer2_update(sta);
818 } 836 }
@@ -914,7 +932,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
914 pinfo->generation = mesh_paths_generation; 932 pinfo->generation = mesh_paths_generation;
915 933
916 pinfo->filled = MPATH_INFO_FRAME_QLEN | 934 pinfo->filled = MPATH_INFO_FRAME_QLEN |
917 MPATH_INFO_DSN | 935 MPATH_INFO_SN |
918 MPATH_INFO_METRIC | 936 MPATH_INFO_METRIC |
919 MPATH_INFO_EXPTIME | 937 MPATH_INFO_EXPTIME |
920 MPATH_INFO_DISCOVERY_TIMEOUT | 938 MPATH_INFO_DISCOVERY_TIMEOUT |
@@ -922,7 +940,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
922 MPATH_INFO_FLAGS; 940 MPATH_INFO_FLAGS;
923 941
924 pinfo->frame_qlen = mpath->frame_queue.qlen; 942 pinfo->frame_qlen = mpath->frame_queue.qlen;
925 pinfo->dsn = mpath->dsn; 943 pinfo->sn = mpath->sn;
926 pinfo->metric = mpath->metric; 944 pinfo->metric = mpath->metric;
927 if (time_before(jiffies, mpath->exp_time)) 945 if (time_before(jiffies, mpath->exp_time))
928 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); 946 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
@@ -934,8 +952,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
934 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 952 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
935 if (mpath->flags & MESH_PATH_RESOLVING) 953 if (mpath->flags & MESH_PATH_RESOLVING)
936 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 954 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
937 if (mpath->flags & MESH_PATH_DSN_VALID) 955 if (mpath->flags & MESH_PATH_SN_VALID)
938 pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; 956 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
939 if (mpath->flags & MESH_PATH_FIXED) 957 if (mpath->flags & MESH_PATH_FIXED)
940 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 958 pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
941 if (mpath->flags & MESH_PATH_RESOLVING) 959 if (mpath->flags & MESH_PATH_RESOLVING)
@@ -1008,7 +1026,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1008{ 1026{
1009 struct mesh_config *conf; 1027 struct mesh_config *conf;
1010 struct ieee80211_sub_if_data *sdata; 1028 struct ieee80211_sub_if_data *sdata;
1029 struct ieee80211_if_mesh *ifmsh;
1030
1011 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1031 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1032 ifmsh = &sdata->u.mesh;
1012 1033
1013 /* Set the config options which we are interested in setting */ 1034 /* Set the config options which we are interested in setting */
1014 conf = &(sdata->u.mesh.mshcfg); 1035 conf = &(sdata->u.mesh.mshcfg);
@@ -1043,6 +1064,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1043 mask)) 1064 mask))
1044 conf->dot11MeshHWMPnetDiameterTraversalTime = 1065 conf->dot11MeshHWMPnetDiameterTraversalTime =
1045 nconf->dot11MeshHWMPnetDiameterTraversalTime; 1066 nconf->dot11MeshHWMPnetDiameterTraversalTime;
1067 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
1068 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1069 ieee80211_mesh_root_setup(ifmsh);
1070 }
1046 return 0; 1071 return 0;
1047} 1072}
1048 1073