wlan: Handle ACL callback functions supporting NL80211 interface
ACL interface introduces access control policy by configuring
access/deny list of the specific station MAC address. This
commit implements the ACL functionality in the WLAN host driver
by registering the callbacks to {cfg/nl}80211 interface.
Change-Id: Ia170662d032266d735eee5f8626d57cbe29f90b5
CRs-Fixed: 487410
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b7d3f61..e33f4db 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -653,6 +653,8 @@
wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
+ wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
+
/* Supports STATION & AD-HOC modes right now */
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
| BIT(NL80211_IFTYPE_ADHOC)
@@ -1880,8 +1882,8 @@
pConfig->num_deny_mac = pIe[7];
hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
pIe[6], pIe[7]);
- if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
- pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
+ if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
+ pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
for (i = 0; i < pConfig->num_deny_mac; i++)
{
@@ -1906,8 +1908,8 @@
pConfig->num_accept_mac = pIe[7];
hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
pIe[6], pIe[7]);
- if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
- pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
+ if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
+ pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
for (i = 0; i < pConfig->num_accept_mac; i++)
{
@@ -1915,6 +1917,7 @@
acl_entry++;
}
}
+
wlan_hdd_set_sapHwmode(pHostapdAdapter);
#ifdef WLAN_FEATURE_11AC
@@ -7094,6 +7097,7 @@
u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
eHalStatus status = eHAL_STATUS_FAILURE;
+ int result;
if (NULL == pAdapter)
{
@@ -7103,18 +7107,13 @@
}
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- if (NULL == pHddCtx)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: HDD context is Null!!!", __func__);
- return -ENODEV;
- }
+ result = wlan_hdd_validate_context(pHddCtx);
- if (pHddCtx->isLogpInProgress)
+ if (0 != result)
{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s: LOGP in Progress. Ignore!!!", __func__);
- return -EAGAIN;
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return result;
}
hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
@@ -7237,6 +7236,7 @@
hdd_context_t *pHddCtx;
tHalHandle hHal;
tpSirPNOScanReq pPnoRequest = NULL;
+ int result;
ENTER();
@@ -7248,18 +7248,13 @@
}
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- if (NULL == pHddCtx)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: HDD context is Null!!!", __func__);
- return -ENODEV;
- }
+ result = wlan_hdd_validate_context(pHddCtx);
- if (pHddCtx->isLogpInProgress)
+ if (0 != result)
{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s: LOGP in Progress. Ignore!!!", __func__);
- return -EAGAIN;
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return result;
}
hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
@@ -7810,6 +7805,138 @@
}
#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
+/*
+ * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
+ * This function is used to set access control policy
+ */
+static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
+ struct net_device *dev, const struct cfg80211_acl_data *params)
+{
+ int i;
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_hostapd_state_t *pHostapdState;
+ tsap_Config_t *pConfig;
+ v_CONTEXT_t pVosContext = NULL;
+ hdd_context_t *pHddCtx;
+ int status;
+
+ ENTER();
+
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: HDD adapter is Null", __func__);
+ return -ENODEV;
+ }
+
+ if (NULL == params)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: params is Null", __func__);
+ return -EINVAL;
+ }
+
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ status = wlan_hdd_validate_context(pHddCtx);
+
+ if (0 != status)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return status;
+ }
+
+ pVosContext = pHddCtx->pvosContext;
+ pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
+
+ if (NULL == pHostapdState)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: pHostapdState is Null", __func__);
+ return -EINVAL;
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
+ "no acl entries = %d", params->acl_policy, params->n_acl_entries);
+
+ if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
+ {
+ pConfig = &pAdapter->sessionCtx.ap.sapConfig;
+
+ /* default value */
+ pConfig->num_accept_mac = 0;
+ pConfig->num_deny_mac = 0;
+
+ /**
+ * access control policy
+ * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
+ * listed in hostapd.deny file.
+ * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
+ * listed in hostapd.accept file.
+ */
+ if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
+ {
+ pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
+ }
+ else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
+ {
+ pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:Acl Policy : %d is not supported",
+ __func__, params->acl_policy);
+ return -ENOTSUPP;
+ }
+
+ if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
+ {
+ pConfig->num_accept_mac = params->n_acl_entries;
+ for (i = 0; i < params->n_acl_entries; i++)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "** Add ACL MAC entry %i in WhiletList :"
+ MAC_ADDRESS_STR, i,
+ MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
+
+ vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
+ sizeof(qcmacaddr));
+ }
+ }
+ else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
+ {
+ pConfig->num_deny_mac = params->n_acl_entries;
+ for (i = 0; i < params->n_acl_entries; i++)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "** Add ACL MAC entry %i in BlackList :"
+ MAC_ADDRESS_STR, i,
+ MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
+
+ vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
+ sizeof(qcmacaddr));
+ }
+ }
+
+ if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: SAP Set Mac Acl fail", __func__);
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid device_mode = %d",
+ __func__, pAdapter->device_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* cfg80211_ops */
static struct cfg80211_ops wlan_hdd_cfg80211_ops =
{
@@ -7873,5 +8000,6 @@
.sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
.sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
#endif /*FEATURE_WLAN_SCAN_PNO */
+ .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
};
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index ae03a4f..a577451 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1486,8 +1486,8 @@
// ht_capab is not what the name conveys,this is used for protection bitmap
pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
- if (pCommitConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
- num_mac = pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
+ if (pCommitConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
+ num_mac = pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
else
num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
acl_entry = pCommitConfig->accept_mac;
@@ -1496,8 +1496,8 @@
vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
acl_entry++;
}
- if (pCommitConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
- num_mac = pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
+ if (pCommitConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
+ num_mac = pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
else
num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
acl_entry = pCommitConfig->deny_mac;