diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 55 |
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 | ||
39 | static 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 | |||
39 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | 48 | static 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) | |||
377 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | 393 | static 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 | ||