xref: /NextBSD/contrib/ipfilter/mli_ipl.c (revision e1dd16d965b177f109afb771e59432e36f335d0a)
1 /* $FreeBSD$ */
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  * (C)opyright 1997 by Marc Boucher.
6  *
7  * See the IPFILTER.LICENCE file for details on licencing.
8  *
9  */
10 
11 /* TODO: (MARCXXX)
12 	- ipl_init failure -> open ENODEV or whatever
13 	- prevent multiple LKM loads
14 	- surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ?
15 	- m != m1 problem
16 */
17 
18 #include <sys/types.h>
19 #include <sys/conf.h>
20 #ifdef IPFILTER_LKM
21 #include <sys/mload.h>
22 #endif
23 #include <sys/systm.h>
24 #include <sys/errno.h>
25 #include <net/if.h>
26 #include <net/route.h>
27 #include <netinet/in.h>
28 #ifdef IFF_DRVRLOCK /* IRIX6 */
29 #include <sys/hashing.h>
30 #include <netinet/in_var.h>
31 #endif
32 #include <sys/mbuf.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/ip_var.h>
36 #include <netinet/tcp.h>
37 #include <netinet/udp.h>
38 #include <netinet/tcpip.h>
39 #include <netinet/ip_icmp.h>
40 #include <netinet/ipfilter.h>
41 #include "ipl.h"
42 #include "ip_compat.h"
43 #include "ip_fil.h"
44 #include "ip_nat.h"
45 
46 #ifndef	MBUF_IS_CLUSTER
47 # define	MBUF_IS_CLUSTER(m)	((m)->m_flags & MCL_CLUSTER)
48 #endif
49 #undef	IPFDEBUG	/* #define IPFDEBUG 9 */
50 
51 #ifdef IPFILTER_LKM
52 u_int	ipldevflag = D_MP;
53 char	*iplmversion = M_VERSION;
54 #else
55 u_int	ipfilterdevflag = D_MP;
56 char	*ipfiltermversion = M_VERSION;
57 #endif
58 
59 ipfmutex_t	ipl_mutex, ipfi_mutex, ipf_rw, ipf_stinsert, ipf_auth_mx;
60 ipfmutex_t	ipf_nat_new, ipf_natio, ipf_timeoutlock;
61 ipfrwlock_t	ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
62 ipfrwlock_t	ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens;
63 
64 int     (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **));
65 
66 #ifdef IPFILTER_LKM
67 static int *ipff_addr = 0;
68 static int ipff_value;
69 static __psunsigned_t *ipfk_addr = 0;
70 static __psunsigned_t ipfk_code[4];
71 #endif
72 static void nifattach();
73 static void nifdetach();
74 
75 typedef	struct	nif	{
76 	struct	nif	*nf_next;
77 	struct ifnet	*nf_ifp;
78 #if (IRIX < 60500)
79 	int     (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *);
80 #else
81 	int     (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
82 			     struct rtentry *);
83 #endif
84 	char	nf_name[LIFNAMSIZ];
85 	int	nf_unit;
86 } nif_t;
87 
88 static nif_t *nif_head = 0;
89 static int nif_interfaces = 0;
90 extern int in_interfaces;
91 #if IRIX >= 60500
92 toid_t	ipf_timer_id;
93 #endif
94 
95 extern ipnat_t *nat_list;
96 
97 #ifdef IPFDEBUG
ipf_dumppacket(m)98 static void ipf_dumppacket(m)
99 	struct mbuf *m;
100 {
101 	u_char *s;
102 	char *t, line[80];
103 	int len, off, i;
104 
105 	off = 0;
106 
107 	while (m != NULL) {
108 		len = M_LEN(m);
109 		s = mtod(m, u_char *);
110 		printf("mbuf 0x%lx len %d flags %x type %d\n",
111 			m, len, m->m_flags, m->m_type);
112 		printf("dat 0x%lx off 0x%lx/%d s 0x%lx next 0x%lx\n",
113 			m->m_dat, m->m_off, m->m_off, s, m->m_next);
114 		while (len > 0) {
115 			t = line;
116 			for (i = 0; (i < 16) && (len > 0); len--, i++)
117 				sprintf(t, " %02x", *s++), t += strlen(t);
118 			*s = '\0';
119 			printf("mbuf:%x:%s\n", off, line);
120 			off += 16;
121 		}
122 		m = m->m_next;
123 	}
124 }
125 #endif
126 
127 
128 static int
129 #if IRIX < 60500
ipl_if_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst)130 ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
131 #else
132 ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
133 	      struct rtentry *rt)
134 #endif
135 {
136 #if (IPFDEBUG >= 0)
137 	static unsigned int cnt = 0;
138 #endif
139 	nif_t *nif;
140 
141 	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
142 	for (nif = nif_head; nif; nif = nif->nf_next)
143 		if (nif->nf_ifp == ifp)
144 			break;
145 	MUTEX_EXIT(&ipfi_mutex);
146 
147 	if (nif == NULL) {
148 		printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp);
149 		return ENETDOWN;
150 	}
151 
152 #if (IPFDEBUG >= 7)
153 	if ((++cnt % 200) == 0)
154 		printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (u_long)m->m_flags, m->m_off);
155 #endif
156 
157 	if (ipf_checkp) {
158 		struct mbuf *m1 = m;
159 		struct ip *ip;
160 		int hlen;
161 
162 		switch(m->m_type)
163 		{
164 		case MT_HEADER:
165 			if (m->m_len == 0) {
166 				if (m->m_next == NULL)
167 					break;
168 				m = m->m_next;
169 			}
170 			/* FALLTHROUGH */
171 		case MT_DATA:
172 			if (!MBUF_IS_CLUSTER(m) &&
173 			    ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
174 #if (IPFDEBUG >= 4)
175 				printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
176 #endif
177 				break;
178 			}
179 			if (m->m_len < sizeof(char)) {
180 #if (IPFDEBUG >= 3)
181 				printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags);
182 #endif
183 				break;
184 			}
185 			ip = mtod(m, struct ip *);
186 			if (ip->ip_v != IPVERSION) {
187 #if (IPFDEBUG >= 2)
188 				ipf_dumppacket(m);
189 				printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
190 #endif
191 				break;
192 			}
193 
194 			hlen = ip->ip_hl << 2;
195 			if ((*ipf_checkp)(ip, hlen, ifp, 1, &m1) || (m1 == NULL))
196 				return EHOSTUNREACH;
197 
198 			m = m1;
199 			break;
200 
201 		default:
202 #if (IPFDEBUG >= 2)
203 			printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
204 #endif
205 			break;
206 		}
207 	}
208 #if (IRIX < 60500)
209 	return (*nif->nf_output)(ifp, m, dst);
210 #else
211 	return (*nif->nf_output)(ifp, m, dst, rt);
212 #endif
213 }
214 
215 int
216 
217 
218 #if !defined(IPFILTER_LKM) && (IRIX >= 60500)
ipfilter_kernel(struct ifnet * rcvif,struct mbuf * m)219 ipfilter_kernel(struct ifnet *rcvif, struct mbuf *m)
220 #else
221 ipl_kernel(struct ifnet *rcvif, struct mbuf *m)
222 #endif
223 {
224 #if (IPFDEBUG >= 7)
225 	static unsigned int cnt = 0;
226 
227 	if ((++cnt % 200) == 0)
228 		printf("IP Filter: ipl_kernel(rcvif=0x%lx, m=0x%lx\n",
229 			rcvif, m);
230 #endif
231 
232 	if (ipf_running <= 0)
233 		return IPF_ACCEPTIT;
234 
235 	/*
236 	 * Check if we want to allow this packet to be processed.
237 	 * Consider it to be bad if not.
238 	 */
239 	if (ipf_checkp) {
240 		struct mbuf *m1 = m;
241 		struct ip *ip;
242 		int hlen;
243 
244 		if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) {
245 #if (IPFDEBUG >= 4)
246 			printf("IP Filter: ipl_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
247 #endif
248 			return IPF_ACCEPTIT;
249 		}
250 
251 		if (!MBUF_IS_CLUSTER(m) &&
252 		    ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
253 #if (IPFDEBUG >= 4)
254 			printf("IP Filter: ipl_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
255 #endif
256 			return IPF_ACCEPTIT;
257 		}
258 
259 		if (m->m_len < sizeof(char)) {
260 #if (IPFDEBUG >= 1)
261 			printf("IP Filter: ipl_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags);
262 #endif
263 			return IPF_ACCEPTIT;
264 		}
265 
266 		ip = mtod(m, struct ip *);
267 		if (ip->ip_v != IPVERSION) {
268 #if (IPFDEBUG >= 4)
269 			printf("IP Filter: ipl_kernel: bad ip_v\n");
270 #endif
271 			m_freem(m);
272 			return IPF_DROPIT;
273 		}
274 
275 		ip->ip_len = htons(ip->ip_len);
276 		ip->ip_off = htons(ip->ip_off);
277 		hlen = ip->ip_hl << 2;
278 		if ((*ipf_checkp)(ip, hlen, rcvif, 0, &m1) || !m1)
279 			return IPF_DROPIT;
280 		ip = mtod(m1, struct ip *);
281 		ip->ip_len = ntohs(ip->ip_len);
282 		ip->ip_off = ntohs(ip->ip_off);
283 
284 #if (IPFDEBUG >= 2)
285 		if (m != m1)
286 			printf("IP Filter: ipl_kernel: m != m1\n");
287 #endif
288 	}
289 
290 	return IPF_ACCEPTIT;
291 }
292 
293 int
ipl_ipfilter_attach(void)294 ipl_ipfilter_attach(void)
295 {
296 #if defined(IPFILTER_LKM)
297 	__psunsigned_t *addr_ff, *addr_fk;
298 
299 	st_findaddr("ipfilterflag", &addr_ff);
300 # if (IPFDEBUG >= 1)
301 	printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff);
302 # endif
303 	if (!addr_ff)
304 		return ESRCH;
305 
306 	st_findaddr("ipfilter_kernel", &addr_fk);
307 # if (IPFDEBUG >= 1)
308 	printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk);
309 # endif
310 	if (!addr_fk)
311 		return ESRCH;
312 
313 	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
314 
315 	ipff_addr = (int *)addr_ff;
316 
317 	ipff_value = *ipff_addr;
318 	*ipff_addr = 0;
319 
320 
321 	ipfk_addr = addr_fk;
322 
323 	bcopy(ipfk_addr, ipfk_code, sizeof(ipfk_code));
324 
325 	/* write a "li t4, ipl_kernel" instruction */
326 	ipfk_addr[0] = 0x3c0c0000 |
327 		       (((__psunsigned_t)ipl_kernel >> 16) & 0xffff);
328 	ipfk_addr[1] = 0x358c0000 |
329 		       ((__psunsigned_t)ipl_kernel & 0xffff);
330 	/* write a "jr t4" instruction" */
331 	ipfk_addr[2] = 0x01800008;
332 
333 	/* write a "nop" instruction */
334 	ipfk_addr[3] = 0;
335 
336 	icache_inval(ipfk_addr, sizeof(ipfk_code));
337 
338 	*ipff_addr = 1; /* enable ipfilter_kernel */
339 
340 	MUTEX_EXIT(&ipfi_mutex);
341 #else
342 	extern int ipfilterflag;
343 
344 	ipfilterflag = 1;
345 #endif
346 	nif_interfaces = 0;
347 	nifattach();
348 
349 	return 0;
350 }
351 
352 
353 /*
354  * attach the packet filter to each non-loopback interface that is running
355  */
356 static void
nifattach()357 nifattach()
358 {
359 	nif_t *nif, *qf2;
360 	struct ifnet *ifp;
361 	struct frentry *f;
362 	ipnat_t *np;
363 
364 	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
365 
366 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
367 		if ((!(ifp->if_flags & IFF_RUNNING)) ||
368 			(ifp->if_flags & IFF_LOOPBACK))
369 			continue;
370 
371 		/*
372 		 * Look for entry already setup for this device
373 		 */
374 		for (nif = nif_head; nif; nif = nif->nf_next)
375 			if (nif->nf_ifp == ifp)
376 				break;
377 		if (nif)
378 			continue;
379 
380 		if (ifp->if_output == ipl_if_output) {
381 			printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n",
382 				ifp);
383 			continue;
384 		}
385 #if (IPFDEBUG >= 2)
386 		printf("IP Filter: nifattach nif %x opt %x\n",
387 		       ifp, ifp->if_output);
388 #endif
389 		KMALLOC(nif, nif_t *);
390 		if (!nif) {
391 			printf("IP Filter: malloc(%d) for nif_t failed\n",
392 			       sizeof(nif_t));
393 			continue;
394 		}
395 
396 		nif->nf_ifp = ifp;
397 		(void) strncpy(nif->nf_name, ifp->if_name,
398 			       sizeof(nif->nf_name));
399 		nif->nf_name[sizeof(nif->nf_name) - 1] = '\0';
400 		nif->nf_unit = ifp->if_unit;
401 
402 		nif->nf_next = nif_head;
403 		nif_head = nif;
404 
405 		/*
406 		 * Activate any rules directly associated with this interface
407 		 */
408 		WRITE_ENTER(&ipf_mutex);
409 		for (f = ipf_rules[0][0]; f; f = f->fr_next) {
410 			if ((f->fr_ifa == (struct ifnet *)-1)) {
411 				if (f->fr_ifname[0] &&
412 				    (GETIFP(f->fr_ifname, 4) == ifp))
413 					f->fr_ifa = ifp;
414 			}
415 		}
416 		for (f = ipf_rules[1][0]; f; f = f->fr_next) {
417 			if ((f->fr_ifa == (struct ifnet *)-1)) {
418 				if (f->fr_ifname[0] &&
419 				    (GETIFP(f->fr_ifname, 4) == ifp))
420 					f->fr_ifa = ifp;
421 			}
422 		}
423 		RWLOCK_EXIT(&ipf_mutex);
424 		WRITE_ENTER(&ipf_nat);
425 		for (np = nat_list; np; np = np->in_next) {
426 			if ((np->in_ifps[0] == (void *)-1)) {
427 				if (np->in_ifnames[0][0] &&
428 				    (GETIFP(np->in_ifnames[0], 4) == ifp))
429 					np->in_ifps[0] = (void *)ifp;
430 			}
431 			if ((np->in_ifps[1] == (void *)-1)) {
432 				if (np->in_ifnames[1][0] &&
433 				    (GETIFP(np->in_ifnames[1], 4) == ifp))
434 					np->in_ifps[1] = (void *)ifp;
435 			}
436 		}
437 		RWLOCK_EXIT(&ipf_nat);
438 
439 		nif->nf_output = ifp->if_output;
440 		ifp->if_output = ipl_if_output;
441 
442 #if (IPFDEBUG >= 2)
443 		printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n",
444 			ifp, nif->nf_output, ifp->if_output);
445 #endif
446 
447 		printf("IP Filter: attach to [%s,%d]\n",
448 			nif->nf_name, ifp->if_unit);
449 	}
450 	if (!nif_head)
451 		printf("IP Filter: not attached to any interfaces\n");
452 
453 	nif_interfaces = in_interfaces;
454 
455 	MUTEX_EXIT(&ipfi_mutex);
456 
457 	return;
458 }
459 
460 
461 /*
462  * unhook the IP filter from all defined interfaces with IP addresses
463  */
464 static void
nifdetach()465 nifdetach()
466 {
467 	nif_t *nif, *qf2, **qp;
468 	struct ifnet *ifp;
469 
470 	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
471 	/*
472 	 * Make two passes, first get rid of all the unknown devices, next
473 	 * unlink known devices.
474 	 */
475 	for (qp = &nif_head; (nif = *qp); ) {
476 		for (ifp = ifnet; ifp; ifp = ifp->if_next)
477 			if (nif->nf_ifp == ifp)
478 				break;
479 		if (ifp) {
480 			qp = &nif->nf_next;
481 			continue;
482 		}
483 		printf("IP Filter: removing [%s]\n", nif->nf_name);
484 		*qp = nif->nf_next;
485 		KFREE(nif);
486 	}
487 
488 	while ((nif = nif_head)) {
489 		nif_head = nif->nf_next;
490 		for (ifp = ifnet; ifp; ifp = ifp->if_next)
491 			if (nif->nf_ifp == ifp)
492 				break;
493 		if (ifp) {
494 			printf("IP Filter: detaching [%s,%d]\n",
495 				nif->nf_name, ifp->if_unit);
496 
497 #if (IPFDEBUG >= 4)
498 			printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n",
499 				ifp, ifp->if_output, nif->nf_output);
500 #endif
501 			ifp->if_output = nif->nf_output;
502 		}
503 		KFREE(nif);
504 	}
505 	MUTEX_EXIT(&ipfi_mutex);
506 
507 	return;
508 }
509 
510 
511 void
ipl_ipfilter_detach(void)512 ipl_ipfilter_detach(void)
513 {
514 #ifdef IPFILTER_LKM
515 	nifdetach();
516 	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
517 
518 	if (ipff_addr) {
519 		*ipff_addr = 0;
520 
521 		if (ipfk_addr) {
522 			bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code));
523 			icache_inval(ipfk_addr - 16, sizeof(ipfk_code)+32);
524 		}
525 
526 		*ipff_addr = ipff_value;
527 	}
528 
529 	MUTEX_EXIT(&ipfi_mutex);
530 #else
531 	extern int ipfilterflag;
532 
533 	nifdetach();
534 
535 	ipfilterflag = 0;
536 #endif
537 }
538 
539 
540 /* this function is called from ipf_slowtimer at 500ms intervals to
541    keep our interface list in sync */
542 void
ipl_ipfilter_intfsync(void)543 ipl_ipfilter_intfsync(void)
544 {
545 	MUTEX_ENTER(&ipfi_mutex);
546 	if (nif_interfaces != in_interfaces) {
547 		/* if the number of interfaces has changed, resync */
548 		MUTEX_EXIT(&ipfi_mutex);
549 		ipf_sync(&ipfmain, NULL);
550 	} else
551 		MUTEX_EXIT(&ipfi_mutex);
552 }
553 
554 #ifdef IPFILTER_LKM
555 /* this routine should be treated as an interrupt routine and should
556    not call any routines that would cause it to sleep, such as: biowait(),
557    sleep(), psema() or delay().
558 */
559 int
iplunload(void)560 iplunload(void)
561 {
562 	int error = 0;
563 
564 	if (ipf_refcnt)
565 		return EBUSY;
566 
567 	WRITE_ENTER(&ipf_global);
568 	error = ipl_detach();
569 	if (error != 0) {
570 		RWLOCK_EXIT(&ipf_global);
571 		return error;
572 	}
573 	ipf_running = -2;
574 
575 #if (IRIX < 60500)
576 	LOCK_DEALLOC(ipl_mutex.l);
577 	LOCK_DEALLOC(ipf_rw.l);
578 	LOCK_DEALLOC(ipf_auth.l);
579 	LOCK_DEALLOC(ipf_natfrag.l);
580 	LOCK_DEALLOC(ipf_ipidfrag.l);
581 	LOCK_DEALLOC(ipf_tokens.l);
582 	LOCK_DEALLOC(ipf_stinsert.l);
583 	LOCK_DEALLOC(ipf_nat_new.l);
584 	LOCK_DEALLOC(ipf_natio.l);
585 	LOCK_DEALLOC(ipf_nat.l);
586 	LOCK_DEALLOC(ipf_state.l);
587 	LOCK_DEALLOC(ipf_frag.l);
588 	LOCK_DEALLOC(ipf_auth_mx.l);
589 	LOCK_DEALLOC(ipf_mutex.l);
590 	LOCK_DEALLOC(ipf_frcache.l);
591 	LOCK_DEALLOC(ipfi_mutex.l);
592 	RWLOCK_EXIT(&ipf_global);
593 	LOCK_DEALLOC(ipf_global.l);
594 #else
595 	MUTEX_DESTROY(&ipf_rw);
596 	MUTEX_DESTROY(&ipfi_mutex);
597 	MUTEX_DESTROY(&ipf_timeoutlock);
598 	RW_DESTROY(&ipf_mutex);
599 	RW_DESTROY(&ipf_frcache);
600 	RW_DESTROY(&ipf_tokens);
601 	RWLOCK_EXIT(&ipf_global);
602 	delay(hz);
603 	RW_DESTROY(&ipf_global);
604 #endif
605 
606 	printf("%s unloaded\n", ipfilter_version);
607 
608 	delay(hz);
609 
610 	return 0;
611 }
612 #endif
613 
614 void
ipfilterinit(void)615 ipfilterinit(void)
616 {
617 #ifdef IPFILTER_LKM
618 	int error;
619 #endif
620 
621 #if (IRIX < 60500)
622 	ipfi_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
623 ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
624 ipf_frcache.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
625 ipf_timeoutlock.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
626 	ipf_global.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
627 	ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
628 	ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
629 	ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
630 	ipf_stinsert.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
631 	ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
632 	ipf_ipidfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
633 	ipf_tokens.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
634 	ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
635 	ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
636 	ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
637 
638 	if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_timeoutlock.l ||
639 	    !ipf_frag.l || !ipf_state.l || !ipf_nat.l || !ipf_natfrag.l ||
640 	    !ipf_auth.l || !ipf_rw.l || !ipf_ipidfrag.l || !ipl_mutex.l ||
641 	    !ipf_stinsert.l || !ipf_auth_mx.l || !ipf_frcache.l ||
642 	    !ipf_tokens.l)
643 		panic("IP Filter: LOCK_ALLOC failed");
644 #else
645 	MUTEX_INIT(&ipf_rw, "ipf rw mutex");
646 	MUTEX_INIT(&ipf_timeoutlock, "ipf timeout mutex");
647 	RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
648 	RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
649 	RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
650 #endif
651 
652 #ifdef IPFILTER_LKM
653 	error = ipl_attach();
654 	if (error) {
655 		iplunload();
656 	} else {
657 		char *defpass;
658 
659 		if (FR_ISPASS(ipf_pass))
660 			defpass = "pass";
661 		else if (FR_ISBLOCK(ipf_pass))
662 			defpass = "block";
663 		else
664 			defpass = "no-match -> block";
665 
666 		printf("%s initialized.  Default = %s all, Logging = %s%s\n",
667 			ipfilter_version, defpass,
668 # ifdef  IPFILTER_LOG
669 			"enabled",
670 # else
671 			"disabled",
672 # endif
673 # ifdef IPFILTER_COMPILED
674 		" (COMPILED)"
675 # else
676 		""
677 # endif
678 		);
679 	}
680 #endif
681 
682 	return;
683 }
684