diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7b5131bd6fa1..6dc3579c0ac5 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 | } |
@@ -338,7 +354,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
338 | sinfo->rx_packets = sta->rx_packets; | 354 | sinfo->rx_packets = sta->rx_packets; |
339 | sinfo->tx_packets = sta->tx_packets; | 355 | sinfo->tx_packets = sta->tx_packets; |
340 | 356 | ||
341 | if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | 357 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
358 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | ||
342 | sinfo->filled |= STATION_INFO_SIGNAL; | 359 | sinfo->filled |= STATION_INFO_SIGNAL; |
343 | sinfo->signal = (s8)sta->last_signal; | 360 | sinfo->signal = (s8)sta->last_signal; |
344 | } | 361 | } |
@@ -377,13 +394,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, | 394 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, |
378 | int idx, u8 *mac, struct station_info *sinfo) | 395 | int idx, u8 *mac, struct station_info *sinfo) |
379 | { | 396 | { |
380 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 397 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
381 | struct sta_info *sta; | 398 | struct sta_info *sta; |
382 | int ret = -ENOENT; | 399 | int ret = -ENOENT; |
383 | 400 | ||
384 | rcu_read_lock(); | 401 | rcu_read_lock(); |
385 | 402 | ||
386 | sta = sta_info_get_by_idx(local, idx, dev); | 403 | sta = sta_info_get_by_idx(sdata, idx); |
387 | if (sta) { | 404 | if (sta) { |
388 | ret = 0; | 405 | ret = 0; |
389 | memcpy(mac, sta->sta.addr, ETH_ALEN); | 406 | memcpy(mac, sta->sta.addr, ETH_ALEN); |
@@ -738,13 +755,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
738 | 755 | ||
739 | err = sta_info_insert(sta); | 756 | err = sta_info_insert(sta); |
740 | if (err) { | 757 | 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(); | 758 | rcu_read_unlock(); |
749 | return err; | 759 | return err; |
750 | } | 760 | } |
@@ -813,6 +823,15 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
813 | return -EINVAL; | 823 | return -EINVAL; |
814 | } | 824 | } |
815 | 825 | ||
826 | if (params->vlan->ieee80211_ptr->use_4addr) { | ||
827 | if (vlansdata->u.vlan.sta) { | ||
828 | rcu_read_unlock(); | ||
829 | return -EBUSY; | ||
830 | } | ||
831 | |||
832 | rcu_assign_pointer(vlansdata->u.vlan.sta, sta); | ||
833 | } | ||
834 | |||
816 | sta->sdata = vlansdata; | 835 | sta->sdata = vlansdata; |
817 | ieee80211_send_layer2_update(sta); | 836 | ieee80211_send_layer2_update(sta); |
818 | } | 837 | } |
@@ -914,7 +933,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
914 | pinfo->generation = mesh_paths_generation; | 933 | pinfo->generation = mesh_paths_generation; |
915 | 934 | ||
916 | pinfo->filled = MPATH_INFO_FRAME_QLEN | | 935 | pinfo->filled = MPATH_INFO_FRAME_QLEN | |
917 | MPATH_INFO_DSN | | 936 | MPATH_INFO_SN | |
918 | MPATH_INFO_METRIC | | 937 | MPATH_INFO_METRIC | |
919 | MPATH_INFO_EXPTIME | | 938 | MPATH_INFO_EXPTIME | |
920 | MPATH_INFO_DISCOVERY_TIMEOUT | | 939 | MPATH_INFO_DISCOVERY_TIMEOUT | |
@@ -922,7 +941,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
922 | MPATH_INFO_FLAGS; | 941 | MPATH_INFO_FLAGS; |
923 | 942 | ||
924 | pinfo->frame_qlen = mpath->frame_queue.qlen; | 943 | pinfo->frame_qlen = mpath->frame_queue.qlen; |
925 | pinfo->dsn = mpath->dsn; | 944 | pinfo->sn = mpath->sn; |
926 | pinfo->metric = mpath->metric; | 945 | pinfo->metric = mpath->metric; |
927 | if (time_before(jiffies, mpath->exp_time)) | 946 | if (time_before(jiffies, mpath->exp_time)) |
928 | pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); | 947 | pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); |
@@ -934,8 +953,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
934 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; | 953 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; |
935 | if (mpath->flags & MESH_PATH_RESOLVING) | 954 | if (mpath->flags & MESH_PATH_RESOLVING) |
936 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; | 955 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; |
937 | if (mpath->flags & MESH_PATH_DSN_VALID) | 956 | if (mpath->flags & MESH_PATH_SN_VALID) |
938 | pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; | 957 | pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; |
939 | if (mpath->flags & MESH_PATH_FIXED) | 958 | if (mpath->flags & MESH_PATH_FIXED) |
940 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; | 959 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; |
941 | if (mpath->flags & MESH_PATH_RESOLVING) | 960 | if (mpath->flags & MESH_PATH_RESOLVING) |
@@ -1008,7 +1027,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, | |||
1008 | { | 1027 | { |
1009 | struct mesh_config *conf; | 1028 | struct mesh_config *conf; |
1010 | struct ieee80211_sub_if_data *sdata; | 1029 | struct ieee80211_sub_if_data *sdata; |
1030 | struct ieee80211_if_mesh *ifmsh; | ||
1031 | |||
1011 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1032 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1033 | ifmsh = &sdata->u.mesh; | ||
1012 | 1034 | ||
1013 | /* Set the config options which we are interested in setting */ | 1035 | /* Set the config options which we are interested in setting */ |
1014 | conf = &(sdata->u.mesh.mshcfg); | 1036 | conf = &(sdata->u.mesh.mshcfg); |
@@ -1043,6 +1065,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, | |||
1043 | mask)) | 1065 | mask)) |
1044 | conf->dot11MeshHWMPnetDiameterTraversalTime = | 1066 | conf->dot11MeshHWMPnetDiameterTraversalTime = |
1045 | nconf->dot11MeshHWMPnetDiameterTraversalTime; | 1067 | nconf->dot11MeshHWMPnetDiameterTraversalTime; |
1068 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) { | ||
1069 | conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode; | ||
1070 | ieee80211_mesh_root_setup(ifmsh); | ||
1071 | } | ||
1046 | return 0; | 1072 | return 0; |
1047 | } | 1073 | } |
1048 | 1074 | ||