aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c81
1 files changed, 74 insertions, 7 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1e728fff474e..e69da8d20474 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -105,6 +105,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
105 105
106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
107 .len = NL80211_HT_CAPABILITY_LEN }, 107 .len = NL80211_HT_CAPABILITY_LEN },
108
109 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
110 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
111 .len = IEEE80211_MAX_DATA_LEN },
108}; 112};
109 113
110/* message building helper */ 114/* message building helper */
@@ -738,7 +742,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
738 if (info->attrs[NL80211_ATTR_KEY_IDX]) 742 if (info->attrs[NL80211_ATTR_KEY_IDX])
739 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 743 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
740 744
741 if (key_idx > 3) 745 if (key_idx > 5)
742 return -EINVAL; 746 return -EINVAL;
743 747
744 if (info->attrs[NL80211_ATTR_MAC]) 748 if (info->attrs[NL80211_ATTR_MAC])
@@ -804,30 +808,41 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
804 int err; 808 int err;
805 struct net_device *dev; 809 struct net_device *dev;
806 u8 key_idx; 810 u8 key_idx;
811 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
812 u8 key_index);
807 813
808 if (!info->attrs[NL80211_ATTR_KEY_IDX]) 814 if (!info->attrs[NL80211_ATTR_KEY_IDX])
809 return -EINVAL; 815 return -EINVAL;
810 816
811 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 817 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
812 818
813 if (key_idx > 3) 819 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
820 if (key_idx < 4 || key_idx > 5)
821 return -EINVAL;
822 } else if (key_idx > 3)
814 return -EINVAL; 823 return -EINVAL;
815 824
816 /* currently only support setting default key */ 825 /* currently only support setting default key */
817 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) 826 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
827 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
818 return -EINVAL; 828 return -EINVAL;
819 829
820 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 830 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
821 if (err) 831 if (err)
822 return err; 832 return err;
823 833
824 if (!drv->ops->set_default_key) { 834 if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
835 func = drv->ops->set_default_key;
836 else
837 func = drv->ops->set_default_mgmt_key;
838
839 if (!func) {
825 err = -EOPNOTSUPP; 840 err = -EOPNOTSUPP;
826 goto out; 841 goto out;
827 } 842 }
828 843
829 rtnl_lock(); 844 rtnl_lock();
830 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx); 845 err = func(&drv->wiphy, dev, key_idx);
831 rtnl_unlock(); 846 rtnl_unlock();
832 847
833 out: 848 out:
@@ -863,7 +878,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
863 if (info->attrs[NL80211_ATTR_MAC]) 878 if (info->attrs[NL80211_ATTR_MAC])
864 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 879 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
865 880
866 if (key_idx > 3) 881 if (key_idx > 5)
867 return -EINVAL; 882 return -EINVAL;
868 883
869 /* 884 /*
@@ -894,6 +909,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
894 if (params.key_len != 13) 909 if (params.key_len != 13)
895 return -EINVAL; 910 return -EINVAL;
896 break; 911 break;
912 case WLAN_CIPHER_SUITE_AES_CMAC:
913 if (params.key_len != 16)
914 return -EINVAL;
915 break;
897 default: 916 default:
898 return -EINVAL; 917 return -EINVAL;
899 } 918 }
@@ -928,7 +947,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
928 if (info->attrs[NL80211_ATTR_KEY_IDX]) 947 if (info->attrs[NL80211_ATTR_KEY_IDX])
929 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 948 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
930 949
931 if (key_idx > 3) 950 if (key_idx > 5)
932 return -EINVAL; 951 return -EINVAL;
933 952
934 if (info->attrs[NL80211_ATTR_MAC]) 953 if (info->attrs[NL80211_ATTR_MAC])
@@ -1889,6 +1908,11 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1889 mutex_lock(&cfg80211_drv_mutex); 1908 mutex_lock(&cfg80211_drv_mutex);
1890 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY); 1909 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
1891 mutex_unlock(&cfg80211_drv_mutex); 1910 mutex_unlock(&cfg80211_drv_mutex);
1911 /* This means the regulatory domain was already set, however
1912 * we don't want to confuse userspace with a "successful error"
1913 * message so lets just treat it as a success */
1914 if (r == -EALREADY)
1915 r = 0;
1892 return r; 1916 return r;
1893} 1917}
1894 1918
@@ -2134,6 +2158,43 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2134 return -EINVAL; 2158 return -EINVAL;
2135} 2159}
2136 2160
2161static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2162 struct genl_info *info)
2163{
2164 struct cfg80211_registered_device *drv;
2165 int err;
2166 struct net_device *dev;
2167 struct mgmt_extra_ie_params params;
2168
2169 memset(&params, 0, sizeof(params));
2170
2171 if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
2172 return -EINVAL;
2173 params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
2174 if (params.subtype > 15)
2175 return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
2176
2177 if (info->attrs[NL80211_ATTR_IE]) {
2178 params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2179 params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2180 }
2181
2182 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2183 if (err)
2184 return err;
2185
2186 if (drv->ops->set_mgmt_extra_ie) {
2187 rtnl_lock();
2188 err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
2189 rtnl_unlock();
2190 } else
2191 err = -EOPNOTSUPP;
2192
2193 cfg80211_put_dev(drv);
2194 dev_put(dev);
2195 return err;
2196}
2197
2137static struct genl_ops nl80211_ops[] = { 2198static struct genl_ops nl80211_ops[] = {
2138 { 2199 {
2139 .cmd = NL80211_CMD_GET_WIPHY, 2200 .cmd = NL80211_CMD_GET_WIPHY,
@@ -2295,6 +2356,12 @@ static struct genl_ops nl80211_ops[] = {
2295 .policy = nl80211_policy, 2356 .policy = nl80211_policy,
2296 .flags = GENL_ADMIN_PERM, 2357 .flags = GENL_ADMIN_PERM,
2297 }, 2358 },
2359 {
2360 .cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
2361 .doit = nl80211_set_mgmt_extra_ie,
2362 .policy = nl80211_policy,
2363 .flags = GENL_ADMIN_PERM,
2364 },
2298}; 2365};
2299 2366
2300/* multicast groups */ 2367/* multicast groups */