xref: /dflybsd-src/sys/netproto/802_11/wlan_acl/ieee80211_acl.c (revision 1e290df35345fbdb4da7834e2bc7c2c5a083b4a4)
132176cfdSRui Paulo /*-
232176cfdSRui Paulo  * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting
3841ab66cSSepherosa Ziehau  * All rights reserved.
4841ab66cSSepherosa Ziehau  *
5841ab66cSSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
6841ab66cSSepherosa Ziehau  * modification, are permitted provided that the following conditions
7841ab66cSSepherosa Ziehau  * are met:
8841ab66cSSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
9841ab66cSSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer.
10841ab66cSSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
11841ab66cSSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
12841ab66cSSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
13841ab66cSSepherosa Ziehau  *
14841ab66cSSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15841ab66cSSepherosa Ziehau  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16841ab66cSSepherosa Ziehau  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17841ab66cSSepherosa Ziehau  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18841ab66cSSepherosa Ziehau  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19841ab66cSSepherosa Ziehau  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20841ab66cSSepherosa Ziehau  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21841ab66cSSepherosa Ziehau  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22841ab66cSSepherosa Ziehau  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23841ab66cSSepherosa Ziehau  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24841ab66cSSepherosa Ziehau  *
2532176cfdSRui Paulo  * $FreeBSD: head/sys/net80211/ieee80211_acl.c 186302 2008-12-18 23:00:09Z sam $
26841ab66cSSepherosa Ziehau  */
27841ab66cSSepherosa Ziehau 
28841ab66cSSepherosa Ziehau /*
29841ab66cSSepherosa Ziehau  * IEEE 802.11 MAC ACL support.
30841ab66cSSepherosa Ziehau  *
3132176cfdSRui Paulo  * When this module is loaded the sender address of each auth mgt
32841ab66cSSepherosa Ziehau  * frame is passed to the iac_check method and the module indicates
33841ab66cSSepherosa Ziehau  * if the frame should be accepted or rejected.  If the policy is
34841ab66cSSepherosa Ziehau  * set to ACL_POLICY_OPEN then all frames are accepted w/o checking
35841ab66cSSepherosa Ziehau  * the address.  Otherwise, the address is looked up in the database
36841ab66cSSepherosa Ziehau  * and if found the frame is either accepted (ACL_POLICY_ALLOW)
37841ab66cSSepherosa Ziehau  * or rejected (ACL_POLICY_DENT).
38841ab66cSSepherosa Ziehau  */
3932176cfdSRui Paulo #include "opt_wlan.h"
4032176cfdSRui Paulo 
41841ab66cSSepherosa Ziehau #include <sys/param.h>
42841ab66cSSepherosa Ziehau #include <sys/kernel.h>
43841ab66cSSepherosa Ziehau #include <sys/systm.h>
44841ab66cSSepherosa Ziehau #include <sys/mbuf.h>
45841ab66cSSepherosa Ziehau #include <sys/module.h>
46841ab66cSSepherosa Ziehau #include <sys/queue.h>
47841ab66cSSepherosa Ziehau 
48841ab66cSSepherosa Ziehau #include <sys/socket.h>
49841ab66cSSepherosa Ziehau 
50841ab66cSSepherosa Ziehau #include <net/if.h>
51841ab66cSSepherosa Ziehau #include <net/if_media.h>
52841ab66cSSepherosa Ziehau #include <net/ethernet.h>
53841ab66cSSepherosa Ziehau #include <net/route.h>
54841ab66cSSepherosa Ziehau 
55841ab66cSSepherosa Ziehau #include <netproto/802_11/ieee80211_var.h>
56841ab66cSSepherosa Ziehau 
57841ab66cSSepherosa Ziehau enum {
58841ab66cSSepherosa Ziehau 	ACL_POLICY_OPEN		= 0,	/* open, don't check ACL's */
59841ab66cSSepherosa Ziehau 	ACL_POLICY_ALLOW	= 1,	/* allow traffic from MAC */
60841ab66cSSepherosa Ziehau 	ACL_POLICY_DENY		= 2,	/* deny traffic from MAC */
6132176cfdSRui Paulo 	/*
6232176cfdSRui Paulo 	 * NB: ACL_POLICY_RADIUS must be the same value as
6332176cfdSRui Paulo 	 *     IEEE80211_MACCMD_POLICY_RADIUS because of the way
6432176cfdSRui Paulo 	 *     acl_getpolicy() works.
6532176cfdSRui Paulo 	 */
6632176cfdSRui Paulo 	ACL_POLICY_RADIUS	= 7,	/* defer to RADIUS ACL server */
67841ab66cSSepherosa Ziehau };
68841ab66cSSepherosa Ziehau 
69841ab66cSSepherosa Ziehau #define	ACL_HASHSIZE	32
70841ab66cSSepherosa Ziehau 
71841ab66cSSepherosa Ziehau struct acl {
72841ab66cSSepherosa Ziehau 	TAILQ_ENTRY(acl)	acl_list;
73841ab66cSSepherosa Ziehau 	LIST_ENTRY(acl)		acl_hash;
74841ab66cSSepherosa Ziehau 	uint8_t			acl_macaddr[IEEE80211_ADDR_LEN];
75841ab66cSSepherosa Ziehau };
76841ab66cSSepherosa Ziehau struct aclstate {
77841ab66cSSepherosa Ziehau 	int			as_policy;
78841ab66cSSepherosa Ziehau 	int			as_nacls;
79841ab66cSSepherosa Ziehau 	TAILQ_HEAD(, acl)	as_list;	/* list of all ACL's */
80841ab66cSSepherosa Ziehau 	LIST_HEAD(, acl)	as_hash[ACL_HASHSIZE];
8132176cfdSRui Paulo 	struct ieee80211vap	*as_vap;
82841ab66cSSepherosa Ziehau };
83841ab66cSSepherosa Ziehau 
84841ab66cSSepherosa Ziehau /* simple hash is enough for variation of macaddr */
85841ab66cSSepherosa Ziehau #define	ACL_HASH(addr)	\
86841ab66cSSepherosa Ziehau 	(((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % ACL_HASHSIZE)
87841ab66cSSepherosa Ziehau 
88841ab66cSSepherosa Ziehau MALLOC_DEFINE(M_80211_ACL, "acl", "802.11 station acl");
89841ab66cSSepherosa Ziehau 
9032176cfdSRui Paulo static	int acl_free_all(struct ieee80211vap *);
9132176cfdSRui Paulo 
9232176cfdSRui Paulo /* number of references from net80211 layer */
9332176cfdSRui Paulo static	int nrefs = 0;
94841ab66cSSepherosa Ziehau 
95841ab66cSSepherosa Ziehau static int
9632176cfdSRui Paulo acl_attach(struct ieee80211vap *vap)
97841ab66cSSepherosa Ziehau {
98841ab66cSSepherosa Ziehau 	struct aclstate *as;
99841ab66cSSepherosa Ziehau 
10032176cfdSRui Paulo 	as = (struct aclstate *) kmalloc(sizeof(struct aclstate),
101c567b546SJoe Talbott 		M_80211_ACL, M_INTWAIT | M_ZERO);
102841ab66cSSepherosa Ziehau 	if (as == NULL)
103841ab66cSSepherosa Ziehau 		return 0;
104841ab66cSSepherosa Ziehau 	TAILQ_INIT(&as->as_list);
105841ab66cSSepherosa Ziehau 	as->as_policy = ACL_POLICY_OPEN;
10632176cfdSRui Paulo 	as->as_vap = vap;
10732176cfdSRui Paulo 	vap->iv_as = as;
10832176cfdSRui Paulo 	nrefs++;			/* NB: we assume caller locking */
109841ab66cSSepherosa Ziehau 	return 1;
110841ab66cSSepherosa Ziehau }
111841ab66cSSepherosa Ziehau 
112841ab66cSSepherosa Ziehau static void
11332176cfdSRui Paulo acl_detach(struct ieee80211vap *vap)
114841ab66cSSepherosa Ziehau {
11532176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
116841ab66cSSepherosa Ziehau 
11732176cfdSRui Paulo 	KASSERT(nrefs > 0, ("imbalanced attach/detach"));
11832176cfdSRui Paulo 	nrefs--;			/* NB: we assume caller locking */
11932176cfdSRui Paulo 
12032176cfdSRui Paulo 	acl_free_all(vap);
12132176cfdSRui Paulo 	vap->iv_as = NULL;
12232176cfdSRui Paulo 	kfree(as, M_80211_ACL);
123841ab66cSSepherosa Ziehau }
124841ab66cSSepherosa Ziehau 
125841ab66cSSepherosa Ziehau static __inline struct acl *
126841ab66cSSepherosa Ziehau _find_acl(struct aclstate *as, const uint8_t *macaddr)
127841ab66cSSepherosa Ziehau {
128841ab66cSSepherosa Ziehau 	struct acl *acl;
129841ab66cSSepherosa Ziehau 	int hash;
130841ab66cSSepherosa Ziehau 
131841ab66cSSepherosa Ziehau 	hash = ACL_HASH(macaddr);
132841ab66cSSepherosa Ziehau 	LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
133841ab66cSSepherosa Ziehau 		if (IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr))
134841ab66cSSepherosa Ziehau 			return acl;
135841ab66cSSepherosa Ziehau 	}
136841ab66cSSepherosa Ziehau 	return NULL;
137841ab66cSSepherosa Ziehau }
138841ab66cSSepherosa Ziehau 
139841ab66cSSepherosa Ziehau static void
140841ab66cSSepherosa Ziehau _acl_free(struct aclstate *as, struct acl *acl)
141841ab66cSSepherosa Ziehau {
142841ab66cSSepherosa Ziehau 
143841ab66cSSepherosa Ziehau 	TAILQ_REMOVE(&as->as_list, acl, acl_list);
144841ab66cSSepherosa Ziehau 	LIST_REMOVE(acl, acl_hash);
145efda3bd0SMatthew Dillon 	kfree(acl, M_80211_ACL);
146841ab66cSSepherosa Ziehau 	as->as_nacls--;
147841ab66cSSepherosa Ziehau }
148841ab66cSSepherosa Ziehau 
149841ab66cSSepherosa Ziehau static int
15032176cfdSRui Paulo acl_check(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
151841ab66cSSepherosa Ziehau {
15232176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
153841ab66cSSepherosa Ziehau 
154841ab66cSSepherosa Ziehau 	switch (as->as_policy) {
155841ab66cSSepherosa Ziehau 	case ACL_POLICY_OPEN:
15632176cfdSRui Paulo 	case ACL_POLICY_RADIUS:
157841ab66cSSepherosa Ziehau 		return 1;
158841ab66cSSepherosa Ziehau 	case ACL_POLICY_ALLOW:
159841ab66cSSepherosa Ziehau 		return _find_acl(as, mac) != NULL;
160841ab66cSSepherosa Ziehau 	case ACL_POLICY_DENY:
161841ab66cSSepherosa Ziehau 		return _find_acl(as, mac) == NULL;
162841ab66cSSepherosa Ziehau 	}
163841ab66cSSepherosa Ziehau 	return 0;		/* should not happen */
164841ab66cSSepherosa Ziehau }
165841ab66cSSepherosa Ziehau 
166841ab66cSSepherosa Ziehau static int
16732176cfdSRui Paulo acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
168841ab66cSSepherosa Ziehau {
16932176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
170841ab66cSSepherosa Ziehau 	struct acl *acl, *new;
171*1e290df3SAntonio Huete Jimenez 	char ethstr[ETHER_ADDRSTRLEN + 1];
172841ab66cSSepherosa Ziehau 	int hash;
173841ab66cSSepherosa Ziehau 
174c567b546SJoe Talbott 	new = (struct acl *) kmalloc(sizeof(struct acl), M_80211_ACL, M_INTWAIT | M_ZERO);
175841ab66cSSepherosa Ziehau 	if (new == NULL) {
17632176cfdSRui Paulo 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
177*1e290df3SAntonio Huete Jimenez 		    "ACL: add %s failed, no memory\n", kether_ntoa(mac, ethstr));
178841ab66cSSepherosa Ziehau 		/* XXX statistic */
179841ab66cSSepherosa Ziehau 		return ENOMEM;
180841ab66cSSepherosa Ziehau 	}
181841ab66cSSepherosa Ziehau 
182841ab66cSSepherosa Ziehau 	hash = ACL_HASH(mac);
183841ab66cSSepherosa Ziehau 	LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
184841ab66cSSepherosa Ziehau 		if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
18532176cfdSRui Paulo 			kfree(new, M_80211_ACL);
18632176cfdSRui Paulo 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
187*1e290df3SAntonio Huete Jimenez 				"ACL: add %s failed, already present\n",
188*1e290df3SAntonio Huete Jimenez 				kether_ntoa(mac, ethstr));
189841ab66cSSepherosa Ziehau 			return EEXIST;
190841ab66cSSepherosa Ziehau 		}
191841ab66cSSepherosa Ziehau 	}
192841ab66cSSepherosa Ziehau 	IEEE80211_ADDR_COPY(new->acl_macaddr, mac);
193841ab66cSSepherosa Ziehau 	TAILQ_INSERT_TAIL(&as->as_list, new, acl_list);
194841ab66cSSepherosa Ziehau 	LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash);
195841ab66cSSepherosa Ziehau 	as->as_nacls++;
196841ab66cSSepherosa Ziehau 
19732176cfdSRui Paulo 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
198*1e290df3SAntonio Huete Jimenez 	    "ACL: add %s\n", kether_ntoa(mac, ethstr));
199841ab66cSSepherosa Ziehau 	return 0;
200841ab66cSSepherosa Ziehau }
201841ab66cSSepherosa Ziehau 
202841ab66cSSepherosa Ziehau static int
20332176cfdSRui Paulo acl_remove(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
204841ab66cSSepherosa Ziehau {
20532176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
206841ab66cSSepherosa Ziehau 	struct acl *acl;
207*1e290df3SAntonio Huete Jimenez 	char ethstr[ETHER_ADDRSTRLEN + 1];
208841ab66cSSepherosa Ziehau 
209841ab66cSSepherosa Ziehau 	acl = _find_acl(as, mac);
210841ab66cSSepherosa Ziehau 	if (acl != NULL)
211841ab66cSSepherosa Ziehau 		_acl_free(as, acl);
212841ab66cSSepherosa Ziehau 
21332176cfdSRui Paulo 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
214*1e290df3SAntonio Huete Jimenez 	    "ACL: remove %s%s\n", kether_ntoa(mac, ethstr),
215841ab66cSSepherosa Ziehau 		acl == NULL ? ", not present" : "");
216841ab66cSSepherosa Ziehau 
217841ab66cSSepherosa Ziehau 	return (acl == NULL ? ENOENT : 0);
218841ab66cSSepherosa Ziehau }
219841ab66cSSepherosa Ziehau 
220841ab66cSSepherosa Ziehau static int
22132176cfdSRui Paulo acl_free_all(struct ieee80211vap *vap)
222841ab66cSSepherosa Ziehau {
22332176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
224841ab66cSSepherosa Ziehau 	struct acl *acl;
225841ab66cSSepherosa Ziehau 
22632176cfdSRui Paulo 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, "ACL: %s\n", "free all");
227841ab66cSSepherosa Ziehau 
228841ab66cSSepherosa Ziehau 	while ((acl = TAILQ_FIRST(&as->as_list)) != NULL)
229841ab66cSSepherosa Ziehau 		_acl_free(as, acl);
230841ab66cSSepherosa Ziehau 
231841ab66cSSepherosa Ziehau 	return 0;
232841ab66cSSepherosa Ziehau }
233841ab66cSSepherosa Ziehau 
234841ab66cSSepherosa Ziehau static int
23532176cfdSRui Paulo acl_setpolicy(struct ieee80211vap *vap, int policy)
236841ab66cSSepherosa Ziehau {
23732176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
238841ab66cSSepherosa Ziehau 
23932176cfdSRui Paulo 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
240841ab66cSSepherosa Ziehau 		"ACL: set policy to %u\n", policy);
241841ab66cSSepherosa Ziehau 
242841ab66cSSepherosa Ziehau 	switch (policy) {
243841ab66cSSepherosa Ziehau 	case IEEE80211_MACCMD_POLICY_OPEN:
244841ab66cSSepherosa Ziehau 		as->as_policy = ACL_POLICY_OPEN;
245841ab66cSSepherosa Ziehau 		break;
246841ab66cSSepherosa Ziehau 	case IEEE80211_MACCMD_POLICY_ALLOW:
247841ab66cSSepherosa Ziehau 		as->as_policy = ACL_POLICY_ALLOW;
248841ab66cSSepherosa Ziehau 		break;
249841ab66cSSepherosa Ziehau 	case IEEE80211_MACCMD_POLICY_DENY:
250841ab66cSSepherosa Ziehau 		as->as_policy = ACL_POLICY_DENY;
251841ab66cSSepherosa Ziehau 		break;
25232176cfdSRui Paulo 	case IEEE80211_MACCMD_POLICY_RADIUS:
25332176cfdSRui Paulo 		as->as_policy = ACL_POLICY_RADIUS;
25432176cfdSRui Paulo 		break;
255841ab66cSSepherosa Ziehau 	default:
256841ab66cSSepherosa Ziehau 		return EINVAL;
257841ab66cSSepherosa Ziehau 	}
258841ab66cSSepherosa Ziehau 	return 0;
259841ab66cSSepherosa Ziehau }
260841ab66cSSepherosa Ziehau 
261841ab66cSSepherosa Ziehau static int
26232176cfdSRui Paulo acl_getpolicy(struct ieee80211vap *vap)
263841ab66cSSepherosa Ziehau {
26432176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
26532176cfdSRui Paulo 
26632176cfdSRui Paulo 	return as->as_policy;
267841ab66cSSepherosa Ziehau }
268841ab66cSSepherosa Ziehau 
269841ab66cSSepherosa Ziehau static int
27032176cfdSRui Paulo acl_setioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
271841ab66cSSepherosa Ziehau {
27232176cfdSRui Paulo 
273841ab66cSSepherosa Ziehau 	return EINVAL;
274841ab66cSSepherosa Ziehau }
275841ab66cSSepherosa Ziehau 
276841ab66cSSepherosa Ziehau static int
27732176cfdSRui Paulo acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
278841ab66cSSepherosa Ziehau {
27932176cfdSRui Paulo 	struct aclstate *as = vap->iv_as;
280841ab66cSSepherosa Ziehau 	struct acl *acl;
281841ab66cSSepherosa Ziehau 	struct ieee80211req_maclist *ap;
282841ab66cSSepherosa Ziehau 	int error, space, i;
283841ab66cSSepherosa Ziehau 
284841ab66cSSepherosa Ziehau 	switch (ireq->i_val) {
285841ab66cSSepherosa Ziehau 	case IEEE80211_MACCMD_POLICY:
286841ab66cSSepherosa Ziehau 		ireq->i_val = as->as_policy;
287841ab66cSSepherosa Ziehau 		return 0;
288841ab66cSSepherosa Ziehau 	case IEEE80211_MACCMD_LIST:
289841ab66cSSepherosa Ziehau 		space = as->as_nacls * IEEE80211_ADDR_LEN;
290841ab66cSSepherosa Ziehau 		if (ireq->i_len == 0) {
291841ab66cSSepherosa Ziehau 			ireq->i_len = space;	/* return required space */
292841ab66cSSepherosa Ziehau 			return 0;		/* NB: must not error */
293841ab66cSSepherosa Ziehau 		}
29432176cfdSRui Paulo 		ap = (struct ieee80211req_maclist *) kmalloc(space,
295c567b546SJoe Talbott 		    M_TEMP, M_INTWAIT);
296841ab66cSSepherosa Ziehau 		if (ap == NULL)
297841ab66cSSepherosa Ziehau 			return ENOMEM;
298841ab66cSSepherosa Ziehau 		i = 0;
299841ab66cSSepherosa Ziehau 		TAILQ_FOREACH(acl, &as->as_list, acl_list) {
300841ab66cSSepherosa Ziehau 			IEEE80211_ADDR_COPY(ap[i].ml_macaddr, acl->acl_macaddr);
301841ab66cSSepherosa Ziehau 			i++;
302841ab66cSSepherosa Ziehau 		}
303841ab66cSSepherosa Ziehau 		if (ireq->i_len >= space) {
304841ab66cSSepherosa Ziehau 			error = copyout(ap, ireq->i_data, space);
305841ab66cSSepherosa Ziehau 			ireq->i_len = space;
306841ab66cSSepherosa Ziehau 		} else
307841ab66cSSepherosa Ziehau 			error = copyout(ap, ireq->i_data, ireq->i_len);
308efda3bd0SMatthew Dillon 		kfree(ap, M_TEMP);
309841ab66cSSepherosa Ziehau 		return error;
310841ab66cSSepherosa Ziehau 	}
311841ab66cSSepherosa Ziehau 	return EINVAL;
312841ab66cSSepherosa Ziehau }
313841ab66cSSepherosa Ziehau 
314841ab66cSSepherosa Ziehau static const struct ieee80211_aclator mac = {
315841ab66cSSepherosa Ziehau 	.iac_name	= "mac",
316841ab66cSSepherosa Ziehau 	.iac_attach	= acl_attach,
317841ab66cSSepherosa Ziehau 	.iac_detach	= acl_detach,
318841ab66cSSepherosa Ziehau 	.iac_check	= acl_check,
319841ab66cSSepherosa Ziehau 	.iac_add	= acl_add,
320841ab66cSSepherosa Ziehau 	.iac_remove	= acl_remove,
321841ab66cSSepherosa Ziehau 	.iac_flush	= acl_free_all,
322841ab66cSSepherosa Ziehau 	.iac_setpolicy	= acl_setpolicy,
323841ab66cSSepherosa Ziehau 	.iac_getpolicy	= acl_getpolicy,
324841ab66cSSepherosa Ziehau 	.iac_setioctl	= acl_setioctl,
325841ab66cSSepherosa Ziehau 	.iac_getioctl	= acl_getioctl,
326841ab66cSSepherosa Ziehau };
32732176cfdSRui Paulo IEEE80211_ACL_MODULE(wlan_acl, mac, 1);
328