diff options
author | Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> | 2013-01-18 00:48:45 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-25 12:36:44 -0500 |
commit | 77765eaf5cfb6b8dd98ec8b54b411d74ff6095f1 (patch) | |
tree | 2b32fca883ee0c5a149290b3df3d97b21cb85549 | |
parent | 6d45a74b1f2e42e41c9931bfb35cdb789d0bb3ea (diff) |
cfg80211/nl80211: add API for MAC address ACLs
Add API to enable drivers to implement MAC address based
access control in AP/P2P GO mode. Capable drivers advertise
this capability by setting the maximum number of MAC
addresses in such a list in wiphy->max_acl_mac_addrs.
An initial ACL may be given to the NL80211_CMD_START_AP
command and/or changed later with NL80211_CMD_SET_MAC_ACL.
Black- and whitelists are supported, but not simultaneously.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
[rewrite commit log, many cleanups]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | include/net/cfg80211.h | 34 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 51 | ||||
-rw-r--r-- | net/wireless/core.c | 5 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 116 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 12 | ||||
-rw-r--r-- | net/wireless/trace.h | 18 |
6 files changed, 234 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 183033789e69..36e076e374d2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -532,6 +532,22 @@ struct mac_address { | |||
532 | }; | 532 | }; |
533 | 533 | ||
534 | /** | 534 | /** |
535 | * struct cfg80211_acl_data - Access control list data | ||
536 | * | ||
537 | * @acl_policy: ACL policy to be applied on the station's | ||
538 | entry specified by mac_addr | ||
539 | * @n_acl_entries: Number of MAC address entries passed | ||
540 | * @mac_addrs: List of MAC addresses of stations to be used for ACL | ||
541 | */ | ||
542 | struct cfg80211_acl_data { | ||
543 | enum nl80211_acl_policy acl_policy; | ||
544 | int n_acl_entries; | ||
545 | |||
546 | /* Keep it last */ | ||
547 | struct mac_address mac_addrs[]; | ||
548 | }; | ||
549 | |||
550 | /** | ||
535 | * struct cfg80211_ap_settings - AP configuration | 551 | * struct cfg80211_ap_settings - AP configuration |
536 | * | 552 | * |
537 | * Used to configure an AP interface. | 553 | * Used to configure an AP interface. |
@@ -550,6 +566,8 @@ struct mac_address { | |||
550 | * @inactivity_timeout: time in seconds to determine station's inactivity. | 566 | * @inactivity_timeout: time in seconds to determine station's inactivity. |
551 | * @p2p_ctwindow: P2P CT Window | 567 | * @p2p_ctwindow: P2P CT Window |
552 | * @p2p_opp_ps: P2P opportunistic PS | 568 | * @p2p_opp_ps: P2P opportunistic PS |
569 | * @acl: ACL configuration used by the drivers which has support for | ||
570 | * MAC address based access control | ||
553 | */ | 571 | */ |
554 | struct cfg80211_ap_settings { | 572 | struct cfg80211_ap_settings { |
555 | struct cfg80211_chan_def chandef; | 573 | struct cfg80211_chan_def chandef; |
@@ -566,6 +584,7 @@ struct cfg80211_ap_settings { | |||
566 | int inactivity_timeout; | 584 | int inactivity_timeout; |
567 | u8 p2p_ctwindow; | 585 | u8 p2p_ctwindow; |
568 | bool p2p_opp_ps; | 586 | bool p2p_opp_ps; |
587 | const struct cfg80211_acl_data *acl; | ||
569 | }; | 588 | }; |
570 | 589 | ||
571 | /** | 590 | /** |
@@ -1800,6 +1819,13 @@ struct cfg80211_gtk_rekey_data { | |||
1800 | * | 1819 | * |
1801 | * @start_p2p_device: Start the given P2P device. | 1820 | * @start_p2p_device: Start the given P2P device. |
1802 | * @stop_p2p_device: Stop the given P2P device. | 1821 | * @stop_p2p_device: Stop the given P2P device. |
1822 | * | ||
1823 | * @set_mac_acl: Sets MAC address control list in AP and P2P GO mode. | ||
1824 | * Parameters include ACL policy, an array of MAC address of stations | ||
1825 | * and the number of MAC addresses. If there is already a list in driver | ||
1826 | * this new list replaces the existing one. Driver has to clear its ACL | ||
1827 | * when number of MAC addresses entries is passed as 0. Drivers which | ||
1828 | * advertise the support for MAC based ACL have to implement this callback. | ||
1803 | */ | 1829 | */ |
1804 | struct cfg80211_ops { | 1830 | struct cfg80211_ops { |
1805 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1831 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
@@ -2020,6 +2046,9 @@ struct cfg80211_ops { | |||
2020 | struct wireless_dev *wdev); | 2046 | struct wireless_dev *wdev); |
2021 | void (*stop_p2p_device)(struct wiphy *wiphy, | 2047 | void (*stop_p2p_device)(struct wiphy *wiphy, |
2022 | struct wireless_dev *wdev); | 2048 | struct wireless_dev *wdev); |
2049 | |||
2050 | int (*set_mac_acl)(struct wiphy *wiphy, struct net_device *dev, | ||
2051 | const struct cfg80211_acl_data *params); | ||
2023 | }; | 2052 | }; |
2024 | 2053 | ||
2025 | /* | 2054 | /* |
@@ -2325,6 +2354,9 @@ struct wiphy_wowlan_support { | |||
2325 | * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. | 2354 | * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. |
2326 | * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. | 2355 | * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. |
2327 | * If null, then none can be over-ridden. | 2356 | * If null, then none can be over-ridden. |
2357 | * | ||
2358 | * @max_acl_mac_addrs: Maximum number of MAC addresses that the device | ||
2359 | * supports for ACL. | ||
2328 | */ | 2360 | */ |
2329 | struct wiphy { | 2361 | struct wiphy { |
2330 | /* assign these fields before you register the wiphy */ | 2362 | /* assign these fields before you register the wiphy */ |
@@ -2346,6 +2378,8 @@ struct wiphy { | |||
2346 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ | 2378 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ |
2347 | u16 interface_modes; | 2379 | u16 interface_modes; |
2348 | 2380 | ||
2381 | u16 max_acl_mac_addrs; | ||
2382 | |||
2349 | u32 flags, features; | 2383 | u32 flags, features; |
2350 | 2384 | ||
2351 | u32 ap_sme_capa; | 2385 | u32 ap_sme_capa; |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index e6eeb4ba5dc5..5b7dbc1ea966 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -170,7 +170,8 @@ | |||
170 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, | 170 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, |
171 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, | 171 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, |
172 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, | 172 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, |
173 | * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. | 173 | * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT, |
174 | * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS. | ||
174 | * The channel to use can be set on the interface or be given using the | 175 | * The channel to use can be set on the interface or be given using the |
175 | * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. | 176 | * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. |
176 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP | 177 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP |
@@ -586,6 +587,16 @@ | |||
586 | * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames | 587 | * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames |
587 | * for IBSS or MESH vif. | 588 | * for IBSS or MESH vif. |
588 | * | 589 | * |
590 | * @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control. | ||
591 | * This is to be used with the drivers advertising the support of MAC | ||
592 | * address based access control. List of MAC addresses is passed in | ||
593 | * %NL80211_ATTR_MAC_ADDRS and ACL policy is passed in | ||
594 | * %NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it | ||
595 | * is not already done. The new list will replace any existing list. Driver | ||
596 | * will clear its ACL when the list of MAC addresses passed is empty. This | ||
597 | * command is used in AP/P2P GO mode. Driver has to make sure to clear its | ||
598 | * ACL list during %NL80211_CMD_STOP_AP. | ||
599 | * | ||
589 | * @NL80211_CMD_MAX: highest used command number | 600 | * @NL80211_CMD_MAX: highest used command number |
590 | * @__NL80211_CMD_AFTER_LAST: internal use | 601 | * @__NL80211_CMD_AFTER_LAST: internal use |
591 | */ | 602 | */ |
@@ -736,6 +747,8 @@ enum nl80211_commands { | |||
736 | 747 | ||
737 | NL80211_CMD_SET_MCAST_RATE, | 748 | NL80211_CMD_SET_MCAST_RATE, |
738 | 749 | ||
750 | NL80211_CMD_SET_MAC_ACL, | ||
751 | |||
739 | /* add new commands above here */ | 752 | /* add new commands above here */ |
740 | 753 | ||
741 | /* used to define NL80211_CMD_MAX below */ | 754 | /* used to define NL80211_CMD_MAX below */ |
@@ -1313,6 +1326,16 @@ enum nl80211_commands { | |||
1313 | * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode | 1326 | * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode |
1314 | * defined in &enum nl80211_mesh_power_mode. | 1327 | * defined in &enum nl80211_mesh_power_mode. |
1315 | * | 1328 | * |
1329 | * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy, | ||
1330 | * carried in a u32 attribute | ||
1331 | * | ||
1332 | * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for | ||
1333 | * MAC ACL. | ||
1334 | * | ||
1335 | * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum | ||
1336 | * number of MAC addresses that a device can support for MAC | ||
1337 | * ACL. | ||
1338 | * | ||
1316 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1339 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1317 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1340 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1318 | */ | 1341 | */ |
@@ -1585,6 +1608,12 @@ enum nl80211_attrs { | |||
1585 | 1608 | ||
1586 | NL80211_ATTR_LOCAL_MESH_POWER_MODE, | 1609 | NL80211_ATTR_LOCAL_MESH_POWER_MODE, |
1587 | 1610 | ||
1611 | NL80211_ATTR_ACL_POLICY, | ||
1612 | |||
1613 | NL80211_ATTR_MAC_ADDRS, | ||
1614 | |||
1615 | NL80211_ATTR_MAC_ACL_MAX, | ||
1616 | |||
1588 | /* add attributes here, update the policy in nl80211.c */ | 1617 | /* add attributes here, update the policy in nl80211.c */ |
1589 | 1618 | ||
1590 | __NL80211_ATTR_AFTER_LAST, | 1619 | __NL80211_ATTR_AFTER_LAST, |
@@ -3248,7 +3277,7 @@ enum nl80211_probe_resp_offload_support_attr { | |||
3248 | * enum nl80211_connect_failed_reason - connection request failed reasons | 3277 | * enum nl80211_connect_failed_reason - connection request failed reasons |
3249 | * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be | 3278 | * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be |
3250 | * handled by the AP is reached. | 3279 | * handled by the AP is reached. |
3251 | * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Client's MAC is in the AP's blocklist. | 3280 | * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Connection request is rejected due to ACL. |
3252 | */ | 3281 | */ |
3253 | enum nl80211_connect_failed_reason { | 3282 | enum nl80211_connect_failed_reason { |
3254 | NL80211_CONN_FAIL_MAX_CLIENTS, | 3283 | NL80211_CONN_FAIL_MAX_CLIENTS, |
@@ -3276,4 +3305,22 @@ enum nl80211_scan_flags { | |||
3276 | NL80211_SCAN_FLAG_AP = 1<<2, | 3305 | NL80211_SCAN_FLAG_AP = 1<<2, |
3277 | }; | 3306 | }; |
3278 | 3307 | ||
3308 | /** | ||
3309 | * enum nl80211_acl_policy - access control policy | ||
3310 | * | ||
3311 | * Access control policy is applied on a MAC list set by | ||
3312 | * %NL80211_CMD_START_AP and %NL80211_CMD_SET_MAC_ACL, to | ||
3313 | * be used with %NL80211_ATTR_ACL_POLICY. | ||
3314 | * | ||
3315 | * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are | ||
3316 | * listed in ACL, i.e. allow all the stations which are not listed | ||
3317 | * in ACL to authenticate. | ||
3318 | * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow the stations which are listed | ||
3319 | * in ACL, i.e. deny all the stations which are not listed in ACL. | ||
3320 | */ | ||
3321 | enum nl80211_acl_policy { | ||
3322 | NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED, | ||
3323 | NL80211_ACL_POLICY_DENY_UNLESS_LISTED, | ||
3324 | }; | ||
3325 | |||
3279 | #endif /* __LINUX_NL80211_H */ | 3326 | #endif /* __LINUX_NL80211_H */ |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 0e702cdc6043..ce827242f390 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -478,6 +478,11 @@ int wiphy_register(struct wiphy *wiphy) | |||
478 | ETH_ALEN))) | 478 | ETH_ALEN))) |
479 | return -EINVAL; | 479 | return -EINVAL; |
480 | 480 | ||
481 | if (WARN_ON(wiphy->max_acl_mac_addrs && | ||
482 | (!(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME) || | ||
483 | !rdev->ops->set_mac_acl))) | ||
484 | return -EINVAL; | ||
485 | |||
481 | if (wiphy->addresses) | 486 | if (wiphy->addresses) |
482 | memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN); | 487 | memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN); |
483 | 488 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 33de80364c5c..b5978ab4ad7a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -365,6 +365,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
365 | [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, | 365 | [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, |
366 | [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, | 366 | [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, |
367 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, | 367 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, |
368 | [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, | ||
369 | [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, | ||
368 | }; | 370 | }; |
369 | 371 | ||
370 | /* policy for the key attributes */ | 372 | /* policy for the key attributes */ |
@@ -1268,6 +1270,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1268 | dev->wiphy.ht_capa_mod_mask)) | 1270 | dev->wiphy.ht_capa_mod_mask)) |
1269 | goto nla_put_failure; | 1271 | goto nla_put_failure; |
1270 | 1272 | ||
1273 | if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME && | ||
1274 | dev->wiphy.max_acl_mac_addrs && | ||
1275 | nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX, | ||
1276 | dev->wiphy.max_acl_mac_addrs)) | ||
1277 | goto nla_put_failure; | ||
1278 | |||
1271 | return genlmsg_end(msg, hdr); | 1279 | return genlmsg_end(msg, hdr); |
1272 | 1280 | ||
1273 | nla_put_failure: | 1281 | nla_put_failure: |
@@ -2491,6 +2499,97 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) | |||
2491 | return err; | 2499 | return err; |
2492 | } | 2500 | } |
2493 | 2501 | ||
2502 | /* This function returns an error or the number of nested attributes */ | ||
2503 | static int validate_acl_mac_addrs(struct nlattr *nl_attr) | ||
2504 | { | ||
2505 | struct nlattr *attr; | ||
2506 | int n_entries = 0, tmp; | ||
2507 | |||
2508 | nla_for_each_nested(attr, nl_attr, tmp) { | ||
2509 | if (nla_len(attr) != ETH_ALEN) | ||
2510 | return -EINVAL; | ||
2511 | |||
2512 | n_entries++; | ||
2513 | } | ||
2514 | |||
2515 | return n_entries; | ||
2516 | } | ||
2517 | |||
2518 | /* | ||
2519 | * This function parses ACL information and allocates memory for ACL data. | ||
2520 | * On successful return, the calling function is responsible to free the | ||
2521 | * ACL buffer returned by this function. | ||
2522 | */ | ||
2523 | static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy, | ||
2524 | struct genl_info *info) | ||
2525 | { | ||
2526 | enum nl80211_acl_policy acl_policy; | ||
2527 | struct nlattr *attr; | ||
2528 | struct cfg80211_acl_data *acl; | ||
2529 | int i = 0, n_entries, tmp; | ||
2530 | |||
2531 | if (!wiphy->max_acl_mac_addrs) | ||
2532 | return ERR_PTR(-EOPNOTSUPP); | ||
2533 | |||
2534 | if (!info->attrs[NL80211_ATTR_ACL_POLICY]) | ||
2535 | return ERR_PTR(-EINVAL); | ||
2536 | |||
2537 | acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]); | ||
2538 | if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED && | ||
2539 | acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED) | ||
2540 | return ERR_PTR(-EINVAL); | ||
2541 | |||
2542 | if (!info->attrs[NL80211_ATTR_MAC_ADDRS]) | ||
2543 | return ERR_PTR(-EINVAL); | ||
2544 | |||
2545 | n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]); | ||
2546 | if (n_entries < 0) | ||
2547 | return ERR_PTR(n_entries); | ||
2548 | |||
2549 | if (n_entries > wiphy->max_acl_mac_addrs) | ||
2550 | return ERR_PTR(-ENOTSUPP); | ||
2551 | |||
2552 | acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries), | ||
2553 | GFP_KERNEL); | ||
2554 | if (!acl) | ||
2555 | return ERR_PTR(-ENOMEM); | ||
2556 | |||
2557 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) { | ||
2558 | memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN); | ||
2559 | i++; | ||
2560 | } | ||
2561 | |||
2562 | acl->n_acl_entries = n_entries; | ||
2563 | acl->acl_policy = acl_policy; | ||
2564 | |||
2565 | return acl; | ||
2566 | } | ||
2567 | |||
2568 | static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info) | ||
2569 | { | ||
2570 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
2571 | struct net_device *dev = info->user_ptr[1]; | ||
2572 | struct cfg80211_acl_data *acl; | ||
2573 | int err; | ||
2574 | |||
2575 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | ||
2576 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | ||
2577 | return -EOPNOTSUPP; | ||
2578 | |||
2579 | if (!dev->ieee80211_ptr->beacon_interval) | ||
2580 | return -EINVAL; | ||
2581 | |||
2582 | acl = parse_acl_data(&rdev->wiphy, info); | ||
2583 | if (IS_ERR(acl)) | ||
2584 | return PTR_ERR(acl); | ||
2585 | |||
2586 | err = rdev_set_mac_acl(rdev, dev, acl); | ||
2587 | |||
2588 | kfree(acl); | ||
2589 | |||
2590 | return err; | ||
2591 | } | ||
2592 | |||
2494 | static int nl80211_parse_beacon(struct genl_info *info, | 2593 | static int nl80211_parse_beacon(struct genl_info *info, |
2495 | struct cfg80211_beacon_data *bcn) | 2594 | struct cfg80211_beacon_data *bcn) |
2496 | { | 2595 | { |
@@ -2734,6 +2833,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2734 | if (err) | 2833 | if (err) |
2735 | return err; | 2834 | return err; |
2736 | 2835 | ||
2836 | if (info->attrs[NL80211_ATTR_ACL_POLICY]) { | ||
2837 | params.acl = parse_acl_data(&rdev->wiphy, info); | ||
2838 | if (IS_ERR(params.acl)) | ||
2839 | return PTR_ERR(params.acl); | ||
2840 | } | ||
2841 | |||
2737 | err = rdev_start_ap(rdev, dev, ¶ms); | 2842 | err = rdev_start_ap(rdev, dev, ¶ms); |
2738 | if (!err) { | 2843 | if (!err) { |
2739 | wdev->preset_chandef = params.chandef; | 2844 | wdev->preset_chandef = params.chandef; |
@@ -2742,6 +2847,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2742 | wdev->ssid_len = params.ssid_len; | 2847 | wdev->ssid_len = params.ssid_len; |
2743 | memcpy(wdev->ssid, params.ssid, wdev->ssid_len); | 2848 | memcpy(wdev->ssid, params.ssid, wdev->ssid_len); |
2744 | } | 2849 | } |
2850 | |||
2851 | kfree(params.acl); | ||
2852 | |||
2745 | return err; | 2853 | return err; |
2746 | } | 2854 | } |
2747 | 2855 | ||
@@ -7876,6 +7984,14 @@ static struct genl_ops nl80211_ops[] = { | |||
7876 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7984 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7877 | NL80211_FLAG_NEED_RTNL, | 7985 | NL80211_FLAG_NEED_RTNL, |
7878 | }, | 7986 | }, |
7987 | { | ||
7988 | .cmd = NL80211_CMD_SET_MAC_ACL, | ||
7989 | .doit = nl80211_set_mac_acl, | ||
7990 | .policy = nl80211_policy, | ||
7991 | .flags = GENL_ADMIN_PERM, | ||
7992 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | ||
7993 | NL80211_FLAG_NEED_RTNL, | ||
7994 | }, | ||
7879 | }; | 7995 | }; |
7880 | 7996 | ||
7881 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 7997 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 6c0c8191f837..422d38291d66 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -875,4 +875,16 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
875 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | 875 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); |
876 | trace_rdev_return_void(&rdev->wiphy); | 876 | trace_rdev_return_void(&rdev->wiphy); |
877 | } | 877 | } |
878 | |||
879 | static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, | ||
880 | struct net_device *dev, | ||
881 | struct cfg80211_acl_data *params) | ||
882 | { | ||
883 | int ret; | ||
884 | |||
885 | trace_rdev_set_mac_acl(&rdev->wiphy, dev, params); | ||
886 | ret = rdev->ops->set_mac_acl(&rdev->wiphy, dev, params); | ||
887 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
888 | return ret; | ||
889 | } | ||
878 | #endif /* __CFG80211_RDEV_OPS */ | 890 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 2134576f426e..8bc553199686 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1767,6 +1767,24 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device, | |||
1767 | TP_ARGS(wiphy, wdev) | 1767 | TP_ARGS(wiphy, wdev) |
1768 | ); | 1768 | ); |
1769 | 1769 | ||
1770 | TRACE_EVENT(rdev_set_mac_acl, | ||
1771 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1772 | struct cfg80211_acl_data *params), | ||
1773 | TP_ARGS(wiphy, netdev, params), | ||
1774 | TP_STRUCT__entry( | ||
1775 | WIPHY_ENTRY | ||
1776 | NETDEV_ENTRY | ||
1777 | __field(u32, acl_policy) | ||
1778 | ), | ||
1779 | TP_fast_assign( | ||
1780 | WIPHY_ASSIGN; | ||
1781 | WIPHY_ASSIGN; | ||
1782 | __entry->acl_policy = params->acl_policy; | ||
1783 | ), | ||
1784 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d", | ||
1785 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->acl_policy) | ||
1786 | ); | ||
1787 | |||
1770 | /************************************************************* | 1788 | /************************************************************* |
1771 | * cfg80211 exported functions traces * | 1789 | * cfg80211 exported functions traces * |
1772 | *************************************************************/ | 1790 | *************************************************************/ |