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.c276
1 files changed, 230 insertions, 46 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3f80e565365..9b62710891a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
123 .len = NL80211_MAX_SUPP_RATES }, 123 .len = NL80211_MAX_SUPP_RATES },
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 127
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 129 .len = NL80211_HT_CAPABILITY_LEN },
@@ -171,6 +171,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, 171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
174 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
174}; 175};
175 176
176/* policy for the key attributes */ 177/* policy for the key attributes */
@@ -182,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
182 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 183 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
183 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 184 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
184 [NL80211_KEY_TYPE] = { .type = NLA_U32 }, 185 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
186 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
187};
188
189/* policy for the key default flags */
190static const struct nla_policy
191nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
192 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
193 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
185}; 194};
186 195
187/* ifidx get helper */ 196/* ifidx get helper */
@@ -314,6 +323,7 @@ struct key_parse {
314 int idx; 323 int idx;
315 int type; 324 int type;
316 bool def, defmgmt; 325 bool def, defmgmt;
326 bool def_uni, def_multi;
317}; 327};
318 328
319static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) 329static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
327 k->def = !!tb[NL80211_KEY_DEFAULT]; 337 k->def = !!tb[NL80211_KEY_DEFAULT];
328 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; 338 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
329 339
340 if (k->def) {
341 k->def_uni = true;
342 k->def_multi = true;
343 }
344 if (k->defmgmt)
345 k->def_multi = true;
346
330 if (tb[NL80211_KEY_IDX]) 347 if (tb[NL80211_KEY_IDX])
331 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); 348 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
332 349
@@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
349 return -EINVAL; 366 return -EINVAL;
350 } 367 }
351 368
369 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
370 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
371 int err = nla_parse_nested(kdt,
372 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
373 tb[NL80211_KEY_DEFAULT_TYPES],
374 nl80211_key_default_policy);
375 if (err)
376 return err;
377
378 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
379 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
380 }
381
352 return 0; 382 return 0;
353} 383}
354 384
@@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
373 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 403 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
374 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 404 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
375 405
406 if (k->def) {
407 k->def_uni = true;
408 k->def_multi = true;
409 }
410 if (k->defmgmt)
411 k->def_multi = true;
412
376 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 413 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
377 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 414 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
378 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) 415 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
379 return -EINVAL; 416 return -EINVAL;
380 } 417 }
381 418
419 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
420 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
421 int err = nla_parse_nested(
422 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
423 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
424 nl80211_key_default_policy);
425 if (err)
426 return err;
427
428 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
429 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
430 }
431
382 return 0; 432 return 0;
383} 433}
384 434
@@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
401 if (k->def && k->defmgmt) 451 if (k->def && k->defmgmt)
402 return -EINVAL; 452 return -EINVAL;
403 453
454 if (k->defmgmt) {
455 if (k->def_uni || !k->def_multi)
456 return -EINVAL;
457 }
458
404 if (k->idx != -1) { 459 if (k->idx != -1) {
405 if (k->defmgmt) { 460 if (k->defmgmt) {
406 if (k->idx < 4 || k->idx > 5) 461 if (k->idx < 4 || k->idx > 5)
@@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
450 goto error; 505 goto error;
451 def = 1; 506 def = 1;
452 result->def = parse.idx; 507 result->def = parse.idx;
508 if (!parse.def_uni || !parse.def_multi)
509 goto error;
453 } else if (parse.defmgmt) 510 } else if (parse.defmgmt)
454 goto error; 511 goto error;
455 err = cfg80211_validate_key_settings(rdev, &parse.p, 512 err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -548,7 +605,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) 605 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 606 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
550 607
551 if (dev->ops->get_antenna) { 608 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
609 dev->wiphy.available_antennas_tx);
610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
611 dev->wiphy.available_antennas_rx);
612
613 if ((dev->wiphy.available_antennas_tx ||
614 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
552 u32 tx_ant = 0, rx_ant = 0; 615 u32 tx_ant = 0, rx_ant = 0;
553 int res; 616 int res;
554 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 617 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
@@ -662,7 +725,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
662 CMD(add_beacon, NEW_BEACON); 725 CMD(add_beacon, NEW_BEACON);
663 CMD(add_station, NEW_STATION); 726 CMD(add_station, NEW_STATION);
664 CMD(add_mpath, NEW_MPATH); 727 CMD(add_mpath, NEW_MPATH);
665 CMD(update_mesh_params, SET_MESH_PARAMS); 728 CMD(update_mesh_config, SET_MESH_CONFIG);
666 CMD(change_bss, SET_BSS); 729 CMD(change_bss, SET_BSS);
667 CMD(auth, AUTHENTICATE); 730 CMD(auth, AUTHENTICATE);
668 CMD(assoc, ASSOCIATE); 731 CMD(assoc, ASSOCIATE);
@@ -698,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
698 761
699 nla_nest_end(msg, nl_cmds); 762 nla_nest_end(msg, nl_cmds);
700 763
764 if (dev->ops->remain_on_channel)
765 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
766 dev->wiphy.max_remain_on_channel_duration);
767
701 /* for now at least assume all drivers have it */ 768 /* for now at least assume all drivers have it */
702 if (dev->ops->mgmt_tx) 769 if (dev->ops->mgmt_tx)
703 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 770 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
@@ -1046,7 +1113,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && 1113 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { 1114 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1048 u32 tx_ant, rx_ant; 1115 u32 tx_ant, rx_ant;
1049 if (!rdev->ops->set_antenna) { 1116 if ((!rdev->wiphy.available_antennas_tx &&
1117 !rdev->wiphy.available_antennas_rx) ||
1118 !rdev->ops->set_antenna) {
1050 result = -EOPNOTSUPP; 1119 result = -EOPNOTSUPP;
1051 goto bad_res; 1120 goto bad_res;
1052 } 1121 }
@@ -1054,6 +1123,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); 1123 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 1124 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1056 1125
1126 /* reject antenna configurations which don't match the
1127 * available antenna masks, except for the "all" mask */
1128 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
1129 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
1130 result = -EINVAL;
1131 goto bad_res;
1132 }
1133
1134 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
1135 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
1136
1057 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 1137 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1058 if (result) 1138 if (result)
1059 goto bad_res; 1139 goto bad_res;
@@ -1575,8 +1655,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1575 struct key_parse key; 1655 struct key_parse key;
1576 int err; 1656 int err;
1577 struct net_device *dev = info->user_ptr[1]; 1657 struct net_device *dev = info->user_ptr[1];
1578 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1579 u8 key_index);
1580 1658
1581 err = nl80211_parse_key(info, &key); 1659 err = nl80211_parse_key(info, &key);
1582 if (err) 1660 if (err)
@@ -1589,27 +1667,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1589 if (!key.def && !key.defmgmt) 1667 if (!key.def && !key.defmgmt)
1590 return -EINVAL; 1668 return -EINVAL;
1591 1669
1592 if (key.def) 1670 wdev_lock(dev->ieee80211_ptr);
1593 func = rdev->ops->set_default_key;
1594 else
1595 func = rdev->ops->set_default_mgmt_key;
1596 1671
1597 if (!func) 1672 if (key.def) {
1598 return -EOPNOTSUPP; 1673 if (!rdev->ops->set_default_key) {
1674 err = -EOPNOTSUPP;
1675 goto out;
1676 }
1599 1677
1600 wdev_lock(dev->ieee80211_ptr); 1678 err = nl80211_key_allowed(dev->ieee80211_ptr);
1601 err = nl80211_key_allowed(dev->ieee80211_ptr); 1679 if (err)
1602 if (!err) 1680 goto out;
1603 err = func(&rdev->wiphy, dev, key.idx); 1681
1682 if (!(rdev->wiphy.flags &
1683 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1684 if (!key.def_uni || !key.def_multi) {
1685 err = -EOPNOTSUPP;
1686 goto out;
1687 }
1688 }
1689
1690 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1691 key.def_uni, key.def_multi);
1692
1693 if (err)
1694 goto out;
1604 1695
1605#ifdef CONFIG_CFG80211_WEXT 1696#ifdef CONFIG_CFG80211_WEXT
1606 if (!err) { 1697 dev->ieee80211_ptr->wext.default_key = key.idx;
1607 if (func == rdev->ops->set_default_key)
1608 dev->ieee80211_ptr->wext.default_key = key.idx;
1609 else
1610 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1611 }
1612#endif 1698#endif
1699 } else {
1700 if (key.def_uni || !key.def_multi) {
1701 err = -EINVAL;
1702 goto out;
1703 }
1704
1705 if (!rdev->ops->set_default_mgmt_key) {
1706 err = -EOPNOTSUPP;
1707 goto out;
1708 }
1709
1710 err = nl80211_key_allowed(dev->ieee80211_ptr);
1711 if (err)
1712 goto out;
1713
1714 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
1715 dev, key.idx);
1716 if (err)
1717 goto out;
1718
1719#ifdef CONFIG_CFG80211_WEXT
1720 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1721#endif
1722 }
1723
1724 out:
1613 wdev_unlock(dev->ieee80211_ptr); 1725 wdev_unlock(dev->ieee80211_ptr);
1614 1726
1615 return err; 1727 return err;
@@ -2569,7 +2681,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2569 return r; 2681 return r;
2570} 2682}
2571 2683
2572static int nl80211_get_mesh_params(struct sk_buff *skb, 2684static int nl80211_get_mesh_config(struct sk_buff *skb,
2573 struct genl_info *info) 2685 struct genl_info *info)
2574{ 2686{
2575 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2687 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2584,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2584 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2696 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2585 return -EOPNOTSUPP; 2697 return -EOPNOTSUPP;
2586 2698
2587 if (!rdev->ops->get_mesh_params) 2699 if (!rdev->ops->get_mesh_config)
2588 return -EOPNOTSUPP; 2700 return -EOPNOTSUPP;
2589 2701
2590 wdev_lock(wdev); 2702 wdev_lock(wdev);
@@ -2592,7 +2704,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2592 if (!wdev->mesh_id_len) 2704 if (!wdev->mesh_id_len)
2593 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); 2705 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
2594 else 2706 else
2595 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, 2707 err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
2596 &cur_params); 2708 &cur_params);
2597 wdev_unlock(wdev); 2709 wdev_unlock(wdev);
2598 2710
@@ -2604,10 +2716,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2604 if (!msg) 2716 if (!msg)
2605 return -ENOMEM; 2717 return -ENOMEM;
2606 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2718 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2607 NL80211_CMD_GET_MESH_PARAMS); 2719 NL80211_CMD_GET_MESH_CONFIG);
2608 if (!hdr) 2720 if (!hdr)
2609 goto nla_put_failure; 2721 goto nla_put_failure;
2610 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); 2722 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
2611 if (!pinfoattr) 2723 if (!pinfoattr)
2612 goto nla_put_failure; 2724 goto nla_put_failure;
2613 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 2725 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2669,7 +2781,15 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2669 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 2781 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2670}; 2782};
2671 2783
2672static int nl80211_parse_mesh_params(struct genl_info *info, 2784static const struct nla_policy
2785 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2786 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2787 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2788 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
2789 .len = IEEE80211_MAX_DATA_LEN },
2790};
2791
2792static int nl80211_parse_mesh_config(struct genl_info *info,
2673 struct mesh_config *cfg, 2793 struct mesh_config *cfg,
2674 u32 *mask_out) 2794 u32 *mask_out)
2675{ 2795{
@@ -2685,10 +2805,10 @@ do {\
2685} while (0);\ 2805} while (0);\
2686 2806
2687 2807
2688 if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) 2808 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
2689 return -EINVAL; 2809 return -EINVAL;
2690 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, 2810 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2691 info->attrs[NL80211_ATTR_MESH_PARAMS], 2811 info->attrs[NL80211_ATTR_MESH_CONFIG],
2692 nl80211_meshconf_params_policy)) 2812 nl80211_meshconf_params_policy))
2693 return -EINVAL; 2813 return -EINVAL;
2694 2814
@@ -2735,15 +2855,51 @@ do {\
2735 dot11MeshHWMPRootMode, mask, 2855 dot11MeshHWMPRootMode, mask,
2736 NL80211_MESHCONF_HWMP_ROOTMODE, 2856 NL80211_MESHCONF_HWMP_ROOTMODE,
2737 nla_get_u8); 2857 nla_get_u8);
2738
2739 if (mask_out) 2858 if (mask_out)
2740 *mask_out = mask; 2859 *mask_out = mask;
2860
2741 return 0; 2861 return 0;
2742 2862
2743#undef FILL_IN_MESH_PARAM_IF_SET 2863#undef FILL_IN_MESH_PARAM_IF_SET
2744} 2864}
2745 2865
2746static int nl80211_update_mesh_params(struct sk_buff *skb, 2866static int nl80211_parse_mesh_setup(struct genl_info *info,
2867 struct mesh_setup *setup)
2868{
2869 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
2870
2871 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
2872 return -EINVAL;
2873 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
2874 info->attrs[NL80211_ATTR_MESH_SETUP],
2875 nl80211_mesh_setup_params_policy))
2876 return -EINVAL;
2877
2878 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
2879 setup->path_sel_proto =
2880 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
2881 IEEE80211_PATH_PROTOCOL_VENDOR :
2882 IEEE80211_PATH_PROTOCOL_HWMP;
2883
2884 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
2885 setup->path_metric =
2886 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
2887 IEEE80211_PATH_METRIC_VENDOR :
2888 IEEE80211_PATH_METRIC_AIRTIME;
2889
2890 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
2891 struct nlattr *ieattr =
2892 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
2893 if (!is_valid_ie_attr(ieattr))
2894 return -EINVAL;
2895 setup->vendor_ie = nla_data(ieattr);
2896 setup->vendor_ie_len = nla_len(ieattr);
2897 }
2898
2899 return 0;
2900}
2901
2902static int nl80211_update_mesh_config(struct sk_buff *skb,
2747 struct genl_info *info) 2903 struct genl_info *info)
2748{ 2904{
2749 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2905 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2756,10 +2912,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2756 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2912 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2757 return -EOPNOTSUPP; 2913 return -EOPNOTSUPP;
2758 2914
2759 if (!rdev->ops->update_mesh_params) 2915 if (!rdev->ops->update_mesh_config)
2760 return -EOPNOTSUPP; 2916 return -EOPNOTSUPP;
2761 2917
2762 err = nl80211_parse_mesh_params(info, &cfg, &mask); 2918 err = nl80211_parse_mesh_config(info, &cfg, &mask);
2763 if (err) 2919 if (err)
2764 return err; 2920 return err;
2765 2921
@@ -2768,7 +2924,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2768 err = -ENOLINK; 2924 err = -ENOLINK;
2769 2925
2770 if (!err) 2926 if (!err)
2771 err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, 2927 err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
2772 mask, &cfg); 2928 mask, &cfg);
2773 2929
2774 wdev_unlock(wdev); 2930 wdev_unlock(wdev);
@@ -4128,7 +4284,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4128 * We should be on that channel for at least one jiffie, 4284 * We should be on that channel for at least one jiffie,
4129 * and more than 5 seconds seems excessive. 4285 * and more than 5 seconds seems excessive.
4130 */ 4286 */
4131 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 4287 if (!duration || !msecs_to_jiffies(duration) ||
4288 duration > rdev->wiphy.max_remain_on_channel_duration)
4132 return -EINVAL; 4289 return -EINVAL;
4133 4290
4134 if (!rdev->ops->remain_on_channel) 4291 if (!rdev->ops->remain_on_channel)
@@ -4296,6 +4453,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4453 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4454 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4455 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4456 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4299 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4457 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4300 return -EOPNOTSUPP; 4458 return -EOPNOTSUPP;
4301 4459
@@ -4336,6 +4494,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4336 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4494 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4337 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4495 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4338 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4496 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4497 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4339 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4498 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4340 return -EOPNOTSUPP; 4499 return -EOPNOTSUPP;
4341 4500
@@ -4562,14 +4721,16 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4562 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4563 struct net_device *dev = info->user_ptr[1]; 4722 struct net_device *dev = info->user_ptr[1];
4564 struct mesh_config cfg; 4723 struct mesh_config cfg;
4724 struct mesh_setup setup;
4565 int err; 4725 int err;
4566 4726
4567 /* start with default */ 4727 /* start with default */
4568 memcpy(&cfg, &default_mesh_config, sizeof(cfg)); 4728 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
4729 memcpy(&setup, &default_mesh_setup, sizeof(setup));
4569 4730
4570 if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { 4731 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
4571 /* and parse parameters if given */ 4732 /* and parse parameters if given */
4572 err = nl80211_parse_mesh_params(info, &cfg, NULL); 4733 err = nl80211_parse_mesh_config(info, &cfg, NULL);
4573 if (err) 4734 if (err)
4574 return err; 4735 return err;
4575 } 4736 }
@@ -4578,10 +4739,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4578 !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) 4739 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
4579 return -EINVAL; 4740 return -EINVAL;
4580 4741
4581 return cfg80211_join_mesh(rdev, dev, 4742 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
4582 nla_data(info->attrs[NL80211_ATTR_MESH_ID]), 4743 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4583 nla_len(info->attrs[NL80211_ATTR_MESH_ID]), 4744
4584 &cfg); 4745 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
4746 /* parse additional setup parameters if given */
4747 err = nl80211_parse_mesh_setup(info, &setup);
4748 if (err)
4749 return err;
4750 }
4751
4752 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
4585} 4753}
4586 4754
4587static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) 4755static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
@@ -4847,16 +5015,16 @@ static struct genl_ops nl80211_ops[] = {
4847 .flags = GENL_ADMIN_PERM, 5015 .flags = GENL_ADMIN_PERM,
4848 }, 5016 },
4849 { 5017 {
4850 .cmd = NL80211_CMD_GET_MESH_PARAMS, 5018 .cmd = NL80211_CMD_GET_MESH_CONFIG,
4851 .doit = nl80211_get_mesh_params, 5019 .doit = nl80211_get_mesh_config,
4852 .policy = nl80211_policy, 5020 .policy = nl80211_policy,
4853 /* can be retrieved by unprivileged users */ 5021 /* can be retrieved by unprivileged users */
4854 .internal_flags = NL80211_FLAG_NEED_NETDEV | 5022 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4855 NL80211_FLAG_NEED_RTNL, 5023 NL80211_FLAG_NEED_RTNL,
4856 }, 5024 },
4857 { 5025 {
4858 .cmd = NL80211_CMD_SET_MESH_PARAMS, 5026 .cmd = NL80211_CMD_SET_MESH_CONFIG,
4859 .doit = nl80211_update_mesh_params, 5027 .doit = nl80211_update_mesh_config,
4860 .policy = nl80211_policy, 5028 .policy = nl80211_policy,
4861 .flags = GENL_ADMIN_PERM, 5029 .flags = GENL_ADMIN_PERM,
4862 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5030 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -5368,6 +5536,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
5368 NL80211_CMD_DISASSOCIATE, gfp); 5536 NL80211_CMD_DISASSOCIATE, gfp);
5369} 5537}
5370 5538
5539void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
5540 struct net_device *netdev, const u8 *buf,
5541 size_t len, gfp_t gfp)
5542{
5543 nl80211_send_mlme_event(rdev, netdev, buf, len,
5544 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
5545}
5546
5547void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
5548 struct net_device *netdev, const u8 *buf,
5549 size_t len, gfp_t gfp)
5550{
5551 nl80211_send_mlme_event(rdev, netdev, buf, len,
5552 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
5553}
5554
5371static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 5555static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
5372 struct net_device *netdev, int cmd, 5556 struct net_device *netdev, int cmd,
5373 const u8 *addr, gfp_t gfp) 5557 const u8 *addr, gfp_t gfp)