mli_ipl.c revision 259128
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
52u_int	ipldevflag = D_MP;
53char	*iplmversion = M_VERSION;
54#else
55u_int	ipfilterdevflag = D_MP;
56char	*ipfiltermversion = M_VERSION;
57#endif
58
59ipfmutex_t	ipl_mutex, ipfi_mutex, ipf_rw, ipf_stinsert, ipf_auth_mx;
60ipfmutex_t	ipf_nat_new, ipf_natio, ipf_timeoutlock;
61ipfrwlock_t	ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
62ipfrwlock_t	ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens;
63
64int     (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **));
65
66#ifdef IPFILTER_LKM
67static int *ipff_addr = 0;
68static int ipff_value;
69static __psunsigned_t *ipfk_addr = 0;
70static __psunsigned_t ipfk_code[4];
71#endif
72static void nifattach();
73static void nifdetach();
74
75typedef	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
88static nif_t *nif_head = 0;
89static int nif_interfaces = 0;
90extern int in_interfaces;
91#if IRIX >= 60500
92toid_t	ipf_timer_id;
93#endif
94
95extern ipnat_t *nat_list;
96
97#ifdef IPFDEBUG
98static 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
128static int
129#if IRIX < 60500
130ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
131#else
132ipl_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
215int
216
217
218#if !defined(IPFILTER_LKM) && (IRIX >= 60500)
219ipfilter_kernel(struct ifnet *rcvif, struct mbuf *m)
220#else
221ipl_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
293int
294ipl_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 */
356static void
357nifattach()
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 */
464static void
465nifdetach()
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
511void
512ipl_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 */
542void
543ipl_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*/
559int
560iplunload(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
614void
615ipfilterinit(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);
623ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
624ipf_frcache.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
625ipf_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