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 49VNET_DECLARE(ipf_main_softc_t, ipfmain); 50#define V_ipfmain VNET(ipfmain) 51 52#ifdef __FreeBSD__ 53static struct cdev *ipf_devs[IPL_LOGSIZE]; 54#else 55static dev_t ipf_devs[IPL_LOGSIZE]; 56#endif 57 58static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); 59static int sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS ); 60static int sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS ); 61static int sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS ); 62static int sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS ); 63static int ipf_modload(void); 64static int ipf_modunload(void); 65static int ipf_fbsd_sysctl_create(void); 66static int ipf_fbsd_sysctl_destroy(void); 67 68#ifdef __FreeBSD__ 69static int ipfopen(struct cdev*, int, int, struct thread *); 70static int ipfclose(struct cdev*, int, int, struct thread *); 71static int ipfread(struct cdev*, struct uio *, int); 72static int ipfwrite(struct cdev*, struct uio *, int); 73#else 74static int ipfopen(dev_t, int, int, struct proc *); 75static int ipfclose(dev_t, int, int, struct proc *); 76static int ipfread(dev_t, struct uio *, int); 77static 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 86SYSCTL_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) 107static struct sysctl_ctx_list ipf_clist; 108#define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ 109#define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) 110SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 111 "IPF"); 112SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_flags), 0, "IPF flags"); 113SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_pass), 0, "default pass/block"); 114SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_active), 0, "IPF is active"); 115SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, 116 &VNET_NAME(ipfmain.ipf_tcpidletimeout), 0, "TCP idle timeout in seconds"); 117SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, 118 &VNET_NAME(ipfmain.ipf_tcphalfclosed), 0, "timeout for half closed TCP sessions"); 119SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, 120 &VNET_NAME(ipfmain.ipf_tcpclosewait), 0, "timeout for TCP sessions in closewait status"); 121SYSCTL_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"); 123SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, 124 &VNET_NAME(ipfmain.ipf_tcptimeout), 0, ""); 125SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, 126 &VNET_NAME(ipfmain.ipf_tcpclosed), 0, ""); 127SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, 128 &VNET_NAME(ipfmain.ipf_udptimeout), 0, "UDP timeout"); 129SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, 130 &VNET_NAME(ipfmain.ipf_udpacktimeout), 0, ""); 131SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, 132 &VNET_NAME(ipfmain.ipf_icmptimeout), 0, "ICMP timeout"); 133SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, 134 &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running"); 135SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, ""); 136SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, ""); 137SYSCTL_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> 143static int ipfpoll(struct cdev *dev, int events, struct thread *td); 144 145static 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 157static int ipfpoll(dev_t dev, int events, struct proc *td); 158 159static 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 176static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, 177 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; 178 179static int 180ipfilter_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 201static void 202vnet_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} 242VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 243 vnet_ipf_init, NULL); 244 245static int 246ipf_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 280static void 281vnet_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} 301VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 302 vnet_ipf_uninit, NULL); 303 304static int 305ipf_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 330static moduledata_t ipfiltermod = { 331 "ipfilter", 332 ipfilter_modevent, 333 0 334}; 335 336 337DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND); 338#ifdef MODULE_VERSION 339MODULE_VERSION(ipfilter, 1); 340#endif 341 342 343#ifdef SYSCTL_IPF 344int 345sysctl_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 366sysctl_error: 367 return (error); 368} 369 370/* 371 * arg2 holds the offset of the relevant member in the virtualized 372 * ipfmain structure. 373 */ 374static int 375sysctl_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 388static int 389sysctl_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 402static int 403sysctl_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 416static int 417sysctl_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 432static int 433#ifdef __FreeBSD__ 434ipfpoll(struct cdev *dev, int events, struct thread *td) 435#else 436ipfpoll(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 */ 485static int 486#ifdef __FreeBSD__ 487ipfopen(struct cdev *dev, int flags, int devtype, struct thread *p) 488#else 489ipfopen(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 520static int 521#ifdef __FreeBSD__ 522ipfclose(struct cdev *dev, int flags, int devtype, struct thread *p) 523#else 524ipfclose(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__ 543static int ipfread(struct cdev *dev, struct uio *uio, int ioflag) 544#else 545static 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__ 586static int ipfwrite(struct cdev *dev, struct uio *uio, int ioflag) 587#else 588static 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 610static int 611ipf_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 643static int 644ipf_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