1 /* $FreeBSD$ */ 2 3 /* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * $FreeBSD$ 7 * See the IPFILTER.LICENCE file for details on licencing. 8 */ 9 10 #if defined(KERNEL) || defined(_KERNEL) 11 # undef KERNEL 12 # undef _KERNEL 13 # define KERNEL 1 14 # define _KERNEL 1 15 #endif 16 17 #include <sys/param.h> 18 #include <sys/systm.h> 19 #include <sys/kernel.h> 20 #include <sys/module.h> 21 #include <sys/conf.h> 22 #include <sys/socket.h> 23 #include <sys/sysctl.h> 24 #include <sys/select.h> 25 #ifdef __FreeBSD__ 26 # include <sys/selinfo.h> 27 # include <sys/jail.h> 28 # ifdef _KERNEL 29 # include <net/vnet.h> 30 # else 31 # define CURVNET_SET(arg) 32 # define CURVNET_RESTORE() 33 # define VNET_DEFINE(_t, _v) _t _v 34 # define VNET_DECLARE(_t, _v) extern _t _v 35 # define VNET(arg) arg 36 # endif 37 #endif 38 #include <net/if.h> 39 #include <netinet/in_systm.h> 40 #include <netinet/in.h> 41 42 43 #include "netinet/ipl.h" 44 #include "netinet/ip_compat.h" 45 #include "netinet/ip_fil.h" 46 #include "netinet/ip_state.h" 47 #include "netinet/ip_nat.h" 48 #include "netinet/ip_auth.h" 49 #include "netinet/ip_frag.h" 50 #include "netinet/ip_sync.h" 51 52 VNET_DECLARE(ipf_main_softc_t, ipfmain); 53 #define V_ipfmain VNET(ipfmain) 54 55 #ifdef __FreeBSD__ 56 static struct cdev *ipf_devs[IPL_LOGSIZE]; 57 #else 58 static dev_t ipf_devs[IPL_LOGSIZE]; 59 #endif 60 61 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); 62 static int sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS ); 63 static int sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS ); 64 static int sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS ); 65 static int sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS ); 66 static int ipf_modload(void); 67 static int ipf_modunload(void); 68 static int ipf_fbsd_sysctl_create(void); 69 static int ipf_fbsd_sysctl_destroy(void); 70 71 #ifdef __FreeBSD__ 72 static int ipfopen(struct cdev*, int, int, struct thread *); 73 static int ipfclose(struct cdev*, int, int, struct thread *); 74 static int ipfread(struct cdev*, struct uio *, int); 75 static int ipfwrite(struct cdev*, struct uio *, int); 76 #else 77 static int ipfopen(dev_t, int, int, struct proc *); 78 static int ipfclose(dev_t, int, int, struct proc *); 79 static int ipfread(dev_t, struct uio *, int); 80 static int ipfwrite(dev_t, struct uio *, int); 81 #endif 82 83 #ifdef LARGE_NAT 84 #define IPF_LARGE_NAT 1 85 #else 86 #define IPF_LARGE_NAT 0 87 #endif 88 89 SYSCTL_DECL(_net_inet); 90 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ 91 SYSCTL_OID(parent, nbr, name, \ 92 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \ 93 ptr, val, sysctl_ipf_int, "I", descr) 94 #define SYSCTL_DYN_IPF_NAT(parent, nbr, name, access,ptr, val, descr) \ 95 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \ 96 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE |access, \ 97 ptr, val, sysctl_ipf_int_nat, "I", descr) 98 #define SYSCTL_DYN_IPF_STATE(parent, nbr, name, access,ptr, val, descr) \ 99 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \ 100 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \ 101 ptr, val, sysctl_ipf_int_state, "I", descr) 102 #define SYSCTL_DYN_IPF_FRAG(parent, nbr, name, access,ptr, val, descr) \ 103 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \ 104 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \ 105 ptr, val, sysctl_ipf_int_frag, "I", descr) 106 #define SYSCTL_DYN_IPF_AUTH(parent, nbr, name, access,ptr, val, descr) \ 107 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \ 108 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \ 109 ptr, val, sysctl_ipf_int_auth, "I", descr) 110 static struct sysctl_ctx_list ipf_clist; 111 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ 112 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) 113 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 114 "IPF"); 115 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_flags), 0, "IPF flags"); 116 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_pass), 0, "default pass/block"); 117 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_active), 0, "IPF is active"); 118 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, 119 &VNET_NAME(ipfmain.ipf_tcpidletimeout), 0, "TCP idle timeout in seconds"); 120 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, 121 &VNET_NAME(ipfmain.ipf_tcphalfclosed), 0, "timeout for half closed TCP sessions"); 122 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, 123 &VNET_NAME(ipfmain.ipf_tcpclosewait), 0, "timeout for TCP sessions in closewait status"); 124 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, 125 &VNET_NAME(ipfmain.ipf_tcplastack), 0, "timeout for TCP sessions in last ack status"); 126 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, 127 &VNET_NAME(ipfmain.ipf_tcptimeout), 0, ""); 128 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, 129 &VNET_NAME(ipfmain.ipf_tcpclosed), 0, ""); 130 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, 131 &VNET_NAME(ipfmain.ipf_udptimeout), 0, "UDP timeout"); 132 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, 133 &VNET_NAME(ipfmain.ipf_udpacktimeout), 0, ""); 134 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, 135 &VNET_NAME(ipfmain.ipf_icmptimeout), 0, "ICMP timeout"); 136 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, 137 &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running"); 138 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, ""); 139 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, ""); 140 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, large_nat, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_large_nat), 0, "large_nat"); 141 142 #define CDEV_MAJOR 79 143 #include <sys/poll.h> 144 #ifdef __FreeBSD__ 145 # include <sys/select.h> 146 static int ipfpoll(struct cdev *dev, int events, struct thread *td); 147 148 static struct cdevsw ipf_cdevsw = { 149 .d_version = D_VERSION, 150 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ 151 .d_open = ipfopen, 152 .d_close = ipfclose, 153 .d_read = ipfread, 154 .d_write = ipfwrite, 155 .d_ioctl = ipfioctl, 156 .d_poll = ipfpoll, 157 .d_name = "ipf", 158 }; 159 #else 160 static int ipfpoll(dev_t dev, int events, struct proc *td); 161 162 static struct cdevsw ipf_cdevsw = { 163 /* open */ ipfopen, 164 /* close */ ipfclose, 165 /* read */ ipfread, 166 /* write */ ipfwrite, 167 /* ioctl */ ipfioctl, 168 /* poll */ ipfpoll, 169 /* mmap */ nommap, 170 /* strategy */ nostrategy, 171 /* name */ "ipf", 172 /* maj */ CDEV_MAJOR, 173 /* dump */ nodump, 174 /* psize */ nopsize, 175 /* flags */ 0, 176 }; 177 #endif 178 179 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, 180 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; 181 182 static int 183 ipfilter_modevent(module_t mod, int type, void *unused) 184 { 185 int error = 0; 186 187 switch (type) 188 { 189 case MOD_LOAD : 190 error = ipf_modload(); 191 break; 192 193 case MOD_UNLOAD : 194 error = ipf_modunload(); 195 break; 196 default: 197 error = EINVAL; 198 break; 199 } 200 return (error); 201 } 202 203 204 static void 205 vnet_ipf_init(void) 206 { 207 char *defpass; 208 int error; 209 210 if (ipf_create_all(&V_ipfmain) == NULL) 211 return; 212 213 error = ipfattach(&V_ipfmain); 214 if (error) { 215 ipf_destroy_all(&V_ipfmain); 216 return; 217 } 218 219 if (FR_ISPASS(V_ipfmain.ipf_pass)) 220 defpass = "pass"; 221 else if (FR_ISBLOCK(V_ipfmain.ipf_pass)) 222 defpass = "block"; 223 else 224 defpass = "no-match -> block"; 225 226 if (IS_DEFAULT_VNET(curvnet)) { 227 printf("%s initialized. Default = %s all, Logging = %s%s\n", 228 ipfilter_version, defpass, 229 #ifdef IPFILTER_LOG 230 "enabled", 231 #else 232 "disabled", 233 #endif 234 #ifdef IPFILTER_COMPILED 235 " (COMPILED)" 236 #else 237 "" 238 #endif 239 ); 240 } else { 241 (void)ipf_pfil_hook(); 242 ipf_event_reg(); 243 } 244 } 245 VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 246 vnet_ipf_init, NULL); 247 248 static int 249 ipf_modload(void) 250 { 251 char *c, *str; 252 int i, j, error; 253 254 if (ipf_load_all() != 0) 255 return (EIO); 256 257 if (ipf_fbsd_sysctl_create() != 0) { 258 return (EIO); 259 } 260 261 for (i = 0; i < IPL_LOGSIZE; i++) 262 ipf_devs[i] = NULL; 263 for (i = 0; (str = ipf_devfiles[i]); i++) { 264 c = NULL; 265 for(j = strlen(str); j > 0; j--) 266 if (str[j] == '/') { 267 c = str + j + 1; 268 break; 269 } 270 if (!c) 271 c = str; 272 ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c); 273 } 274 275 error = ipf_pfil_hook(); 276 if (error != 0) 277 return (error); 278 ipf_event_reg(); 279 280 return (0); 281 } 282 283 static void 284 vnet_ipf_uninit(void) 285 { 286 287 if (V_ipfmain.ipf_refcnt) 288 return; 289 290 if (V_ipfmain.ipf_running >= 0) { 291 292 if (ipfdetach(&V_ipfmain) != 0) 293 return; 294 295 V_ipfmain.ipf_running = -2; 296 297 ipf_destroy_all(&V_ipfmain); 298 if (!IS_DEFAULT_VNET(curvnet)) { 299 ipf_event_dereg(); 300 (void)ipf_pfil_unhook(); 301 } 302 } 303 } 304 VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 305 vnet_ipf_uninit, NULL); 306 307 static int 308 ipf_modunload(void) 309 { 310 int error, i; 311 312 ipf_event_dereg(); 313 314 ipf_fbsd_sysctl_destroy(); 315 316 error = ipf_pfil_unhook(); 317 if (error != 0) 318 return (error); 319 320 for (i = 0; ipf_devfiles[i]; i++) { 321 if (ipf_devs[i] != NULL) 322 destroy_dev(ipf_devs[i]); 323 } 324 325 ipf_unload_all(); 326 327 printf("%s unloaded\n", ipfilter_version); 328 329 return (0); 330 } 331 332 333 static moduledata_t ipfiltermod = { 334 "ipfilter", 335 ipfilter_modevent, 336 0 337 }; 338 339 340 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND); 341 #ifdef MODULE_VERSION 342 MODULE_VERSION(ipfilter, 1); 343 #endif 344 345 346 #ifdef SYSCTL_IPF 347 int 348 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) 349 { 350 int error = 0; 351 352 if (arg1) 353 error = SYSCTL_OUT(req, arg1, sizeof(int)); 354 else 355 error = SYSCTL_OUT(req, &arg2, sizeof(int)); 356 357 if (error || !req->newptr) 358 goto sysctl_error; 359 360 if (!arg1) 361 error = EPERM; 362 else { 363 if ((oidp->oid_kind & CTLFLAG_OFF) && (V_ipfmain.ipf_running > 0)) 364 error = EBUSY; 365 else 366 error = SYSCTL_IN(req, arg1, sizeof(int)); 367 } 368 369 sysctl_error: 370 return (error); 371 } 372 373 /* 374 * arg2 holds the offset of the relevant member in the virtualized 375 * ipfmain structure. 376 */ 377 static int 378 sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS ) 379 { 380 if (jailed_without_vnet(curthread->td_ucred)) 381 return (0); 382 383 ipf_nat_softc_t *nat_softc; 384 385 nat_softc = V_ipfmain.ipf_nat_soft; 386 arg1 = (void *)((uintptr_t)nat_softc + (size_t)arg2); 387 388 return (sysctl_ipf_int(oidp, arg1, 0, req)); 389 } 390 391 static int 392 sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS ) 393 { 394 if (jailed_without_vnet(curthread->td_ucred)) 395 return (0); 396 397 ipf_state_softc_t *state_softc; 398 399 state_softc = V_ipfmain.ipf_state_soft; 400 arg1 = (void *)((uintptr_t)state_softc + (size_t)arg2); 401 402 return (sysctl_ipf_int(oidp, arg1, 0, req)); 403 } 404 405 static int 406 sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS ) 407 { 408 if (jailed_without_vnet(curthread->td_ucred)) 409 return (0); 410 411 ipf_auth_softc_t *auth_softc; 412 413 auth_softc = V_ipfmain.ipf_auth_soft; 414 arg1 = (void *)((uintptr_t)auth_softc + (size_t)arg2); 415 416 return (sysctl_ipf_int(oidp, arg1, 0, req)); 417 } 418 419 static int 420 sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS ) 421 { 422 if (jailed_without_vnet(curthread->td_ucred)) 423 return (0); 424 425 ipf_frag_softc_t *frag_softc; 426 427 frag_softc = V_ipfmain.ipf_frag_soft; 428 arg1 = (void *)((uintptr_t)frag_softc + (size_t)arg2); 429 430 return (sysctl_ipf_int(oidp, arg1, 0, req)); 431 } 432 #endif 433 434 435 static int 436 #ifdef __FreeBSD__ 437 ipfpoll(struct cdev *dev, int events, struct thread *td) 438 #else 439 ipfpoll(dev_t dev, int events, struct proc *td) 440 #endif 441 { 442 int unit = GET_MINOR(dev); 443 int revents; 444 445 if (unit < 0 || unit > IPL_LOGMAX) 446 return (0); 447 448 revents = 0; 449 450 CURVNET_SET(TD_TO_VNET(td)); 451 switch (unit) 452 { 453 case IPL_LOGIPF : 454 case IPL_LOGNAT : 455 case IPL_LOGSTATE : 456 #ifdef IPFILTER_LOG 457 if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit)) 458 revents |= events & (POLLIN | POLLRDNORM); 459 #endif 460 break; 461 case IPL_LOGAUTH : 462 if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain)) 463 revents |= events & (POLLIN | POLLRDNORM); 464 break; 465 case IPL_LOGSYNC : 466 if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain)) 467 revents |= events & (POLLIN | POLLRDNORM); 468 if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain)) 469 revents |= events & (POLLOUT | POLLWRNORM); 470 break; 471 case IPL_LOGSCAN : 472 case IPL_LOGLOOKUP : 473 default : 474 break; 475 } 476 477 if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) 478 selrecord(td, &V_ipfmain.ipf_selwait[unit]); 479 CURVNET_RESTORE(); 480 481 return (revents); 482 } 483 484 485 /* 486 * routines below for saving IP headers to buffer 487 */ 488 static int 489 #ifdef __FreeBSD__ 490 ipfopen(struct cdev *dev, int flags, int devtype, struct thread *p) 491 #else 492 ipfopen(dev_t dev, int flags) 493 #endif 494 { 495 int unit = GET_MINOR(dev); 496 int error; 497 498 if (IPL_LOGMAX < unit) 499 error = ENXIO; 500 else { 501 switch (unit) 502 { 503 case IPL_LOGIPF : 504 case IPL_LOGNAT : 505 case IPL_LOGSTATE : 506 case IPL_LOGAUTH : 507 case IPL_LOGLOOKUP : 508 case IPL_LOGSYNC : 509 #ifdef IPFILTER_SCAN 510 case IPL_LOGSCAN : 511 #endif 512 error = 0; 513 break; 514 default : 515 error = ENXIO; 516 break; 517 } 518 } 519 return (error); 520 } 521 522 523 static int 524 #ifdef __FreeBSD__ 525 ipfclose(struct cdev *dev, int flags, int devtype, struct thread *p) 526 #else 527 ipfclose(dev_t dev, int flags) 528 #endif 529 { 530 int unit = GET_MINOR(dev); 531 532 if (IPL_LOGMAX < unit) 533 unit = ENXIO; 534 else 535 unit = 0; 536 return (unit); 537 } 538 539 /* 540 * ipfread/ipflog 541 * both of these must operate with at least splnet() lest they be 542 * called during packet processing and cause an inconsistancy to appear in 543 * the filter lists. 544 */ 545 #ifdef __FreeBSD__ 546 static int ipfread(struct cdev *dev, struct uio *uio, int ioflag) 547 #else 548 static int ipfread(dev, uio, ioflag) 549 int ioflag; 550 dev_t dev; 551 struct uio *uio; 552 #endif 553 { 554 int error; 555 int unit = GET_MINOR(dev); 556 557 if (unit < 0) 558 return (ENXIO); 559 560 CURVNET_SET(TD_TO_VNET(curthread)); 561 if (V_ipfmain.ipf_running < 1) { 562 CURVNET_RESTORE(); 563 return (EIO); 564 } 565 566 if (unit == IPL_LOGSYNC) { 567 error = ipf_sync_read(&V_ipfmain, uio); 568 CURVNET_RESTORE(); 569 return (error); 570 } 571 572 #ifdef IPFILTER_LOG 573 error = ipf_log_read(&V_ipfmain, unit, uio); 574 #else 575 error = ENXIO; 576 #endif 577 CURVNET_RESTORE(); 578 return (error); 579 } 580 581 582 /* 583 * ipfwrite 584 * both of these must operate with at least splnet() lest they be 585 * called during packet processing and cause an inconsistancy to appear in 586 * the filter lists. 587 */ 588 #ifdef __FreeBSD__ 589 static int ipfwrite(struct cdev *dev, struct uio *uio, int ioflag) 590 #else 591 static int ipfwrite(dev, uio, ioflag) 592 int ioflag; 593 dev_t dev; 594 struct uio *uio; 595 #endif 596 { 597 int error; 598 599 CURVNET_SET(TD_TO_VNET(curthread)); 600 if (V_ipfmain.ipf_running < 1) { 601 CURVNET_RESTORE(); 602 return (EIO); 603 } 604 605 if (GET_MINOR(dev) == IPL_LOGSYNC) { 606 error = ipf_sync_write(&V_ipfmain, uio); 607 CURVNET_RESTORE(); 608 return (error); 609 } 610 return (ENXIO); 611 } 612 613 static int 614 ipf_fbsd_sysctl_create(void) 615 { 616 617 sysctl_ctx_init(&ipf_clist); 618 619 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "fr_defnatage", CTLFLAG_RWO, 620 NULL, offsetof(ipf_nat_softc_t, ipf_nat_defage), ""); 621 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statesize", CTLFLAG_RWO, 622 NULL, offsetof(ipf_state_softc_t, ipf_state_size), ""); 623 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statemax", CTLFLAG_RWO, 624 NULL, offsetof(ipf_state_softc_t, ipf_state_max), ""); 625 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_max", CTLFLAG_RWO, 626 NULL, offsetof(ipf_nat_softc_t, ipf_nat_table_max), ""); 627 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_sz", CTLFLAG_RWO, 628 NULL, offsetof(ipf_nat_softc_t, ipf_nat_table_sz), ""); 629 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_natrules_sz", CTLFLAG_RWO, 630 NULL, offsetof(ipf_nat_softc_t, ipf_nat_maprules_sz), ""); 631 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_rdrrules_sz", CTLFLAG_RWO, 632 NULL, offsetof(ipf_nat_softc_t, ipf_nat_rdrrules_sz), ""); 633 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_hostmap_sz", CTLFLAG_RWO, 634 NULL, offsetof(ipf_nat_softc_t, ipf_nat_hostmap_sz), ""); 635 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authsize", CTLFLAG_RWO, 636 NULL, offsetof(ipf_auth_softc_t, ipf_auth_size), ""); 637 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authused", CTLFLAG_RD, 638 NULL, offsetof(ipf_auth_softc_t, ipf_auth_used), ""); 639 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_defaultauthage", CTLFLAG_RW, 640 NULL, offsetof(ipf_auth_softc_t, ipf_auth_defaultage), ""); 641 SYSCTL_DYN_IPF_FRAG(_net_inet_ipf, OID_AUTO, "fr_ipfrttl", CTLFLAG_RW, 642 NULL, offsetof(ipf_frag_softc_t, ipfr_ttl), ""); 643 return (0); 644 } 645 646 static int 647 ipf_fbsd_sysctl_destroy(void) 648 { 649 if (sysctl_ctx_free(&ipf_clist)) { 650 printf("sysctl_ctx_free failed"); 651 return (ENOTEMPTY); 652 } 653 return (0); 654 } 655