diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 56319b51d170..7f18c8fa1880 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -36,6 +36,24 @@ 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 | if (params->use_4addr > 0) { | ||
46 | switch(type) { | ||
47 | case NL80211_IFTYPE_AP_VLAN: | ||
48 | case NL80211_IFTYPE_STATION: | ||
49 | break; | ||
50 | default: | ||
51 | return false; | ||
52 | } | ||
53 | } | ||
54 | return true; | ||
55 | } | ||
56 | |||
39 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | 57 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, |
40 | enum nl80211_iftype type, u32 *flags, | 58 | enum nl80211_iftype type, u32 *flags, |
41 | struct vif_params *params) | 59 | struct vif_params *params) |
@@ -45,7 +63,7 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
45 | struct ieee80211_sub_if_data *sdata; | 63 | struct ieee80211_sub_if_data *sdata; |
46 | int err; | 64 | int err; |
47 | 65 | ||
48 | if (!nl80211_type_check(type)) | 66 | if (!nl80211_params_check(type, params)) |
49 | return -EINVAL; | 67 | return -EINVAL; |
50 | 68 | ||
51 | err = ieee80211_if_add(local, name, &dev, type, params); | 69 | err = ieee80211_if_add(local, name, &dev, type, params); |
@@ -75,7 +93,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
75 | if (netif_running(dev)) | 93 | if (netif_running(dev)) |
76 | return -EBUSY; | 94 | return -EBUSY; |
77 | 95 | ||
78 | if (!nl80211_type_check(type)) | 96 | if (!nl80211_params_check(type, params)) |
79 | return -EINVAL; | 97 | return -EINVAL; |
80 | 98 | ||
81 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 99 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -89,6 +107,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
89 | params->mesh_id_len, | 107 | params->mesh_id_len, |
90 | params->mesh_id); | 108 | params->mesh_id); |
91 | 109 | ||
110 | if (params->use_4addr >= 0) | ||
111 | sdata->use_4addr = !!params->use_4addr; | ||
112 | |||
92 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) | 113 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) |
93 | return 0; | 114 | return 0; |
94 | 115 | ||
@@ -806,6 +827,13 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
806 | return -EINVAL; | 827 | return -EINVAL; |
807 | } | 828 | } |
808 | 829 | ||
830 | if (vlansdata->use_4addr) { | ||
831 | if (vlansdata->u.vlan.sta) | ||
832 | return -EBUSY; | ||
833 | |||
834 | rcu_assign_pointer(vlansdata->u.vlan.sta, sta); | ||
835 | } | ||
836 | |||
809 | sta->sdata = vlansdata; | 837 | sta->sdata = vlansdata; |
810 | ieee80211_send_layer2_update(sta); | 838 | ieee80211_send_layer2_update(sta); |
811 | } | 839 | } |
@@ -907,7 +935,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
907 | pinfo->generation = mesh_paths_generation; | 935 | pinfo->generation = mesh_paths_generation; |
908 | 936 | ||
909 | pinfo->filled = MPATH_INFO_FRAME_QLEN | | 937 | pinfo->filled = MPATH_INFO_FRAME_QLEN | |
910 | MPATH_INFO_DSN | | 938 | MPATH_INFO_SN | |
911 | MPATH_INFO_METRIC | | 939 | MPATH_INFO_METRIC | |
912 | MPATH_INFO_EXPTIME | | 940 | MPATH_INFO_EXPTIME | |
913 | MPATH_INFO_DISCOVERY_TIMEOUT | | 941 | MPATH_INFO_DISCOVERY_TIMEOUT | |
@@ -915,7 +943,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
915 | MPATH_INFO_FLAGS; | 943 | MPATH_INFO_FLAGS; |
916 | 944 | ||
917 | pinfo->frame_qlen = mpath->frame_queue.qlen; | 945 | pinfo->frame_qlen = mpath->frame_queue.qlen; |
918 | pinfo->dsn = mpath->dsn; | 946 | pinfo->sn = mpath->sn; |
919 | pinfo->metric = mpath->metric; | 947 | pinfo->metric = mpath->metric; |
920 | if (time_before(jiffies, mpath->exp_time)) | 948 | if (time_before(jiffies, mpath->exp_time)) |
921 | pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); | 949 | pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); |
@@ -927,8 +955,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
927 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; | 955 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; |
928 | if (mpath->flags & MESH_PATH_RESOLVING) | 956 | if (mpath->flags & MESH_PATH_RESOLVING) |
929 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; | 957 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; |
930 | if (mpath->flags & MESH_PATH_DSN_VALID) | 958 | if (mpath->flags & MESH_PATH_SN_VALID) |
931 | pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; | 959 | pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; |
932 | if (mpath->flags & MESH_PATH_FIXED) | 960 | if (mpath->flags & MESH_PATH_FIXED) |
933 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; | 961 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; |
934 | if (mpath->flags & MESH_PATH_RESOLVING) | 962 | if (mpath->flags & MESH_PATH_RESOLVING) |
@@ -1001,7 +1029,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, | |||
1001 | { | 1029 | { |
1002 | struct mesh_config *conf; | 1030 | struct mesh_config *conf; |
1003 | struct ieee80211_sub_if_data *sdata; | 1031 | struct ieee80211_sub_if_data *sdata; |
1032 | struct ieee80211_if_mesh *ifmsh; | ||
1033 | |||
1004 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1034 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1035 | ifmsh = &sdata->u.mesh; | ||
1005 | 1036 | ||
1006 | /* Set the config options which we are interested in setting */ | 1037 | /* Set the config options which we are interested in setting */ |
1007 | conf = &(sdata->u.mesh.mshcfg); | 1038 | conf = &(sdata->u.mesh.mshcfg); |
@@ -1036,6 +1067,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy, | |||
1036 | mask)) | 1067 | mask)) |
1037 | conf->dot11MeshHWMPnetDiameterTraversalTime = | 1068 | conf->dot11MeshHWMPnetDiameterTraversalTime = |
1038 | nconf->dot11MeshHWMPnetDiameterTraversalTime; | 1069 | nconf->dot11MeshHWMPnetDiameterTraversalTime; |
1070 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) { | ||
1071 | conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode; | ||
1072 | ieee80211_mesh_root_setup(ifmsh); | ||
1073 | } | ||
1039 | return 0; | 1074 | return 0; |
1040 | } | 1075 | } |
1041 | 1076 | ||