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