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